본문 바로가기
Terraform/Terraform 101 Study

2주차 2편 테라폼 기초 - 기본 사용 2/3

by 개발자 영만 2024. 6. 19.

[실습1] VPC + 보안그룹 + EC2 배포

  • default VPC 대신 새로운 VPC를 생성하고 그 안에 EC2 인스턴스를 배포

VPC 생성

  • 새 디렉터리와 Terraform 파일 생성
mkdir my-vpc-ec2
cd my-vpc-ec2
touch vpc.tf
  • vpc.tf 파일 수정
provider "aws" {
  region  = "ap-northeast-2"
}

resource "aws_vpc" "myvpc" {
  cidr_block = "10.10.0.0/16"

  tags = {
    Name = "t101-study"
  }
}
  • Terraform 초기화 및 배포
terraform init
terraform plan
terraform apply -auto-approve
  • VPC 확인
# AWS CLI의 결과를 페이지별로 보여주는 기능을 비활성화
export AWS_PAGER=""

# 모든 VPC의 정보를 JSON 형식으로 출력
aws ec2 describe-vpcs | jq

# 기본 VPC가 아닌 모든 VPC의 정보를 JSON 형식으로 출력
aws ec2 describe-vpcs --filter 'Name=isDefault,Values=false' | jq

#기본 VPC가 아닌 모든 VPC의 정보를 YAML 형식으로 출력
aws ec2 describe-vpcs --filter 'Name=isDefault,Values=false' --output yaml

  • AWS 관리콘솔에서 VPC 생성 정보 확인. DNS 옵션이 활성화되어 있는지 확인

  • vpc.tf 파일 수정 - VPC DNS 옵션 수정
provider "aws" {
  region  = "ap-northeast-2"
}

resource "aws_vpc" "myvpc" {
  cidr_block       = "10.10.0.0/16"
  enable_dns_support   = true
  enable_dns_hostnames = true

  tags = {
    Name = "t101-study"
  }
}
# 배포
terraform plan && terraform apply -auto-approve
  • AWS 관리콘솔에서 VPC 생성 정보 재확인

  • vpc.tf 파일 수정 - VPC 및 서브넷 2개 배포
provider "aws" {
  region  = "ap-northeast-2"
}

resource "aws_vpc" "myvpc" {
  cidr_block       = "10.10.0.0/16"
  enable_dns_support   = true
  enable_dns_hostnames = true

  tags = {
    Name = "t101-study"
  }
}

resource "aws_subnet" "mysubnet1" {
  vpc_id     = aws_vpc.myvpc.id
  cidr_block = "10.10.1.0/24"

  availability_zone = "ap-northeast-2a"

  tags = {
    Name = "t101-subnet1"
  }
}

resource "aws_subnet" "mysubnet2" {
  vpc_id     = aws_vpc.myvpc.id
  cidr_block = "10.10.2.0/24"

  availability_zone = "ap-northeast-2c"

  tags = {
    Name = "t101-subnet2"
  }
}

output "aws_vpc_id" {
  value = aws_vpc.myvpc.id
}
  • 배포 및 확인
# 배포
terraform plan && terraform apply -auto-approve

# 상태에 있는 모든 리소스의 목록을 출력
terraform state list

# 특정 리소스의 상세 정보를 출력
terraform state show aws_subnet.mysubnet1

# 출력 값 조회
terraform output
terraform output aws_vpc_id
terraform output -raw aws_vpc_id

# graph 확인 > graph.dot 파일 선택 후 오른쪽 상단 DOT 클릭
terraform graph > graph.dot

# 서브넷 확인
VPCID=$(terraform output -raw aws_vpc_id)
aws ec2 describe-subnets --output text
aws ec2 describe-subnets --filters "Name=vpc-id,Values=$VPCID" | jq
aws ec2 describe-subnets --filters "Name=vpc-id,Values=$VPCID" --output table

  • vpc.tf 파일 수정 - 인터넷 게이트웨이(IGW) 추가
provider "aws" {
  region  = "ap-northeast-2"
}

