🍀 Cloud Architect/IaC

[Terraform] 테라폼 EC2 배포 실습

나리 집사 2024. 6. 15. 12:53
테라폼으로 시작하는 IaC 책을 기준으로 정리하였습니다.

실습1. AWS CLI 설치 및 자격증명

1. AWS Free-Tier 계정을 생성한다.

2. AWS IAM User를 생성한다. 이때, 관리자 수준 권한(AdministratorAccess)과 프로그래밍 방식 액세스 권한(Access/Secret Key)을 부여한다.

3. AWS CLI v2 설치 및 IAM User 자격 증명 설정

# macOS 설치 방법
$ brew install awscli

# Linux(WSL2) 설치 방법
$ curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
$ unzip awscliv2.zip
$ sudo ./aws/install

# aws cli 버전 확인
$ aws --version
aws-cli/2.7.31 Python/3.10.7 Darwin/21.6.0 source/x86_64 prompt/off

# aws cli 사용 시도, 실패
$ aws s3 ls

# aws configure 로 자격증명 설정 : 방안1
$ aws configure
... >> 입력

# 환경 변수로 자격증명 설정 : 방안2
# Linux or macOS
$ export AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
$ export AWS_SECRET_ACCESS_KEY=wJalrXUtnFYYYYYYYY
$ export AWS_DEFAULT_REGION=us-west-2

# 페이저 사용 비활성화
$ export AWS_PAGER=""

# aws cli 사용 시도
$ aws s3 ls

# 실습 툴 설치
$ sudo apt install -y tree jq

 

실습2-1. EC2 1대 배포

0. 사전 준비

# 작업 디렉터리 생성 및 이동
$ mkdir ec2-test
$ cd ec2-test

# [터미널1] EC2 생성 모니터링
$ export AWS_PAGER=""
$ while true; do aws ec2 describe-instances --query "Reservations[*].Instances[*].{PublicIPAdd:PublicIpAddress,InstanceName:Tags[?Key=='Name']|[0].Value,Status:State.Name}" --filters Name=instance-state-name,Values=running --output text ; echo "------------------------------" ; sleep 1; done

 

1. HCL(Hashicorp Configuration Language) 코드 파일 생성

- provider : Terraform으로 정의할 Infrastructure Provider를 의미 - Docs

- resource : 실제로 생성할 인프라 자원을 의미

$ cat <<EOT > main.tf
provider "aws" {
  region = "ap-northeast-2"
}

resource "aws_instance" "example" {
  ami           = "$AL2ID"
  instance_type = "t2.micro"
}
EOT

resource “<PROVIDER>_<TYPE>” “<NAME>” { [CONFIG ...] }

  • PROVIDER : ‘aws’ 같은 공급자의 이름
  • TYPE : ‘security_group’ 같은 리소스의 유형
  • NAME : 리소스의 이름
  • CONFIG : 한개 이상 arguments

 

2. 터미널에서 배포 실행

아래 3개의 명령어를 이용하여 배포를 실행한다.

terraform init : 초기화

terraform plan : 만들어질 리소스 확인

terraform apply : 실행

# [터미널2] EC2 생성

# 초기화 # 폴더 내에서 초기화하지 않으면 실행 불가
$ terraform init
$ ls -al
$ tree .terraform

# plan 확인
$ terraform plan

# apply 실행
$ terraform apply
 Enter a value: yes 입력

# ec2 생성 확인 : aws 웹 관리 콘솔에서도 확인 - 서울 리전 선택
$ export AWS_PAGER=""
$ aws ec2 describe-instances --output table

배포 실행
터미널1의 실행창

 

실습2-2. EC2 1대 태그 수정

1. HCL 코드 파일 생성

$ cat <<EOT > main.tf
provider "aws" {
  region = "ap-northeast-2"
}

resource "aws_instance" "example" {
  ami           = "$AL2ID"
  instance_type = "t2.micro"

  tags = {
    Name = "t101-study"
  }

}
EOT

2. 배포 실행

$ terraform plan
$ terraform apply

 

실습2-3. EC2 1대 삭제

# 리소스 삭제
$ terraform destroy
 Enter a value: yes

# 혹은 -auto-approve를 사용하여 자동 승인
$ terraform destroy -auto-approve

 

실습3. EC2 1대 배포 & 웹 서버 설정

0. 사전 설정

# 디렉터리 생성
$ mkdir web-test
$ cd web-test

# Ubuntu 22.04 최신 AMI ID 확인
$ aws ec2 describe-images --owners 099720109477 \
    --filters "Name=name,Values=ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*" "Name=state,Values=available" \
    --query 'Images|sort_by(@, &CreationDate)[-1].[ImageId, Name]' --output text

# 변수 지정
$ UBUNTUID=ami-0572f73f0a5650b33

 

1. 코드 파일 작성: user_data에 실행 명령어 작성

$ cat <<EOT > main.tf
provider "aws" {
  region = "ap-northeast-2"
}

resource "aws_instance" "example" {
  ami                    = "$UBUNTUID"
  instance_type          = "t2.micro"
  vpc_security_group_ids = [aws_security_group.instance.id]

  user_data = <<-EOF
              #!/bin/bash
              echo "Hello, T101 Study" > index.html
              nohup busybox httpd -f -p 8080 &
              EOF

  tags = {
    Name = "Single-WebSrv"
  }
}

resource "aws_security_group" "instance" {
  name = var.security_group_name

  ingress {
    from_port   = 8080
    to_port     = 8080
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

variable "security_group_name" {
  description = "The name of the security group"
  type        = string
  default     = "terraform-example-instance"
}

output "public_ip" {
  value       = aws_instance.example.public_ip
  description = "The public IP of the Instance"
}
EOT

2. 배포 실행

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

 

3. 웹 서버 접속 시도: 터미널에서 실행

# [터미널3] 모니터링
$ PIP=3.39.22.130
# $ PIP=$(terraform output -raw public_ip)
$ while true; do curl --connect-timeout 1  http://$PIP:8080/ ; echo "------------------------------"; date; sleep 1; done

# (옵션) 리소스 생성 그래프 확인
$ terraform graph

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

 

(+) 테라폼은 Immutable? Mutable?

테라폼은 Immutable. 인프라스트럭처의 상태를 변경할 때, 기존의 인프라스트럭처를 수정하거나 업데이트하는 것이 아니라 새로운 인프라스트럭처를 생성하여 이전 상태의 인프라스트럭처를 교체하는 방식을 의미한다.