⭐ 가시다(gasida) 님이 진행하는 Terraform T101 4기 실습 스터디 게시글입니다.
책 '테라폼으로 시작하는 IaC'을 참고했습니다! 
게시글 상 소스코드, 사진에서 **굵게** 혹은 '''코드쉘''' 에 대한 부분이 들어가있을수도 있습니다.

1. OpenTofu 소개

OpenTofu 로고. 두부처럼생겼다

 

OpenTofu

  • OpenTofu 는 오픈소스 IaC 도구입니다.
  • HashiCorp 가 Terraform의 라이센스를 변경함(2023)에따라 Fork버전인 OpenTF 가 빌드업되었다.
    Terraform의 포크버전 OpenTF가 OpenTofu로 이름을 변경하였습니다.
  • 공식링크: https://opentofu.org/

OpenTofu 가 어떻게 작동하는지

  • API 를 통해 Cloud Platform 및 기타 서비스에서 리소스 생성 및 관리
  • Provider 는 OpenTofu가 액세스 가능한 API를 통해 모든 플랫폼, 서비스와 함께 작업할 수 있도록 함
  • 수많은 공급자를 작성함(AWS, Azure, GCP, …)

OpenTofu 워크플로의 구성

  • Write: 여러 클라우드 공급자, 서비스에 걸쳐있는 Resource 정의
  • Plan: 기존 인프라와 비교하여 생성,업데이트,제거 할 Resource 를 설명하는 작업
  • Apply: 모든 리소스 종속성을 반영하여 올바른 순서대로 작업을 수행

OpenTofu vs Terraform

  • 기술적인 측면에서 OpenTofu 1.6.x 와 Terraform 1.6.x 는 매우 흡사함
  • 라이센스 측면에서 OpenTofu는 오픈소스
  • OpenTofu는 자체공급자가 없음

 

 

2. OpenTofu 설치

  • tenv 설치로 사용
# (옵션) tfenv 제거
brew remove tfenv

# Tenv 설치
## brew install cosign
brew install tenv
tenv -v
tenv -h
tenv tofu -h
which tenv

# (옵션) Install shell completion
tenv completion zsh > ~/.tenv.completion.zsh
echo "source '~/.tenv.completion.zsh'" >> ~/.zshrc
#
tenv tofu -h
tenv tofu list
tenv tofu list-remote

# 설치
tenv tofu install 1.7.3
tenv tofu list
tenv tofu use 1.7.3
tenv tofu detect

# tofu 확인
tofu -h
tofu version

 

 

 

3. OpenTofu 로 AWS 리소스 배포 코드 작성 후 배포 및 정리해보기

프로필계정 확인하는 방법

방법1: aws configure list-profiles
aws configure list-profiles
#default 

방법2: credentials 파일 확인
cd ~/.aws
cat credentials # [대괄호]로 출력되는 이름이 프로필계정이다! 
#[default]
#aws_access_key_id = ...
#aws_secret_access_key = ... 

 

 

AWS Provider 설정

00_provider.tf

variable aws_region {
    default = "us-east-1"
    description = "AWS region where the resources will be provisioned"
}

# Configure the AWS Provider
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
    # helm = {
    #     source = "hashicorp/aws"
    #     version = "~> 2.6"
    # }
  }
}

# Configure region and profile
provider "aws" {
  region = var.aws_region
  profile = "default"
}

 

 

VPC 설정

01_vpc.tf

resource "aws_vpc" "mycustomvpc" {
    cidr_block = "10.0.0.0/16"
    enable_dns_support = true
    enable_dns_hostnames = true

    tags = {
        "owner" = "jjongguet"
        "Name" = "my custom VPC"
    }
}

 

 

internet_gateway 설정

02_internet_gateway.tf

resource "aws_internet_gateway" "igw" { 
    vpc_id = aws_vpc.mycustomvpc.id
    tags = {
        "owner" = "jjongguet"
        "Name" = "IGW"
    }
}

 

 

Subnet 설정

03_subnet.tf

resource "aws_subnet" "private-us-east-1a" {
  vpc_id     = aws_vpc.mycustomvpc.id
  cidr_block = "10.0.1.0/24"
  availability_zone = "us-east-1a"

  tags = {
    "subnet" = "private-us-east-1a"
    "Name" = "Private Subnet"
  }
}

