본문 바로가기

About/IaC

[Terraform] Terraform을 이용하여 AWS EC2 Ubuntu Instance 생성(VPC, Subnet, Private IP 설정)

Terraform을 이용하여 AWS 환경에서 Ubuntu 인스턴스를 생성하는 예제에 대하여 살펴보겠습니다.

다음의 Terraform Document를 참조하였습니다.

https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance

 

Terraform Registry

 

registry.terraform.io

실습환경은 다음과 같습니다.

  • Ubuntu 22.04 LTS
  • aws-cli/2.7.0 
  • Terraform v1.3.0-dev on linux_arm64

Terraform 코드 작성


인스턴스 타입 및 AMI 확인

코드를 작성하기전 AWS Management Console에 접속하여 필요한 정보를 확인해야합니다. 

1. 인스턴스 타입 확인

AWS Management Console - EC2 - 인스턴스 - 인스턴스 유형에 접속하여 인스턴스 타입을 정합니다.

AWS 인스턴스 타입 확인

실습에서는 t3.micro를 사용하도록 하겠습니다.

2. AMI 확인

AWS Management Console - EC2 - 이미지 - AMI 카탈로그에 접속하여 AMI의 ID를 확인합니다.

Ubuntu 20.04(64비트 ,x86) AMI를 사용하도록 하겠습니다.

Terraform 코드 작성

main.tf 파일을 생성하여 다음과 같이 코드를 작성합니다.

$ cat main.tf
# AWS, region : seoul
provider "aws" {
  region = "ap-northeast-2"
}

# VPC 리소스 생성
resource "aws_vpc" "my_vpc" {
  cidr_block = "172.16.0.0/16"
  tags = {
    Name = "myVPC"
  }
}

# Subnet 리소스 생성
resource "aws_subnet" "my_subnet" {
  vpc_id            = aws_vpc.my_vpc.id
  cidr_block        = "172.16.10.0/24"
  availability_zone = "ap-northeast-2a"
  tags = {
    Name = "mySubnet"
  }
}

# Network Interface 리소스 생성
resource "aws_network_interface" "my_net" {
  subnet_id   = aws_subnet.my_subnet.id
  private_ips = ["172.16.10.100"]
  tags = {
    Name = "private_network_interface"
  }
}

# Ubuntu Instance 생성
resource "aws_instance" "ubuntu" {
  ami           = "ami-0225bc2990c54ce9a" # ubuntu 20.04 (64bit, x86)
  instance_type = "t3.micro"

  network_interface {
    network_interface_id = aws_network_interface.my_net.id
    device_index         = 0
  }
  tags = {
    Name = "myUbuntu"
  }
}

 

코드의 요소를 하나하나 살펴보면 다음과 같습니다.

  • Provider "aws" : AWS 리소스를 생성하므로 Provider는 aws 입니다.
  • resource "aws_vpc" "my_vpc" : 인스턴스에 적용시킬 VPC를 생성합니다.
    • CIDR는 172.16.0.0/16 으로 설정합니다.
  • resource "aws_subnet" "my_subnet" : 생성한 VPC 내에 Subnet 리소스를 생성합니다.
    • 위에서 생성한 VPC 내에 생성해야 하므로 vpc_idaws_vpc.my_vpc.id 입니다.
    • CIDR는 172.16.10.0/24 으로 설정합니다.
    • 가용역역은 "ap-northeast-2a"로 설정합니다.
  • resource "aws_network_interface" "my_net" : 생성한 Subnet 내에 Network Interface를 생성합니다.
    • 위에서 생성한 Subnet 안에서 생성해야 하므로 subnet_idaws_subnet_my_subnet.id 입니다.
    • Private IP는 172.16.10.100 으로 설정합니다. 이 ip는 서브넷의 CIDR 대역폭 안에 존재하는 ip여야 합니다.
  • resource "aws_instance" "ubuntu"  :  생성한 network 인터페이스와 위에서 확인한 정보로 EC2 instance를 생성합니다.
    • ami 값으로 위에서 확인한 ami id를 사용합니다.
    • instance type 또한 위에서 확인한 instance type을 사용합니다.
    • 위에서 생성한 network interface를 사용하므로 network_interface_id aws_network_interface.my_net.id 입니다.
    • device_index는 네트워크 인터페이스 연결의 정수 인덱스입니다.
    • Name 태그로 "myUbuntu"를 사용합니다.

Terraform 코드 적용


위에서 작성한 main.tf 파일을 이용하여 테라폼 코드를 적용합니다.

Terraform init

terraform init 명령어를 통해 AWS Provider를 사용할 수 있도록 설정합니다. AWS 자격증명이 인증이 되어있어야 합니다.

만약 AWS 자격인증이 되어있지 않으면 다음 링크를 참조하세요. 
2022.05.19 - [About/Cloud] - [AWS] AWS CLI 자격 증명하기(aws configure 명령어)

$ terraform init

Initializing the backend...

