Windows 10 환경에서 Terraform을 이용한 AWS 자원 배포 - 3. VPC 및 기타 자원 배포
기존에 default VPC로 사용한 배포환경을 직접 Custom 한 VPC로 구성하는 방법을 실습함
이번에는 main.tf 파일에 모두 선언하는게 아닌 AWS 각 자원 별로 나눠서 작성하고 배포하는 실습을 수행함
vpc, subnet, 보안그룹 등 여러 자원을 하나의 파일이 아닌 다른 파일로 나눠서 작성하고 배포할 수 있다.
1. VPC 생성
// 임의의 폴더를 생성하고 해당 폴더에서 작업
mkdir study2
cd study2
// VPC 생성 스크립트 (윈도우 cmd)
echo provider "aws" { > study2_vpc.tf
echo region = "ap-northeast-2" >> study2_vpc.tf
echo } >> study2_vpc.tf
echo. >> study2_vpc.tf
echo resource "aws_vpc" "ersia_vpc" { >> study2_vpc.tf
echo cidr_block = "10.10.0.0/16" >> study2_vpc.tf
echo enable_dns_support = true >> study2_vpc.tf
echo enable_dns_hostnames = true >> study2_vpc.tf
echo. >> study2_vpc.tf
echo tags = { >> study2_vpc.tf
echo Name = "t101-study" >> study2_vpc.tf
echo } >> study2_vpc.tf
echo } >> study2_vpc.tf
type study2_vpc.tf
// terraform init, plan, apply 수행
terraform init
terraform plan && terraform apply -auto-approve
vpc 생성 시에 dns설정과 같은 옵션은 Terraform 레지스트리 문서에서 지원여부를 확인할 수 있다.
terraform 수행 시 auto-approve는 apply 시 'yes' 입력하는 부분을 자동으로 승낙하기 위한 명령 옵션이다.
정상 수행 완료 및 AWS CLI를 통해 생성 확인
...
...
...
+ tags_all = {
+ "Name" = "t101-study"
}
}
Plan: 1 to add, 0 to change, 0 to destroy.
aws_vpc.ersia_vpc: Creating...
aws_vpc.ersia_vpc: Still creating... [10s elapsed]
aws_vpc.ersia_vpc: Creation complete after 11s [id=vpc-0700db122b73ff234]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
c:\terraform_study\study2>aws ec2 describe-vpcs --output yaml
Vpcs:
- CidrBlock: 10.10.0.0/16
CidrBlockAssociationSet:
- AssociationId: vpc-cidr-assoc-09ae457e9aa4d0c4f
CidrBlock: 10.10.0.0/16
CidrBlockState:
State: associated
DhcpOptionsId: dopt-af11b7c4
InstanceTenancy: default
IsDefault: false
OwnerId: '411158671563'
State: available
Tags:
- Key: Name
Value: t101-study
VpcId: vpc-0700db122b73ff234
c:\terraform_study\study2>
2. Subnet 생성
vpc를 생성한 폴더와 같은 폴더에서 아래의 작업을 수행해야 함
// Subnet 생성
echo resource "aws_subnet" "ersia_subnet1" { > study2_subnet.tf
echo vpc_id = aws_vpc.ersia_vpc.id >> study2_subnet.tf
echo cidr_block = "10.10.1.0/24" >> study2_subnet.tf
echo. >> study2_subnet.tf
echo availability_zone = "ap-northeast-2a" >> study2_subnet.tf
echo. >> study2_subnet.tf
echo tags = { >> study2_subnet.tf
echo Name = "t101-subnet1" >> study2_subnet.tf
echo } >> study2_subnet.tf
echo } >> study2_subnet.tf
echo. >> study2_subnet.tf
echo resource "aws_subnet" "ersia_subnet2" { >> study2_subnet.tf
echo vpc_id = aws_vpc.ersia_vpc.id >> study2_subnet.tf
echo cidr_block = "10.10.2.0/24" >> study2_subnet.tf
echo. >> study2_subnet.tf
echo availability_zone = "ap-northeast-2c" >> study2_subnet.tf
echo. >> study2_subnet.tf
echo tags = { >> study2_subnet.tf
echo Name = "t101-subnet2" >> study2_subnet.tf
echo } >> study2_subnet.tf
echo } >> study2_subnet.tf
type study2_subnet.tf
// terraform plan 및 apply 수행
terraform plan && terraform apply -auto-approve
정상 수행 완료 및 AWS CLI를 통해 생성 확인
...
...
...
+ vpc_id = "vpc-0700db122b73ff234"
}
Plan: 2 to add, 0 to change, 0 to destroy.
aws_subnet.ersia_subnet1: Creating...
aws_subnet.ersia_subnet2: Creating...
aws_subnet.ersia_subnet2: Creation complete after 0s [id=subnet-0b23c6f7ce25fc54d]
aws_subnet.ersia_subnet1: Creation complete after 0s [id=subnet-028cfc6f8d7a7583c]
Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
c:\terraform_study\study2>
c:\terraform_study\study2>aws ec2 describe-subnets --output text
SUBNETS False ap-northeast-2a apne2-az1 251 10.10.1.0/24 False False False False False 411158671563 available arn:aws:ec2:ap-northeast-2:411158671563:subnet/subnet-028cfc6f8d7a7583c subnet-028cfc6f8d7a7583c vpc-0700db122b73ff234
PRIVATEDNSNAMEOPTIONSONLAUNCH False False ip-name
TAGS Name t101-subnet1
SUBNETS False ap-northeast-2c apne2-az3 251 10.10.2.0/24 False False False False False 411158671563 available arn:aws:ec2:ap-northeast-2:411158671563:subnet/subnet-0b23c6f7ce25fc54d subnet-0b23c6f7ce25fc54d vpc-0700db122b73ff234
PRIVATEDNSNAMEOPTIONSONLAUNCH False False ip-name
TAGS Name t101-subnet2
c:\terraform_study\study2>
여기서 주의깊게 볼 부분은 vpc_id를 할당하는 부분이다.
subnet을 선언하는 코드에서 aws_vpc.ersia_vpc.id 로 선언한 vpc의 id를 활용해서 사용하는 것을 볼 수 있다.
3. Internet GateWay 생성
// Internet GateWay 생성
echo resource "aws_internet_gateway" "ersia_igw" { > study2_igw.tf
echo vpc_id = aws_vpc.ersia_vpc.id >> study2_igw.tf
echo. >> study2_igw.tf
echo tags = { >> study2_igw.tf
echo Name = "t101-igw" >> study2_igw.tf
echo } >> study2_igw.tf
echo } >> study2_igw.tf
type study2_igw.tf
// terraform plan 및 apply 수행
terraform plan && terraform apply -auto-approve
4. Route Table 생성 및 Subnet 연결
// Route Table 생성
echo resource "aws_route_table" "ersia_rt" { > study2_routetable.tf
echo vpc_id = aws_vpc.ersia_vpc.id >> study2_routetable.tf
echo. >> study2_routetable.tf
echo tags = { >> study2_routetable.tf
echo Name = "t101-rt" >> study2_routetable.tf
echo } >> study2_routetable.tf
echo } >> study2_routetable.tf
echo. >> study2_routetable.tf
echo resource "aws_route_table_association" "ersia_rt_association1" { >> study2_routetable.tf
echo subnet_id = aws_subnet.ersia_subnet1.id >> study2_routetable.tf
echo route_table_id = aws_route_table.ersia_rt.id >> study2_routetable.tf
echo } >> study2_routetable.tf
echo. >> study2_routetable.tf
echo resource "aws_route_table_association" "ersia_rt_association2" { >> study2_routetable.tf
echo subnet_id = aws_subnet.ersia_subnet2.id >> study2_routetable.tf
echo route_table_id = aws_route_table.ersia_rt.id >> study2_routetable.tf
echo } >> study2_routetable.tf
echo. >> study2_routetable.tf
echo resource "aws_route" "ersia_defaultroute" { >> study2_routetable.tf
echo route_table_id = aws_route_table.ersia_rt.id >> study2_routetable.tf
echo destination_cidr_block = "0.0.0.0/0" >> study2_routetable.tf
echo gateway_id = aws_internet_gateway.ersia_igw.id >> study2_routetable.tf
echo } >> study2_routetable.tf
type study2_routetable.tf
// terraform plan 및 apply 수행
terraform plan && terraform apply -auto-approve
5. 보안그룹 생성
// 보안그룹 생성
echo resource "aws_security_group" "ersia_sg" { > study2_sg.tf
echo vpc_id = aws_vpc.ersia_vpc.id >> study2_sg.tf
echo name = "T101 SG" >> study2_sg.tf
echo description = "T101 Study SG" >> study2_sg.tf
echo } >> study2_sg.tf
echo. >> study2_sg.tf
echo resource "aws_security_group_rule" "ersia_sginbound" { >> study2_sg.tf
echo type = "ingress" >> study2_sg.tf
echo from_port = 0 >> study2_sg.tf
echo to_port = 80 >> study2_sg.tf
echo protocol = "tcp" >> study2_sg.tf
echo cidr_blocks = ["0.0.0.0/0"] >> study2_sg.tf
echo security_group_id = aws_security_group.ersia_sg.id >> study2_sg.tf
echo } >> study2_sg.tf
echo. >> study2_sg.tf
echo resource "aws_security_group_rule" "ersia_sgoutbound" { >> study2_sg.tf
echo type = "egress" >> study2_sg.tf
echo from_port = 0 >> study2_sg.tf
echo to_port = 0 >> study2_sg.tf
echo protocol = "-1" >> study2_sg.tf
echo cidr_blocks = ["0.0.0.0/0"] >> study2_sg.tf
echo security_group_id = aws_security_group.ersia_sg.id >> study2_sg.tf
echo } >> study2_sg.tf
// terraform plan 및 apply 수행
terraform plan && terraform apply -auto-approve
6. EC2 및 웹 서비스를 위한 스크립트(userdata) 수행
// EC2 및 userdata 생성
echo data "aws_ami" "ersia_amazonlinux2" { > ec2.tf
echo most_recent = true >> ec2.tf
echo filter { >> ec2.tf
echo name = "owner-alias" >> ec2.tf
echo values = ["amazon"] >> ec2.tf
echo } >> ec2.tf
echo. >> ec2.tf
echo filter { >> ec2.tf
echo name = "name" >> ec2.tf
echo values = ["amzn2-ami-hvm-*-x86_64-ebs"] >> ec2.tf
echo } >> ec2.tf
echo. >> ec2.tf
echo owners = ["amazon"] >> ec2.tf
echo } >> ec2.tf
echo. >> ec2.tf
echo resource "aws_instance" "ersia_ec2" { >> ec2.tf
echo. >> ec2.tf
echo depends_on = [ >> ec2.tf
echo aws_internet_gateway.ersia_igw >> ec2.tf
echo ] >> ec2.tf
echo. >> ec2.tf
echo ami = data.aws_ami.ersia_amazonlinux2.id >> ec2.tf
echo associate_public_ip_address = true >> ec2.tf
echo instance_type = "t2.micro" >> ec2.tf
echo vpc_security_group_ids = ["${aws_security_group.ersia_sg.id}"] >> ec2.tf
echo subnet_id = aws_subnet.ersia_subnet1.id >> ec2.tf
echo. >> ec2.tf
echo user_data = "${file("ec2-userdata-web.tftpl")}" >> ec2.tf
echo. >> ec2.tf
echo user_data_replace_on_change = true >> ec2.tf
echo. >> ec2.tf
echo tags = { >> ec2.tf
echo Name = "t101-jjang" >> ec2.tf
echo } >> ec2.tf
echo } >> ec2.tf
echo. >> ec2.tf
echo output "ersia_ec2_public_ip" { >> ec2.tf
echo value = aws_instance.ersia_ec2.public_ip >> ec2.tf
echo description = "The public IP of the Instance" >> ec2.tf
echo } >> ec2.tf
type ec2.tf
echo #!/bin/bash > ec2-userdata-web.tftpl
echo wget https://busybox.net/downloads/binaries/1.31.0-defconfig-multiarch-musl/busybox-x86_64 >> ec2-userdata-web.tftpl
echo mv busybox-x86_64 busybox >> ec2-userdata-web.tftpl
echo chmod +x busybox >> ec2-userdata-web.tftpl
echo RZAZ=^$(curl http://169.254.169.254/latest/meta-data/placement/availability-zone-id) >> ec2-userdata-web.tftpl
echo IID=^$(curl 169.254.169.254/latest/meta-data/instance-id) >> ec2-userdata-web.tftpl
echo LIP=^$(curl 169.254.169.254/latest/meta-data/local-ipv4) >> ec2-userdata-web.tftpl
echo echo "<h1>RegionAz($RZAZ) : Instance ID($IID) : Private IP($LIP) : Web Server</h1>" ^> index.html >> ec2-userdata-web.tftpl
echo nohup ./busybox httpd -f -p 80 ^& >> ec2-userdata-web.tftpl
type ec2-userdata-web.tftpl
// terraform plan 및 apply 수행
terraform plan && terraform apply -auto-approve
기존에 userdata파일에 변수를 전달하기 위해 templatefile 함수를 사용했지만,
이번에는 변수가 필요하지 않아 file 함수로 사용함
7. 수행 결과 확인 및 자원 삭제
EC2를 제외한 환경은 이어서 실습하기 위해 남겨둠
...
...
...
+ ersia_ec2_public_ip = (known after apply)
aws_instance.ersia_ec2: Creating...
aws_instance.ersia_ec2: Still creating... [10s elapsed]
aws_instance.ersia_ec2: Still creating... [20s elapsed]
aws_instance.ersia_ec2: Creation complete after 21s [id=i-04f5154ef8ec562d4]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Outputs:
ersia_ec2_public_ip = "3.38.213.77"
c:\terraform_study\study2>
c:\terraform_study\study2>set PublicIP=3.38.213.77
c:\terraform_study\study2>curl --connect-timeout 1 http://%PublicIP%/
<h1>RegionAz(apne2-az1) : Instance ID(i-04f5154ef8ec562d4) : Private IP(10.10.1.226) : Web Server</h1>
...
...
...
- throughput = 0 -> null
- volume_id = "vol-0c5ec78613d129e4b" -> null
- volume_size = 8 -> null
- volume_type = "standard" -> null
}
}
Plan: 0 to add, 0 to change, 1 to destroy.
Changes to Outputs:
- ersia_ec2_public_ip = "3.38.213.77" -> null
aws_instance.ersia_ec2: Destroying... [id=i-04f5154ef8ec562d4]
aws_instance.ersia_ec2: Still destroying... [id=i-04f5154ef8ec562d4, 10s elapsed]
aws_instance.ersia_ec2: Still destroying... [id=i-04f5154ef8ec562d4, 20s elapsed]
aws_instance.ersia_ec2: Destruction complete after 30s
Apply complete! Resources: 0 added, 0 changed, 1 destroyed.
c:\terraform_study\study2>