resource "aws_subnet" "private-us-east-1b" {
  vpc_id     = aws_vpc.mycustomvpc.id
  cidr_block = "10.0.2.0/24"
  availability_zone = "us-east-1b"

  tags = {
    "subnet" = "private-us-east-1b"
    "Name" = "Private Subnet"
  }
}

resource "aws_subnet" "public-us-east-1a" {
  vpc_id     = aws_vpc.mycustomvpc.id
  cidr_block = "10.0.3.0/24"
  availability_zone = "us-east-1a"
  map_public_ip_on_launch = true

  tags = {
    "subnet" = "public-us-east-1a"
    "Name" = "Public Subnet"
  }
}

resource "aws_subnet" "public-us-east-1b" {
  vpc_id     = aws_vpc.mycustomvpc.id
  cidr_block = "10.0.4.0/24"
  availability_zone = "us-east-1b"
  map_public_ip_on_launch = true

  tags = {
    "subnet" = "public-us-east-1b"
    "Name" = "Public Subnet"
  }
}

 

 

 

  • AZ : "us-east-1a" 에 배포합니다

NAT Gateway 설정

04_nat_gateway.tf

resource "aws_eip" "nat" {
  #vpc = true 
  domain = "vpc"

  tags = {
    "Name" = "EIP"
    "Owner" = "jjongguet"
  }

}

resource "aws_nat_gateway" "nat" {
  allocation_id = aws_eip.nat.id
  subnet_id     = aws_subnet.public-us-east-1a.id

  tags = {
    "Name" = "NAT Gateway"
    "Owner" = "jjongguet"
  }

  # To ensure proper ordering, it is recommended to add an explicit dependency
  # on the Internet Gateway for the VPC.
  depends_on = [aws_internet_gateway.igw]
}
  • vpc 는 최신버전에서 사용되지않습니다. 대신 domain 을 사용합니다(tofu validate)

 

 

Route table 설정

05_route_tables.tf

resource "aws_route_table" "privateroute" {
  vpc_id = aws_vpc.mycustomvpc.id

  route {
    cidr_block = "0.0.0.0/0"
    nat_gateway_id = aws_nat_gateway.nat.id
  }

  tags = {
    Name = "private"
  }
}

resource "aws_route_table" "publicroute" {
  vpc_id = aws_vpc.mycustomvpc.id

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.igw.id
  }

  tags = {
    Name = "public"
  }
}

resource "aws_route_table_association" "privateassociation_a" {
  subnet_id      = aws_subnet.private-us-east-1a.id
  route_table_id = aws_route_table.privateroute.id
}
resource "aws_route_table_association" "privateassociation_b" {
  subnet_id      = aws_subnet.private-us-east-1b.id
  route_table_id = aws_route_table.privateroute.id
}
resource "aws_route_table_association" "publicassociation_a" {
  subnet_id      = aws_subnet.public-us-east-1a.id
  route_table_id = aws_route_table.publicroute.id
}
resource "aws_route_table_association" "publicassociation_b" {
  subnet_id      = aws_subnet.public-us-east-1b.id
  route_table_id = aws_route_table.publicroute.id
}

 

 

프로젝트 초기화: tofu init

tofu init

#ls -al
total 56
drwxr-xr-x  10 jjongguet  staff   320 Aug  3 15:23 .
drwxr-xr-x@ 16 jjongguet  staff   512 Aug  3 15:15 ..
drwxr-xr-x   3 jjongguet  staff    96 Aug  3 15:23 .terraform
-rw-r--r--   1 jjongguet  staff  1026 Aug  3 15:23 .terraform.lock.hcl
-rw-r--r--   1 jjongguet  staff   452 Aug  3 15:16 00_provider.tf
-rw-r--r--   1 jjongguet  staff   212 Aug  3 15:22 01_vpc.tf
-rw-r--r--   1 jjongguet  staff   150 Aug  3 15:22 02_internet_gateway.tf
-rw-r--r--   1 jjongguet  staff   986 Aug  3 15:20 03_subnet.tf
-rw-r--r--   1 jjongguet  staff   476 Aug  3 15:28 04_nat_gateway.tf
-rw-r--r--   1 jjongguet  staff  1080 Aug  3 15:21 05_route_tables.tf

 

 

