본문 바로가기
IaaC/Terraform

[IaaC] Terraform | AWS VPC 생성 코드 작성

by 인프라보이 2020. 8. 26.

 Terrafrom을 사용하여 AWS 계정에 VPC, 서브넷, 인터넷/NAT 게이트웨이, 라우팅 테이블을 한 번에 작성하는 코드를 만들었습니다.  코드형 인프라 구축에서 제일 기본이 되는 VPC 구성이 정상적으로 완료되어 좋은 출발 신호로 보고 이를 포스팅합니다. 참고로 VPC 생성하는 내용은 아래 링크를 참조하여 만들었습니다. 

https://www.howtoforge.com/create-a-vpc-on-aws-using-terraform/

 대부분의 Terraform 사용방법이 리눅스 기반 또는 Mac 기반으로 제공되고 있어 조금 힘든 부분이 있으며, 지금 가장 충격적인 것은 최신 버전의 Terraform은 이전에 개시한 블로그들을 참조하여 작성하면 명령어가 적용되지 않는 점이 있습니다.

 1. Terraform 버전 확인 
        > terraform -v
        Terraform v0.13.0
        + provider registry.terraform.io/hashicorp/aws v3.3.0

 2. Terraform 실행환경 
       OS : Windows 10
       Tools : Visual Studio Code 

 3. 사전 준비사항
        AWS 계정 준비 및 배포 리전 확인 (서울 리전 : ap-northeast-2)
        IAM 계정 생성하여, AccessKey / SecretKey 생성 
        Visual Studio Code에서 "Terraform 파일"을 보관할 폴더 생성 (ex : C:\terraform)

 4. Terraform으로 AWS 리소스를 불러올 "OOO.tf" 파일 생성
       아래 파일들을 생성하게 되면 VS Code에서 이렇게 보입니다.

 

        main.tf

provider "aws" {
      region     = "${var.region}"
      access_key = "${var.access_key}"
      secret_key = "${var.secret_key}"
}


# VPC resources: This will create 1 VPC with 4 Subnets, 1 Internet Gateway, 4 Route Tables. 

resource "aws_vpc" "default" {
  cidr_block           = var.cidr_block
  enable_dns_support   = true
  enable_dns_hostnames = true

  tags = {
      Name = "infraboy-vpc"
  }
}

resource "aws_internet_gateway" "default" {
  vpc_id = aws_vpc.default.id
}

resource "aws_route_table" "private" {
  count = length(var.private_subnet_cidr_blocks)

  vpc_id = aws_vpc.default.id
}

resource "aws_route" "private" {
  count = length(var.private_subnet_cidr_blocks)

  route_table_id         = aws_route_table.private[count.index].id
  destination_cidr_block = "0.0.0.0/0"
  nat_gateway_id         = aws_nat_gateway.default[count.index].id
}

resource "aws_route_table" "public" {
  vpc_id = aws_vpc.default.id
}

resource "aws_route" "public" {
  route_table_id         = aws_route_table.public.id
  destination_cidr_block = "0.0.0.0/0"
  gateway_id             = aws_internet_gateway.default.id
}

resource "aws_subnet" "private" {
  count = length(var.private_subnet_cidr_blocks)

  vpc_id            = aws_vpc.default.id
  cidr_block        = var.private_subnet_cidr_blocks[count.index]
  availability_zone = var.availability_zones[count.index]
}

resource "aws_subnet" "public" {
  count = length(var.public_subnet_cidr_blocks)

  vpc_id                  = aws_vpc.default.id
  cidr_block              = var.public_subnet_cidr_blocks[count.index]
  availability_zone       = var.availability_zones[count.index]
  map_public_ip_on_launch = true
}

resource "aws_route_table_association" "private" {
  count = length(var.private_subnet_cidr_blocks)

  subnet_id      = aws_subnet.private[count.index].id
  route_table_id = aws_route_table.private[count.index].id
}

resource "aws_route_table_association" "public" {
  count = length(var.public_subnet_cidr_blocks)

  subnet_id      = aws_subnet.public[count.index].id
  route_table_id = aws_route_table.public.id
}


# NAT resources: This will create 2 NAT gateways in 2 Public Subnets for 2 different Private Subnets.

resource "aws_eip" "nat" {
  count = length(var.public_subnet_cidr_blocks)

  vpc = true
}

resource "aws_nat_gateway" "default" {
  depends_on = ["aws_internet_gateway.default"]

  count = length(var.public_subnet_cidr_blocks)

  allocation_id = aws_eip.nat[count.index].id
  subnet_id     = aws_subnet.public[count.index].id
}

        variables.tf

variable "access_key" {
     description = "Access key to AWS console"
     
}
variable "secret_key" {
     description = "Secret key to AWS console"
     
}

variable "region" {
  default     = "ap-northeast-2"
  type        = string
  description = "Region of the VPC"
}


variable "cidr_block" {
  default     = "20.0.0.0/16"
  type        = string
  description = "CIDR block for the VPC"
}

variable "public_subnet_cidr_blocks" {
  default     = ["20.0.0.0/24", "20.0.2.0/24"]
  type        = list
  description = "List of public subnet CIDR blocks"
}

variable "private_subnet_cidr_blocks" {
  default     = ["20.0.1.0/24", "20.0.3.0/24"]
  type        = list
  description = "List of private subnet CIDR blocks"
}

variable "availability_zones" {
  default     = ["ap-northeast-2a", "ap-northeast-2c"]
  type        = list
  description = "List of availability zones"
}
 

        terraform.tfvars

access_key = "AWS 계정의 Access Key 넣기"
secret_key = "AWS 계정의 Secret Key 넣기"


5. Terraform을 통한 VPC 생성

   아래 명령을 통해 Terraform 폴더 내에서 사용되는 공급자용 플러그인을 다운로드하고 설치합니다. 

> terraform init

   아래 명령을 통해 Terraform코드에서 변경 사항을 확인하는 데 사용합니다. 
   기존 코드에서 업데이트된 내용이나, 추가될 내용에 대해 사전에 확인합니다. 

> terraform plan

   아래 명령은 실제 AWS에 main.tf파일에 선언된 리소스를 생성합니다. 리소스를 만들기 위해 사전에 "yes"를 입력할 수 도 있습니다.

> terraform apply

VPC Creating...

  Terraform으로 적용한 모든 리소스를 삭제할 때, 아래 명령어를 사용합니다.

> terraform destroy

All resource destroyed...

 6. 적용 확인

   위 main.tf 코드의 14 line에 "Tags"가 표기되어 있고 "infraboy-vpc"로 정의하였습니다. 다른 리소스에는 Tags표기가 되어 있지 않아 실제 AWS 콘솔에서 위 Terraform으로 생성한 서브넷, 게이트웨이 등에는 Name표기가 되어 있지 않습니다. 
    Terraform apply로 적용 후 Tags를 추가 수정한 뒤, Plan > Apply를 순차적으로 수행하여 변경사항을 적용할 수 있습니다.  이제 특정 계정을 추가로 생성할 때, 일일이 VPC를 세팅할 필요 없이 이 코드만으로 찍어낼 수 있는 장점이 생겼습니다. Terraform을 사용하면 AWS콘솔로 접근할 일이 줄어들게 된다고 합니다.  GUI마우스 클릭에서 CLI로 모든 작업을 하는 그날까지 뜨겁게 달려보겠습니다.

728x90

'IaaC > Terraform' 카테고리의 다른 글

[IaaC] Terraform | 테라폼 설치 on Windows 10  (0) 2020.08.18

댓글