본문 바로가기
IaC/Terraform

[Terraform] 2-1. EC2 웹 서버 커스터마이징하기

by okms1017 2024. 6. 22.
728x90

✍ Posted by Immersive Builder  Seong

 

 

1. 실습 소개

이번 실습에서는 이전 코드를 일부 수정하여 EC2 웹 서버를 커스터마이징합니다. 

직접 VPC를 구성하고 busybox를 통해 웹 서비스를 제공하는 부분이 지난 실습과는 다른 내용입니다. 

 

  • Step1. VPC 구성하기 
  • Step2. 유저데이터(user_data) 작성 
  • Step3. EC2 웹 서버 배포 및 접속 테스트 

 

이전 실습 코드는 하기 링크를 참고하시기 바랍니다.

(**변경 및 추가한 코드만 기술합니다.)

 


▶ 이전 포스팅

 

[Terraform] 1-2. Cloud-init을 활용하여 EC2 웹 서버 배포하기

✍ Posted by Immersive Builder  Seong  1. 실습 소개 이번 실습에서는 테라폼을 사용하여 간단한 EC2 웹 서버를 배포합니다. 실습은 AWS 환경에서 진행하며, 작업 순서는 하기와 같습니다.  Step1. 기본

okms1017.tistory.com

 


2. EC2 웹 서버 커스터마이징하기

Step1. VPC 구성하기 

기본 VPC(default)가 아닌 직접 VPC를 구성하여 EC2 웹 서버를 배포할 예정입니다. 

VPC, AZ, Subnet을 지정하고 라우팅 테이블을 생성하여 Subnet에 연결합니다. 

 

1) VPC : seong-vpc (10.10.0.0/16) 

 


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

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

 

  • cidr_block : 지정한 VPC 영역 (10.10.0.0/16)
  • enable_dns_support : DNS 옵션 활성화 
  • enable_dns_hostnames : DNS 호스트 이름 활성화 

 