Initializing provider plugins...
- Reusing previous version of hashicorp/aws from the dependency lock file
- Using previously-installed hashicorp/aws v4.14.0

Terraform has made some changes to the provider dependency selections recorded
in the .terraform.lock.hcl file. Review those changes and commit them to your
version control system if they represent changes you intended to make.

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

Terraform Plan

terraform plan 명령어를 통해 코드 적용시 변경사항을 파악합니다.

총 4개의 리소스가 생성됩니다.

  • VPC
  • Subnet
  • Network Interface
  • EC2 Instance
$ terraform plan

Terraform used the selected providers to generate the following execution plan. Resource
actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # aws_instance.ubuntu will be created
  + resource "aws_instance" "ubuntu" {
      + ami                                  = "ami-0225bc2990c54ce9a"
      .... 생략

    }

  # aws_network_interface.my_net will be created
  + resource "aws_network_interface" "my_net" {
      .... 생략

      + private_ips               = [
          + "172.16.10.100",
        ]
      .... 생략
    }

  # aws_subnet.my_subnet will be created
  + resource "aws_subnet" "my_subnet" {
      + arn                                            = (known after apply)
      + assign_ipv6_address_on_creation                = false
      + availability_zone                              = "ap-northeast-2a"
      + availability_zone_id                           = (known after apply)
      + cidr_block                                     = "172.16.10.0/24"
     
    .... 생략
 
    }

  # aws_vpc.my_vpc will be created
  + resource "aws_vpc" "my_vpc" {
      + arn                                  = (known after apply)
      + cidr_block                           = "172.16.0.0/16"
      
     ...  생략
        }
    }

Plan: 4 to add, 0 to change, 0 to destroy.

──────────────────────────────────────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take
exactly these actions if you run "terraform apply" now.

Terraform Apply

terraform apply 명령어를 통해 실제 리소스가 생성되도록 합니다. 

실제 리소스가 생성되고는 AWS에서 요금이 부과됩니다. (조심 또 조심)

$ terraform apply

... 생략

Plan: 4 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

aws_vpc.my_vpc: Creating...
aws_vpc.my_vpc: Creation complete after 1s [id=vpc-01de8fa10d5884092]
aws_subnet.my_subnet: Creating...
aws_subnet.my_subnet: Creation complete after 0s [id=subnet-036e24bc463e8ec2c]
aws_network_interface.my_net: Creating...
aws_network_interface.my_net: Creation complete after 1s [id=eni-066d7c15b663edd63]
aws_instance.ubuntu: Creating...
aws_instance.ubuntu: Still creating... [10s elapsed]
aws_instance.ubuntu: Creation complete after 12s [id=i-0dd3a663bbca303e5]

Apply complete! Resources: 4 added, 0 changed, 0 destroyed.

생성된 리소스 확인

AWS Management Console에 접속하여 생성된 인스턴스를 확인합니다.

myUbuntu라는 이름으로 인스턴스 하나가 생성된 것을 확인할 수 있습니다.

인스턴스 요약 정보를 확인하면 위의 코드에서 설정한 내용과 동일한 것을 알 수 있습니다.

스토리지 관련 정보를 입력하지 않았는데, 기본으로 8GB 블록 디바이스가 할당된 것을 확인할 수 있습니다.

Terraform destroy

리소스를 다 사용했다면 terraform destroy 명령어를 통해 리소스를 삭제합니다. 요금이 부과될 수 있으니 꼭 삭제하세요!

위에서 생성한 4개의 리소스가 삭제된 것을 확인할 수 있습니다.

$ terraforom destroy

Plan: 0 to add, 0 to change, 4 to destroy.

Do you really want to destroy all resources?
  Terraform will destroy all your managed infrastructure, as shown above.
  There is no undo. Only 'yes' will be accepted to confirm.

  Enter a value: yes

aws_instance.ubuntu: Destroying... [id=i-0dd3a663bbca303e5]
aws_instance.ubuntu: Still destroying... [id=i-0dd3a663bbca303e5, 10s elapsed]
aws_instance.ubuntu: Still destroying... [id=i-0dd3a663bbca303e5, 20s elapsed]
aws_instance.ubuntu: Destruction complete after 30s
aws_network_interface.my_net: Destroying... [id=eni-066d7c15b663edd63]
aws_network_interface.my_net: Destruction complete after 0s
aws_subnet.my_subnet: Destroying... [id=subnet-036e24bc463e8ec2c]
aws_subnet.my_subnet: Destruction complete after 1s
aws_vpc.my_vpc: Destroying... [id=vpc-01de8fa10d5884092]
aws_vpc.my_vpc: Destruction complete after 0s

Destroy complete! Resources: 4 destroyed.

Terraform을 이용하여 AWS EC2 인스턴스를 생성해보았습니다.

Terraform을 사용할수록 점점 IaC(Infrastructure as Code)의 장점이 몸소 느껴지는 것 같습니다.

감사합니다.