인프런 송주영님 강의를 듣고 나름대로 요약한 내용 입니다.
Terraform
- Terraform이란 서버 인프라를 코드로서 관리하는 프로그램이다.
 - 실습은 AWS 리소스를 Terraform 코드로 작성하여 서버 인프라를 구성 하는 내용 입니다.
 
내 실습 환경
MacOSAWS CLI 2Terraform
  
  
  
  1
2
3
4
5  | curl -sO https://releases.hashicorp.com/terraform/0.12.24/terraform_0.12.24_darwin_amd64.zip
unzip terraform_0.12.24_darwin_amd64.zip
mv terraform /usr/local/bin
terraform --version
Terraform v0.12.24
  | 
 
  
    
        
        1
2
3  | brew install terraform
terraform --version
Terraform v0.12.24
  | 
 
         
      Terraform 기본 개념
    - 
      provider : 인프라 제공자. (ex. AWS, AZURE)
    
 - resource : 실제로 생성할 provider의 인프라 자원. (ex. aws_lb)
 - state: terraform 실행으로 생성된 인프라의 state.
 - 
        output : terraform으로 state 파일을 생서하여 저장하는 것을 의미.
      
 - 
        backend : terraform 실행으로 생성된 state를 저장할 공간. (ex. S3)
      
 - module : 공통적으로 사용할 인프라 코드 묶음.
 - remote state : 다른 경로의 state를 참조하는 것을 의미.
 
 
    
      
      
      
      
      Terraform 기본 명령어
      - init : 해당 폴더를 terraform base로 초기화
 - plan : 작성한 코드로 인프라가 어떻게 변경될지 미리 보기
 - apply : 작성한 코드 실행
 - import
 - state
 - destroy
 
 
      
      
      
      
      
      
모든 실행은 아래 순서로 진행
1. 해당 폴더를 terraform base로 초기화 하고
$> terraform init
2. 코드 작성 후
3. 코드의 plan을 미리보기
$> terraform plan
4. 코드 적용
$> terraform apply
      실습 1
      - VPC 생성
 - Subnet 구성
 - Internet Gateway 생성
 - Route Table 구성
 - Private Subnet
 - NAT Gateway 구성
 
 
      vpc.tf
      cidr_block 필수
    
     1
 2
 3
 4
 5
 6
 7
 8
 9
10  | provider "aws" {
    region = "ap-northeast-2"
}
resource "aws_vpc" "main" {
    cidr_block = "10.0.0.0/16"
    tags = {
        Name = "terraform-101"
    }
}
 | 
 
      
      subnet.tf
      cidr_block은 위에 생성한 vpc에 속한 IP 여야 한다.
    
     1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33  | provider "aws" {
  region  = "ap-northeast-2"
}
resource "aws_vpc" "main" {
  cidr_block       = "10.0.0.0/16"
  tags = {
    Name = "terraform-101"
  }
}
resource "aws_subnet" "first_subnet" {
  vpc_id     = aws_vpc.main.id
  cidr_block = "10.0.1.0/24"
  availability_zone = "ap-northeast-2a"
  tags = {
    Name = "101subnet-1"
  }
}
resource "aws_subnet" "second_subnet" {
  vpc_id     = aws_vpc.main.id
  cidr_block = "10.0.2.0/24"
  availability_zone = "ap-northeast-2b"
  tags = {
    Name = "101subnet-2"
  }
}
 | 
 
      
      internet_gateway.tf
    
    1