resource "aws_vpc" "myvpc" {
  cidr_block       = "10.10.0.0/16"
  enable_dns_support   = true
  enable_dns_hostnames = true

  tags = {
    Name = "t101-study"
  }
}

resource "aws_subnet" "mysubnet1" {
  vpc_id     = aws_vpc.myvpc.id
  cidr_block = "10.10.1.0/24"

  availability_zone = "ap-northeast-2a"

  tags = {
    Name = "t101-subnet1"
  }
}

resource "aws_subnet" "mysubnet2" {
  vpc_id     = aws_vpc.myvpc.id
  cidr_block = "10.10.2.0/24"

  availability_zone = "ap-northeast-2c"

  tags = {
    Name = "t101-subnet2"
  }
}


resource "aws_internet_gateway" "myigw" {
  vpc_id = aws_vpc.myvpc.id

  tags = {
    Name = "t101-igw"
  }
}

output "aws_vpc_id" {
  value = aws_vpc.myvpc.id
}

 

  • 배포 및 확인
terraform plan && terraform apply -auto-approve
terraform state list
terraform state show aws_internet_gateway.myigw

  • vpc.tf 파일 수정 - 라우팅 설정 추가
provider "aws" {
  region  = "ap-northeast-2"
}

resource "aws_vpc" "myvpc" {
  cidr_block       = "10.10.0.0/16"
  enable_dns_support   = true
  enable_dns_hostnames = true

  tags = {
    Name = "t101-study"
  }
}

resource "aws_subnet" "mysubnet1" {
  vpc_id     = aws_vpc.myvpc.id
  cidr_block = "10.10.1.0/24"

  availability_zone = "ap-northeast-2a"

  tags = {
    Name = "t101-subnet1"
  }
}

resource "aws_subnet" "mysubnet2" {
  vpc_id     = aws_vpc.myvpc.id
  cidr_block = "10.10.2.0/24"

  availability_zone = "ap-northeast-2c"

  tags = {
    Name = "t101-subnet2"
  }
}


resource "aws_internet_gateway" "myigw" {
  vpc_id = aws_vpc.myvpc.id

  tags = {
    Name = "t101-igw"
  }
}

resource "aws_route_table" "myrt" {
  vpc_id = aws_vpc.myvpc.id

  tags = {
    Name = "t101-rt"
  }
}

resource "aws_route_table_association" "myrtassociation1" {
  subnet_id      = aws_subnet.mysubnet1.id
  route_table_id = aws_route_table.myrt.id
}

resource "aws_route_table_association" "myrtassociation2" {
  subnet_id      = aws_subnet.mysubnet2.id
  route_table_id = aws_route_table.myrt.id
}

resource "aws_route" "mydefaultroute" {
  route_table_id         = aws_route_table.myrt.id
  destination_cidr_block = "0.0.0.0/0"
  gateway_id             = aws_internet_gateway.myigw.id
}

output "aws_vpc_id" {
  value = aws_vpc.myvpc.id
}
  • 배포 및 확인
terraform plan && terraform apply -auto-approve
terraform state list
terraform state show aws_route.mydefaultroute

# graph 확인 > graph.dot 파일 선택 후 오른쪽 상단 DOT 클릭
terraform graph > graph.dot

# 라우팅 테이블 확인
#aws ec2 describe-route-tables --filters 'Name=tag:Name,Values=t101-rt' --query 'RouteTables[].Associations[].SubnetId'
aws ec2 describe-route-tables --filters 'Name=tag:Name,Values=t101-rt' --output table

보안그룹/EC2 배포

  • sg.tf 파일 생성 - 보안그룹 추가
resource "aws_security_group" "mysg" {
  vpc_id      = aws_vpc.myvpc.id
  name        = "T101 SG"
  description = "T101 Study SG"
}

resource "aws_security_group_rule" "mysginbound" {
  type              = "ingress"
  from_port         = 80
  to_port           = 80
  protocol          = "tcp"
  cidr_blocks       = ["0.0.0.0/0"]
  security_group_id = aws_security_group.mysg.id
}