프로젝트 검증: tofu validate

tofu validate
Success! The configuration is valid.

 

 

프로젝트 계획: tofu plan

tofu plan

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

OpenTofu will perform the following actions:

  # aws_eip.nat will be created
  + resource "aws_eip" "nat" {
      + allocation_id        = (known after apply)
      + arn                  = (known after apply)
      + association_id       = (known after apply)
      + carrier_ip           = (known after apply)
      + customer_owned_ip    = (known after apply)
      + domain               = "vpc"
      + id                   = (known after apply)
      + instance             = (known after apply)
      + network_border_group = (known after apply)
      + network_interface    = (known after apply)
      + private_dns          = (known after apply)
      + private_ip           = (known after apply)
      + ptr_record           = (known after apply)
      + public_dns           = (known after apply)
      + public_ip            = (known after apply)
      + public_ipv4_pool     = (known after apply)
      + tags                 = {
          + "Name"  = "EIP"
          + "Owner" = "jjongguet"
        }
      + tags_all             = {
          + "Name"  = "EIP"
          + "Owner" = "jjongguet"
        }
      + vpc                  = (known after apply)
    }

  # aws_internet_gateway.igw will be created
  + resource "aws_internet_gateway" "igw" {
      + arn      = (known after apply)
      + id       = (known after apply)
      + owner_id = (known after apply)
      + tags     = {
          + "Name"  = "IGW"
          + "owner" = "jjongguet"
        }
      + tags_all = {
          + "Name"  = "IGW"
          + "owner" = "jjongguet"
        }
      + vpc_id   = (known after apply)
    }

  # aws_nat_gateway.nat will be created
  + resource "aws_nat_gateway" "nat" {
      + allocation_id                      = (known after apply)
      + association_id                     = (known after apply)
      + connectivity_type                  = "public"
      + id                                 = (known after apply)
      + network_interface_id               = (known after apply)
      + private_ip                         = (known after apply)
      + public_ip                          = (known after apply)
      + secondary_private_ip_address_count = (known after apply)
      + secondary_private_ip_addresses     = (known after apply)
      + subnet_id                          = (known after apply)
      + tags                               = {
          + "Name"  = "NAT Gateway"
          + "Owner" = "jjongguet"
        }
      + tags_all                           = {
          + "Name"  = "NAT Gateway"
          + "Owner" = "jjongguet"
        }
    }

  # aws_route_table.privateroute will be created
  + resource "aws_route_table" "privateroute" {
      + arn              = (known after apply)
      + id               = (known after apply)
      + owner_id         = (known after apply)
      + propagating_vgws = (known after apply)
      + route            = [
          + {
              + carrier_gateway_id         = ""
              + cidr_block                 = "0.0.0.0/0"
              + core_network_arn           = ""
              + destination_prefix_list_id = ""
              + egress_only_gateway_id     = ""
              + gateway_id                 = ""
              + ipv6_cidr_block            = ""
              + local_gateway_id           = ""
              + nat_gateway_id             = (known after apply)
              + network_interface_id       = ""
              + transit_gateway_id         = ""
              + vpc_endpoint_id            = ""
              + vpc_peering_connection_id  = ""
            },
        ]
      + tags             = {
          + "Name" = "private"
        }
      + tags_all         = {
          + "Name" = "private"
        }
      + vpc_id           = (known after apply)
    }

  # aws_route_table.publicroute will be created
  + resource "aws_route_table" "publicroute" {
      + arn              = (known after apply)
      + id               = (known after apply)
      + owner_id         = (known after apply)
      + propagating_vgws = (known after apply)
      + route            = [
          + {
              + carrier_gateway_id         = ""
              + cidr_block                 = "0.0.0.0/0"
              + core_network_arn           = ""
              + destination_prefix_list_id = ""
              + egress_only_gateway_id     = ""
              + gateway_id                 = (known after apply)
              + ipv6_cidr_block            = ""
              + local_gateway_id           = ""
              + nat_gateway_id             = ""
              + network_interface_id       = ""
              + transit_gateway_id         = ""
              + vpc_endpoint_id            = ""
              + vpc_peering_connection_id  = ""
            },
        ]
      + tags             = {
          + "Name" = "public"
        }
      + tags_all         = {
          + "Name" = "public"
        }
      + vpc_id           = (known after apply)
    }

  # aws_route_table_association.privateassociation_a will be created
  + resource "aws_route_table_association" "privateassociation_a" {
      + id             = (known after apply)
      + route_table_id = (known after apply)
      + subnet_id      = (known after apply)
    }

  # aws_route_table_association.privateassociation_b will be created
  + resource "aws_route_table_association" "privateassociation_b" {
      + id             = (known after apply)
      + route_table_id = (known after apply)
      + subnet_id      = (known after apply)
    }

  # aws_route_table_association.publicassociation_a will be created
  + resource "aws_route_table_association" "publicassociation_a" {
      + id             = (known after apply)
      + route_table_id = (known after apply)
      + subnet_id      = (known after apply)
    }

  # aws_route_table_association.publicassociation_b will be created
  + resource "aws_route_table_association" "publicassociation_b" {
      + id             = (known after apply)
      + route_table_id = (known after apply)
      + subnet_id      = (known after apply)
    }

  # aws_subnet.private-us-east-1a will be created
  + resource "aws_subnet" "private-us-east-1a" {
      + arn                                            = (known after apply)
      + assign_ipv6_address_on_creation                = false
      + availability_zone                              = "us-east-1a"
      + availability_zone_id                           = (known after apply)
      + cidr_block                                     = "10.0.1.0/24"
      + enable_dns64                                   = false
      + enable_resource_name_dns_a_record_on_launch    = false
      + enable_resource_name_dns_aaaa_record_on_launch = false
      + id                                             = (known after apply)
      + ipv6_cidr_block_association_id                 = (known after apply)
      + ipv6_native                                    = false
      + map_public_ip_on_launch                        = false
      + owner_id                                       = (known after apply)
      + private_dns_hostname_type_on_launch            = (known after apply)
      + tags                                           = {
          + "Name"   = "Private Subnet"
          + "subnet" = "private-us-east-1a"
        }
      + tags_all                                       = {
          + "Name"   = "Private Subnet"
          + "subnet" = "private-us-east-1a"
        }
      + vpc_id                                         = (known after apply)
    }

  # aws_subnet.private-us-east-1b will be created
  + resource "aws_subnet" "private-us-east-1b" {
      + arn                                            = (known after apply)
      + assign_ipv6_address_on_creation                = false
      + availability_zone                              = "us-east-1b"
      + availability_zone_id                           = (known after apply)
      + cidr_block                                     = "10.0.2.0/24"
      + enable_dns64                                   = false
      + enable_resource_name_dns_a_record_on_launch    = false
      + enable_resource_name_dns_aaaa_record_on_launch = false
      + id                                             = (known after apply)
      + ipv6_cidr_block_association_id                 = (known after apply)
      + ipv6_native                                    = false
      + map_public_ip_on_launch                        = false
      + owner_id                                       = (known after apply)
      + private_dns_hostname_type_on_launch            = (known after apply)
      + tags                                           = {
          + "Name"   = "Private Subnet"
          + "subnet" = "private-us-east-1b"
        }
      + tags_all                                       = {
          + "Name"   = "Private Subnet"
          + "subnet" = "private-us-east-1b"
        }
      + vpc_id                                         = (known after apply)
    }

  # aws_subnet.public-us-east-1a will be created
  + resource "aws_subnet" "public-us-east-1a" {
      + arn                                            = (known after apply)
      + assign_ipv6_address_on_creation                = false
      + availability_zone                              = "us-east-1a"
      + availability_zone_id                           = (known after apply)
      + cidr_block                                     = "10.0.3.0/24"
      + enable_dns64                                   = false
      + enable_resource_name_dns_a_record_on_launch    = false
      + enable_resource_name_dns_aaaa_record_on_launch = false
      + id                                             = (known after apply)
      + ipv6_cidr_block_association_id                 = (known after apply)
      + ipv6_native                                    = false
      + map_public_ip_on_launch                        = true
      + owner_id                                       = (known after apply)
      + private_dns_hostname_type_on_launch            = (known after apply)
      + tags                                           = {
          + "Name"   = "Public Subnet"
          + "subnet" = "public-us-east-1a"
        }
      + tags_all                                       = {
          + "Name"   = "Public Subnet"
          + "subnet" = "public-us-east-1a"
        }
      + vpc_id                                         = (known after apply)
    }

  # aws_subnet.public-us-east-1b will be created
  + resource "aws_subnet" "public-us-east-1b" {
      + arn                                            = (known after apply)
      + assign_ipv6_address_on_creation                = false
      + availability_zone                              = "us-east-1b"
      + availability_zone_id                           = (known after apply)
      + cidr_block                                     = "10.0.4.0/24"
      + enable_dns64                                   = false
      + enable_resource_name_dns_a_record_on_launch    = false
      + enable_resource_name_dns_aaaa_record_on_launch = false
      + id                                             = (known after apply)
      + ipv6_cidr_block_association_id                 = (known after apply)
      + ipv6_native                                    = false
      + map_public_ip_on_launch                        = true
      + owner_id                                       = (known after apply)
      + private_dns_hostname_type_on_launch            = (known after apply)
      + tags                                           = {
          + "Name"   = "Public Subnet"
          + "subnet" = "public-us-east-1b"
        }
      + tags_all                                       = {
          + "Name"   = "Public Subnet"
          + "subnet" = "public-us-east-1b"
        }
      + vpc_id                                         = (known after apply)
    }

  # aws_vpc.mycustomvpc will be created
  + resource "aws_vpc" "mycustomvpc" {
      + arn                                  = (known after apply)
      + cidr_block                           = "10.0.0.0/16"
      + default_network_acl_id               = (known after apply)
      + default_route_table_id               = (known after apply)
      + default_security_group_id            = (known after apply)
      + dhcp_options_id                      = (known after apply)
      + enable_dns_hostnames                 = true
      + enable_dns_support                   = true
      + enable_network_address_usage_metrics = (known after apply)
      + id                                   = (known after apply)
      + instance_tenancy                     = "default"
      + ipv6_association_id                  = (known after apply)
      + ipv6_cidr_block                      = (known after apply)
      + ipv6_cidr_block_network_border_group = (known after apply)
      + main_route_table_id                  = (known after apply)
      + owner_id                             = (known after apply)
      + tags                                 = {
          + "Name"  = "my custom VPC"
          + "owner" = "jjongguet"
        }
      + tags_all                             = {
          + "Name"  = "my custom VPC"
          + "owner" = "jjongguet"
        }
    }

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

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

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

 

 