2) Subnet : seong-subnet1(10.10.1.0/24), seong-subnet2(10.10.2.0/24) 

 


        data "aws_availability_zones" "available" {
          state = "available"
        }

        resource "aws_subnet" "seong_subnet1" {
          vpc_id     = aws_vpc.seong_vpc.id
          cidr_block = "10.10.1.0/24"

          availability_zone = data.aws_availability_zones.available.names[0]

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

        resource "aws_subnet" "seong_subnet2" {
          vpc_id     = aws_vpc.seong_vpc.id
          cidr_block = "10.10.2.0/24"

          availability_zone = data.aws_availability_zones.available.names[2]

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

 

  • data.aws_availability_zones.available : 가용영역 정보를 가져오기 위한 데이터 소스 
  • aws_subnet.seong_subnet.cidr_block : 지정한 서브넷 네트워크 대역 
  • data.aws_availability_zones.available.names[0] : 가용영역 (ap-northeast-2a)
  • data.aws_availability_zones.available.names[2] : 가용영역 (ap-northeast-2c) 
  • aws_subnet.seong_subnet.tags.Name : 서브넷 태그명 

 

3) Internet Gateway : seong-igw

 


        resource "aws_internet_gateway" "seong_igw" {
          vpc_id = aws_vpc.seong_vpc.id

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

 

  • aws_internet_gateway.seong_igw.tags.Name : IGW 태그명 

 

4) Route Table : seong_rt, seong_rt_association1, seong_rt_association2, seong_default_route 

 


        resource "aws_route_table" "seong_rt" {
          vpc_id = aws_vpc.seong_vpc.id

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

        resource "aws_route_table_association" "seong_rt_association1" {
          subnet_id      = aws_subnet.seong_subnet1.id
          route_table_id = aws_route_table.seong_rt.id
        }

        resource "aws_route_table_association" "seong_rt_association2" {
          subnet_id      = aws_subnet.seong_subnet2.id
          route_table_id = aws_route_table.seong_rt.id
        }

        resource "aws_route" "seong_default_route" {
          route_table_id         = aws_route_table.seong_rt.id
          destination_cidr_block = "0.0.0.0/0"
          gateway_id             = aws_internet_gateway.seong_igw.id
        }

 

  • aws_route_table.seong_rt : VPC(10.10.0.0/16)에 생성할 라우팅 테이블 리소스 
  • aws_route_table_association.seong_rt_association : 명시적으로 서브넷에 연결하기 위한 리소스 
  • aws_route.seong_default_route : destination(0.0.0.0/0) 트래픽은 IGW(seong_igw)를 경유하는 라우팅 규칙 

 

Step2. 유저데이터(user_data) 작성 

t2.micro 타입의 EC2 인스턴스를 배포하고

해당 인스턴스에 busybox를 설치하여 웹 서비스를 기동하는 유저데이터를 작성합니다. 

 


        resource "aws_instance" "seong_ec2" {

          depends_on = [
            aws_internet_gateway.seong_igw
          ]

          ami                         = data.aws_ami.seong_amazonlinux2.id
          associate_public_ip_address = true
          instance_type               = "t2.micro"
          vpc_security_group_ids      = ["${aws_security_group.seong_ec2_sg.id}"]
          subnet_id                   = aws_subnet.seong_subnet1.id

          user_data = <<-EOF
                      #!/bin/bash
                      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 = "seong-ec2"
          }
        }
 

 

  • aws_instance.seong_ec2 : EC2 인스턴스 리소스 선언
  • aws_instance.seong_ec2.dependes_on : IGW 생성 이후 EC2 인스턴스를 생성하도록 제어하는 메타인수
  • data.aws_ami.seong_amazonlinux2.id : 최신 amzn2 AMI 이미지를 가져옴 
  • aws_instance.seong_ec2.associate_public_ip_address : EC2 인스턴스를 생성하면서 공인 IP를 할당함
  • aws_instance.seong_ec2.instance_type : EC2 인스턴스 타입 (t2.micro) 
  • aws_instance.seong_ec2.user_data : EC2 인스턴스 시작 시 실행할 명령어 스크립트 
  • user_data_replace_on_change : 유저데이터 변경에 따른 동작 여부 - 인스턴스 재생성(true) / 인스턴스 유지(false) 
  • aws_instance.seong_ec2.tags.Name : EC2 인스턴스 태그명 

 

Step3. EC2 웹 서버 배포 및 접속 테스트 

구성파일 작성을 완료하면 실행계획을 생성하고 EC2 웹 서버를 배포합니다. 

 

$ terraform init && terraform plan && terraform apply -auto-approve

 

서버가 배포되고 어플리케이션이 실행되기까지 약 3분 정도가 소요됩니다. 

직접 구성한 VPC(10.10.0.0/16)의 1번 Subnet(10.10.1.0/24)에 서버가 배포되고, 외부 접속이 가능한 공인 IP( 52.79.168.107)를 할당받았습니다. 

 

VPC 배포 확인 (seong-vpc)
Subnet 배포 확인 (seong-subnet1,2)
IGW 배포 확인 (seong-igw)
라우팅 테이블 확인 (seong-rt)
라우팅 테이블 서브넷 연결 확인 (seong-rt)
EC2 웹 서버 배포 확인 (seong-ec2)

 

  • WEB 서비스 테스트 

WEB 서비스에 정상적으로 접속이 되는지 테스트합니다. 

 

$ MYIP=$(terraform output -raw seong_ec2_public_ip)

$ while true; do curl --connect-timeout 1 http://$MYIP/ ; echo "------------------------------"; date; sleep 1; done

------------------------------
Sat Jun 22 23:09:35 KST 2024
<h1>RegionAz(apne2-az1) : Instance ID(i-0b1306735aa09e850) : Private IP(10.10.1.6) : Web Server</h1>
------------------------------

 

실습을 완료하고 리소스를 반납합니다. 

 

$ terraform destroy -auto-approve

 

 


[출처] 

1) CloudNet@, T1014 실습 스터디 

2) https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/availability_zones

 

Terraform Registry

 

registry.terraform.io

 

728x90