resource "aws_security_group_rule" "mysgoutbound" {
  type              = "egress"
  from_port         = 0
  to_port           = 0
  protocol          = "-1"
  cidr_blocks       = ["0.0.0.0/0"]
  security_group_id = aws_security_group.mysg.id
}

output "aws_security_group_id" {
  value       = aws_security_group.mysg.id
}
  • 보안그룹 배포
# 배포
terraform plan && terraform apply -auto-approve

# 상태에 있는 모든 리소스의 목록을 조회
terraform state list

# 특정 리소스의 상세 정보를 출력
terraform state show aws_security_group.mysg
terraform state show aws_security_group_rule.mysginbound

# 출력 값 조회
terraform output -raw aws_security_group_id

# 보안그룹 확인
aws ec2 describe-security-groups --group-ids $(terraform output -raw aws_security_group_id)

# graph 확인 > graph.dot 파일 선택 후 오른쪽 상단 DOT 클릭
terraform graph > graph.dot

  • ec2.tf 파일 생성 - EC2 추가
data "aws_ami" "my_amazonlinux2" {
  most_recent = true
  filter {
    name   = "owner-alias"
    values = ["amazon"]
  }

  filter {
    name   = "name"
    values = ["amzn2-ami-hvm-*-x86_64-ebs"]
  }

  owners = ["amazon"]
}

resource "aws_instance" "myec2" {

  depends_on = [
    aws_internet_gateway.myigw
  ]

  ami                         = data.aws_ami.my_amazonlinux2.id
  associate_public_ip_address = true
  instance_type               = "t2.micro"
  vpc_security_group_ids      = ["${aws_security_group.mysg.id}"]
  subnet_id                   = aws_subnet.mysubnet1.id

  user_data = <<-EOF
              #!/bin/bash
              wget https://busybox.net/downloads/binaries/1.31.0-defconfig-multiarch-musl/busybox-x86_64
              mv busybox-x86_64 busybox
              chmod +x busybox
              RZAZ=$(curl http://169.254.169.254/latest/meta-data/placement/availability-zone-id)
              IID=$(curl 169.254.169.254/latest/meta-data/instance-id)
              LIP=$(curl 169.254.169.254/latest/meta-data/local-ipv4)
              echo "<h1>RegionAz($RZAZ) : Instance ID($IID) : Private IP($LIP) : Web Server</h1>" > index.html
              nohup ./busybox httpd -f -p 80 &
              EOF

  user_data_replace_on_change = true

  tags = {
    Name = "t101-myec2"
  }
}

output "myec2_public_ip" {
  value       = aws_instance.myec2.public_ip
  description = "The public IP of the Instance"
}
  • EC2 배포 후 확인
# 배포
terraform plan && terraform apply -auto-approve

# 상태에 있는 모든 리소스의 목록을 조회
terraform state list

# 특정 리소스의 상세 정보를 출력
terraform state show data.aws_ami.my_amazonlinux2
terraform state show aws_instance.myec2

# 데이터소스 값 확인
terraform console
> data.aws_ami.my_amazonlinux2
> data.aws_ami.my_amazonlinux2.id
> data.aws_ami.my_amazonlinux2.image_id
> data.aws_ami.my_amazonlinux2.name
> data.aws_ami.my_amazonlinux2.owners
> data.aws_ami.my_amazonlinux2.platform_details
> data.aws_ami.my_amazonlinux2.hypervisor
> data.aws_ami.my_amazonlinux2.architecture
> exit

# graph 확인 > graph.dot 파일 선택 후 오른쪽 상단 DOT 클릭
terraform graph > graph.dot

# 출력된 EC2 퍼블릭IP로 cul 접속 확인
terraform output -raw myec2_public_ip
MYIP=$(terraform output -raw myec2_public_ip)
while true; do curl --connect-timeout 1  http://$MYIP/ ; echo "------------------------------"; date; sleep 1; done

삭제

terraform destroy -auto-approve