프로젝트 실행: tofu apply --auto-approve

tofu apply --auto-approve

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

OpenTofu will perform the following actions:

  # aws_eip.nat will be created
  + resource "aws_eip" "nat" {
      + allocation_id        = (known after apply)
      + arn                  = (known after apply)
      + association_id       = (known after apply)
      + carrier_ip           = (known after apply)
      + customer_owned_ip    = (known after apply)
      + domain               = "vpc"
      + id                   = (known after apply)
      + instance             = (known after apply)
      + network_border_group = (known after apply)
      + network_interface    = (known after apply)
      + private_dns          = (known after apply)
      + private_ip           = (known after apply)
      + ptr_record           = (known after apply)
      + public_dns           = (known after apply)
      + public_ip            = (known after apply)
      + public_ipv4_pool     = (known after apply)
      + tags                 = {
          + "Name"  = "EIP"
          + "Owner" = "jjongguet"
        }
      + tags_all             = {
          + "Name"  = "EIP"
          + "Owner" = "jjongguet"
        }
      + vpc                  = (known after apply)
    }

  # aws_internet_gateway.igw will be created
  + resource "aws_internet_gateway" "igw" {
      + arn      = (known after apply)
      + id       = (known after apply)
      + owner_id = (known after apply)
      + tags     = {
          + "Name"  = "IGW"
          + "owner" = "jjongguet"
        }
      + tags_all = {
          + "Name"  = "IGW"
          + "owner" = "jjongguet"
        }
      + vpc_id   = (known after apply)
    }

  # aws_nat_gateway.nat will be created
  + resource "aws_nat_gateway" "nat" {
      + allocation_id                      = (known after apply)
      + association_id                     = (known after apply)
      + connectivity_type                  = "public"
      + id                                 = (known after apply)
      + network_interface_id               = (known after apply)
      + private_ip                         = (known after apply)
      + public_ip                          = (known after apply)
      + secondary_private_ip_address_count = (known after apply)
      + secondary_private_ip_addresses     = (known after apply)
      + subnet_id                          = (known after apply)
      + tags                               = {
          + "Name"  = "NAT Gateway"
          + "Owner" = "jjongguet"
        }
      + tags_all                           = {
          + "Name"  = "NAT Gateway"
          + "Owner" = "jjongguet"
        }
    }

  # aws_route_table.privateroute will be created
  + resource "aws_route_table" "privateroute" {
      + arn              = (known after apply)
      + id               = (known after apply)
      + owner_id         = (known after apply)
      + propagating_vgws = (known after apply)
      + route            = [
          + {
              + carrier_gateway_id         = ""
              + cidr_block                 = "0.0.0.0/0"
              + core_network_arn           = ""
              + destination_prefix_list_id = ""
              + egress_only_gateway_id     = ""
              + gateway_id                 = ""
              + ipv6_cidr_block            = ""
              + local_gateway_id           = ""
              + nat_gateway_id             = (known after apply)
              + network_interface_id       = ""
              + transit_gateway_id         = ""
              + vpc_endpoint_id            = ""
              + vpc_peering_connection_id  = ""
            },
        ]
      + tags             = {
          + "Name" = "private"
        }
      + tags_all         = {
          + "Name" = "private"
        }
      + vpc_id           = (known after apply)
    }

  # aws_route_table.publicroute will be created
  + resource "aws_route_table" "publicroute" {
      + arn              = (known after apply)
      + id               = (known after apply)
      + owner_id         = (known after apply)
      + propagating_vgws = (known after apply)
      + route            = [
          + {
              + carrier_gateway_id         = ""
              + cidr_block                 = "0.0.0.0/0"
              + core_network_arn           = ""
              + destination_prefix_list_id = ""
              + egress_only_gateway_id     = ""
              + gateway_id                 = (known after apply)
              + ipv6_cidr_block            = ""
              + local_gateway_id           = ""
              + nat_gateway_id             = ""
              + network_interface_id       = ""
              + transit_gateway_id         = ""
              + vpc_endpoint_id            = ""
              + vpc_peering_connection_id  = ""
            },
        ]
      + tags             = {
          + "Name" = "public"
        }
      + tags_all         = {
          + "Name" = "public"
        }
      + vpc_id           = (known after apply)
    }

  # aws_route_table_association.privateassociation_a will be created
  + resource "aws_route_table_association" "privateassociation_a" {
      + id             = (known after apply)
      + route_table_id = (known after apply)
      + subnet_id      = (known after apply)
    }

  # aws_route_table_association.privateassociation_b will be created
  + resource "aws_route_table_association" "privateassociation_b" {
      + id             = (known after apply)
      + route_table_id = (known after apply)
      + subnet_id      = (known after apply)
    }

  # aws_route_table_association.publicassociation_a will be created
  + resource "aws_route_table_association" "publicassociation_a" {
      + id             = (known after apply)
      + route_table_id = (known after apply)
      + subnet_id      = (known after apply)
    }

  # aws_route_table_association.publicassociation_b will be created
  + resource "aws_route_table_association" "publicassociation_b" {
      + id             = (known after apply)
      + route_table_id = (known after apply)
      + subnet_id      = (known after apply)
    }

  # aws_subnet.private-us-east-1a will be created
  + resource "aws_subnet" "private-us-east-1a" {
      + arn                                            = (known after apply)
      + assign_ipv6_address_on_creation                = false
      + availability_zone                              = "us-east-1a"
      + availability_zone_id                           = (known after apply)
      + cidr_block                                     = "10.0.1.0/24"
      + enable_dns64                                   = false
      + enable_resource_name_dns_a_record_on_launch    = false
      + enable_resource_name_dns_aaaa_record_on_launch = false
      + id                                             = (known after apply)
      + ipv6_cidr_block_association_id                 = (known after apply)
      + ipv6_native                                    = false
      + map_public_ip_on_launch                        = false
      + owner_id                                       = (known after apply)
      + private_dns_hostname_type_on_launch            = (known after apply)
      + tags                                           = {
          + "Name"   = "Private Subnet"
          + "subnet" = "private-us-east-1a"
        }
      + tags_all                                       = {
          + "Name"   = "Private Subnet"
          + "subnet" = "private-us-east-1a"
        }
      + vpc_id                                         = (known after apply)
    }

  # aws_subnet.private-us-east-1b will be created
  + resource "aws_subnet" "private-us-east-1b" {
      + arn                                            = (known after apply)
      + assign_ipv6_address_on_creation                = false
      + availability_zone                              = "us-east-1b"
      + availability_zone_id                           = (known after apply)
      + cidr_block                                     = "10.0.2.0/24"
      + enable_dns64                                   = false
      + enable_resource_name_dns_a_record_on_launch    = false
      + enable_resource_name_dns_aaaa_record_on_launch = false
      + id                                             = (known after apply)
      + ipv6_cidr_block_association_id                 = (known after apply)
      + ipv6_native                                    = false
      + map_public_ip_on_launch                        = false
      + owner_id                                       = (known after apply)
      + private_dns_hostname_type_on_launch            = (known after apply)
      + tags                                           = {
          + "Name"   = "Private Subnet"
          + "subnet" = "private-us-east-1b"
        }
      + tags_all                                       = {
          + "Name"   = "Private Subnet"
          + "subnet" = "private-us-east-1b"
        }
      + vpc_id                                         = (known after apply)
    }

  # aws_subnet.public-us-east-1a will be created
  + resource "aws_subnet" "public-us-east-1a" {
      + arn                                            = (known after apply)
      + assign_ipv6_address_on_creation                = false
      + availability_zone                              = "us-east-1a"
      + availability_zone_id                           = (known after apply)
      + cidr_block                                     = "10.0.3.0/24"
      + enable_dns64                                   = false
      + enable_resource_name_dns_a_record_on_launch    = false
      + enable_resource_name_dns_aaaa_record_on_launch = false
      + id                                             = (known after apply)
      + ipv6_cidr_block_association_id                 = (known after apply)
      + ipv6_native                                    = false
      + map_public_ip_on_launch                        = true
      + owner_id                                       = (known after apply)
      + private_dns_hostname_type_on_launch            = (known after apply)
      + tags                                           = {
          + "Name"   = "Public Subnet"
          + "subnet" = "public-us-east-1a"
        }
      + tags_all                                       = {
          + "Name"   = "Public Subnet"
          + "subnet" = "public-us-east-1a"
        }
      + vpc_id                                         = (known after apply)
    }

  # aws_subnet.public-us-east-1b will be created
  + resource "aws_subnet" "public-us-east-1b" {
      + arn                                            = (known after apply)
      + assign_ipv6_address_on_creation                = false
      + availability_zone                              = "us-east-1b"
      + availability_zone_id                           = (known after apply)
      + cidr_block                                     = "10.0.4.0/24"
      + enable_dns64                                   = false
      + enable_resource_name_dns_a_record_on_launch    = false
      + enable_resource_name_dns_aaaa_record_on_launch = false
      + id                                             = (known after apply)
      + ipv6_cidr_block_association_id                 = (known after apply)
      + ipv6_native                                    = false
      + map_public_ip_on_launch                        = true
      + owner_id                                       = (known after apply)
      + private_dns_hostname_type_on_launch            = (known after apply)
      + tags                                           = {
          + "Name"   = "Public Subnet"
          + "subnet" = "public-us-east-1b"
        }
      + tags_all                                       = {
          + "Name"   = "Public Subnet"
          + "subnet" = "public-us-east-1b"
        }
      + vpc_id                                         = (known after apply)
    }

  # aws_vpc.mycustomvpc will be created
  + resource "aws_vpc" "mycustomvpc" {
      + arn                                  = (known after apply)
      + cidr_block                           = "10.0.0.0/16"
      + default_network_acl_id               = (known after apply)
      + default_route_table_id               = (known after apply)
      + default_security_group_id            = (known after apply)
      + dhcp_options_id                      = (known after apply)
      + enable_dns_hostnames                 = true
      + enable_dns_support                   = true
      + enable_network_address_usage_metrics = (known after apply)
      + id                                   = (known after apply)
      + instance_tenancy                     = "default"
      + ipv6_association_id                  = (known after apply)
      + ipv6_cidr_block                      = (known after apply)
      + ipv6_cidr_block_network_border_group = (known after apply)
      + main_route_table_id                  = (known after apply)
      + owner_id                             = (known after apply)
      + tags                                 = {
          + "Name"  = "my custom VPC"
          + "owner" = "jjongguet"
        }
      + tags_all                             = {
          + "Name"  = "my custom VPC"
          + "owner" = "jjongguet"
        }
    }