2
3
4
5
6
7  | resource "aws_internet_gateway" "igw" {
  vpc_id = aws_vpc.main.id
  tags = {
    Name = "main"
  }
}
 | 
 
    
    
    
    
    
    
      route.tf
      
        생성된 aws_route_table은 aws_route_table_association으로 연결 한다.
    
    
     1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16  | resource "aws_route_table" "route_table" {
    vpc_id = aws_vpc.main.id
    tags = {
        Name = "main"
    }
}
resource "aws_route_table_association" "route_talbe_association_1" {
    subnet_id = aws_subnet.first_subnet.id
    route_table_id = aws_route_table.route_table.id
}
resource "aws_route_table_association" "route_talbe_association_2" {
   subnet_id = aws_subnet.second_subnet.id
   route_talbe_id = aws_route_table.route_table.id
}
 | 
 
    
    
    
      
      private_subnet.tf
    
    
     1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21  | resource "aws_subnet" "first_private_subnet" {
  vpc_id     = aws_vpc.main.id
  cidr_block = "10.0.3.0/24"
  availability_zone = "ap-northeast-2a"
  tags = {
    Name = "101subnet-private-1"
  }
}
resource "aws_subnet" "second_private_subnet" {
  vpc_id     = aws_vpc.main.id
  cidr_block = "10.0.4.0/24"
  availability_zone = "ap-northeast-2b"
  tags = {
    Name = "101subnet-private-2"
  }
}
 | 
 
    
    
    
      
      nat.tf
    
    
    
    
    
     1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36  | resource "aws_eip" "nat_1" {
  vpc   = true
  lifecycle {
    create_before_destroy = true
  }
}
resource "aws_eip" "nat_2" {
  vpc   = true
  lifecycle {
    create_before_destroy = true
  }
}
resource "aws_nat_gateway" "nat_gateway_1" {
  allocation_id = aws_eip.nat_1.id
  # Private subnet이 아니라 public subnet을 연결하셔야 합니다.
  subnet_id = aws_subnet.first_subnet.id
  tags = {
    Name = "NAT-GW-1"
  }
}
resource "aws_nat_gateway" "nat_gateway_2" {
  allocation_id = aws_eip.nat_2.id
  subnet_id = aws_subnet.second_subnet.id
  tags = {
    Name = "NAT-GW-2"
  }
}
 | 
 
      
      nat_association.tf
     1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37  | resource "aws_route_table" "route_table_private_1" {
  vpc_id = aws_vpc.main.id
  tags = {
    Name = "main-private-1"
  }
}
resource "aws_route_table" "route_table_private_2" {
  vpc_id = aws_vpc.main.id
  tags = {
    Name = "main-private-2"
  }
}
resource "aws_route_table_association" "route_table_association_private_1" {
  subnet_id      = aws_subnet.first_private_subnet.id
  route_table_id = aws_route_table.route_table_private_1.id
}
resource "aws_route_table_association" "route_table_association_private_2" {
  subnet_id      = aws_subnet.second_private_subnet.id
  route_table_id = aws_route_table.route_table_private_2.id
}
resource "aws_route" "private_nat_1" {
  route_table_id              = aws_route_table.route_table_private_1.id
  destination_cidr_block      = "0.0.0.0/0"
  nat_gateway_id              = aws_nat_gateway.nat_gateway_1.id
}
resource "aws_route" "private_nat_2" {
  route_table_id              = aws_route_table.route_table_private_2.id
  destination_cidr_block      = "0.0.0.0/0"
  nat_gateway_id              = aws_nat_gateway.nat_gateway_2.id
}
 | 
 
    
    
    
      
      
      
      
      실습 2
      s3.tf
    
     1
 2
 3
 4
 5
 6
 7
 8
 9
10
11  | provider "aws" {
  region  = "ap-northeast-2"
}
resource "aws_s3_bucket" "main" {
  bucket = "devopsart-terraform-101"
  tags = {
    Name        = "devopsart-terraform-101"
  }
}
 | 
 
    
    
    
    
    
    
      
      
      
      실습 3
      - IAM User 생성
 - IAM Group 생성
 - User를 Group에 등록
 - IAM Role 생성
 - IAM Policy 생성
 
user.tf
    
    
     1
 2
 3
 4
 5
 6
 7
  | provider "aws" {
  region  = "ap-northeast-2"
}
resource "aws_iam_user" "gildong_hong" {
  name = "gildong.hong"
}
 | 
 
    
    
    
      
      group.tf
    1
2
3
4
5
6
7  | provider "aws" {
  region  = "ap-northeast-2"
}
resource "aws_iam_group" "devops_group" {
  name = "devops"
}
 | 
 
    
    
    
    
      
      register.tf
    
    
    1
2
3
4
5
6
7
8
9  | resource "aws_iam_group_membership" "devops" {
  name = aws_iam_group.devops_group.name
  users = [
    aws_iam_user.gildong_hong.name
  ]
  group = aws_iam_group.devops_group.name
}
 | 
 
      
      s3_role.tf
    
     1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47  | resource "aws_iam_role" "hello" {
  name               = "hello-iam-role"
  path               = "/"
  assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
EOF
}
resource "aws_iam_role_policy" "hello_s3" {
  name   = "hello-s3-download"
  role   = aws_iam_role.hello.id
  policy = <<EOF
{
  "Statement": [
    {
      "Sid": "AllowAppArtifactsReadAccess",
      "Action": [
        "s3:GetObject"
      ],
      "Resource": [
        "*"
      ],
      "Effect": "Allow"
    }
  ]
}
EOF
}
resource "aws_iam_instance_profile" "hello" {
  name = "hello-profile"
  role = aws_iam_role.hello.name
}
 | 
 
    
    
    
      
      policy.tf
    
     1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25  | resource "aws_iam_user" "gildong_hong" {
  name = "gildong.hong"
}
resource "aws_iam_user_policy" "art_devops_black" {
  name  = "super-admin"
  user  = aws_iam_user.gildong_hong.name
  policy = <<EOF
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "*"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}
EOF
}
 | 
 
    
      
      
      
      Terraform 고도화
      
1. Backend 활용하기
2. Variable 활용하기
3. Function 활용하기
      
      4. GitHub로 협업하기
      
      
        
 
댓글
댓글 쓰기