Plan: 14 to add, 0 to change, 0 to destroy.
aws_eip.nat: Creating...
aws_vpc.mycustomvpc: Creating...
aws_eip.nat: Creation complete after 2s [id=eipalloc-0da22a03345214780]
aws_vpc.mycustomvpc: Still creating... [10s elapsed]
aws_vpc.mycustomvpc: Creation complete after 15s [id=vpc-0b9339f426638f4f8]
aws_subnet.private-us-east-1a: Creating...
aws_subnet.public-us-east-1b: Creating...
aws_internet_gateway.igw: Creating...
aws_subnet.public-us-east-1a: Creating...
aws_subnet.private-us-east-1b: Creating...
aws_internet_gateway.igw: Creation complete after 1s [id=igw-00483195ebf05db32]
aws_route_table.publicroute: Creating...
aws_subnet.private-us-east-1b: Creation complete after 1s [id=subnet-0681ec35e7c4918fa]
aws_subnet.private-us-east-1a: Creation complete after 1s [id=subnet-06d732154283ee20f]
aws_route_table.publicroute: Creation complete after 2s [id=rtb-0495d794f90907b39]
aws_subnet.public-us-east-1b: Still creating... [10s elapsed]
aws_subnet.public-us-east-1a: Still creating... [10s elapsed]
aws_subnet.public-us-east-1b: Creation complete after 12s [id=subnet-0f81190c1e830b3a0]
aws_route_table_association.publicassociation_b: Creating...
aws_subnet.public-us-east-1a: Creation complete after 12s [id=subnet-08b1566fc05928172]
aws_route_table_association.publicassociation_a: Creating...
aws_nat_gateway.nat: Creating...
aws_route_table_association.publicassociation_a: Creation complete after 1s [id=rtbassoc-0ebb5419c4026237e]
aws_route_table_association.publicassociation_b: Creation complete after 1s [id=rtbassoc-0d9da5b464ef52084]
aws_nat_gateway.nat: Still creating... [10s elapsed]
aws_nat_gateway.nat: Still creating... [20s elapsed]
aws_nat_gateway.nat: Still creating... [30s elapsed]
aws_nat_gateway.nat: Still creating... [40s elapsed]
aws_nat_gateway.nat: Still creating... [50s elapsed]
aws_nat_gateway.nat: Still creating... [1m0s elapsed]
aws_nat_gateway.nat: Still creating... [1m10s elapsed]
aws_nat_gateway.nat: Still creating... [1m20s elapsed]
aws_nat_gateway.nat: Creation complete after 1m26s [id=nat-07bac438d83b5b7df]
aws_route_table.privateroute: Creating...
aws_route_table.privateroute: Creation complete after 3s [id=rtb-0b827c6370885b05b]
aws_route_table_association.privateassociation_a: Creating...
aws_route_table_association.privateassociation_b: Creating...
aws_route_table_association.privateassociation_b: Creation complete after 1s [id=rtbassoc-0422bcd3af70210b5]
aws_route_table_association.privateassociation_a: Creation complete after 1s [id=rtbassoc-0a5e459124a21b867]

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

 

 

 

AWS 대시보드에서 확인

  • region: us-east-1b

 

 

  • VPC 대시보드 : 리전별 리소스 항목에서 배포한 리소스를 확인할 수 있습니다.

  • VPC: "10.0.0.0/16” 대역으로 설정한 VPC 가 설정되어있습니다.
    태그에 owner도 제대로 설정되어있습니다. (이미지엔 이번에 배포되지않은 VPC 도 함께캡쳐되어있습니다)

 

 

실습종료(리소스 제거): tofu destroy --auto-approve

tofu destroy --auto
jjongguet