Terraform Install
Terraform은 크게 3가지 방법을 통해 설치할 수 있다.
- 이미 빌드된 바이너리 파일을 다운로드
- 테라폼 소스 코드를 다운로드 후 빌드하기
- OS 패키지 관리자를 활용하기
나는 OS 패키지 관리자를 통한 설치를 진행할 것이고,
macbook과 윈도우 환경에 WSL 환경 2가지를 사용하고 있으므로 두가지 방법에 대해 서술하겠다.
- WSL (Ubuntu)
$ wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
$ echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
$ sudo apt update && sudo apt install terraform
Terraform version 확인
- Mac
Terraform은 IaC(ode)로 os 편집기 외에 IDE를 통해 사용하는 것이 효율적이다.
IDE는 VSCode을 사용하여 작성했다. (pycharm, intellij 등 여러 IDE가 있으므로 기호에 맞게 사용한다.)
OS 설정을 완료하였으니, IDE에서 HCL 문법의 하이라이팅 기능을 사용할 수 있는 extension 프로그램을 설치하자
설치가 되면 아래와 같이 문법에 맞춰 색이 알록달록 적용된다.
Terraform으로 EC2 배포
사전 준비 - AWS CLI 설치
# AWS CLI 설치 방법
$ 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 configure
# AWS Command test
# AWS Default VPC 생
# default VPC를 생성
aws ec2 create-default-vpc
# default Subnet 생성
aws ec2 create-default-subnet --availability-zone ap-northeast-2a
aws ec2 create-default-subnet --availability-zone ap-northeast-2b
aws ec2 create-default-subnet --availability-zone ap-northeast-2c
aws ec2 create-default-subnet --availability-zone ap-northeast-2d
1) Amazon Linux2 최신 ami id 찾기
$ aws ec2 describe-images --owners amazon --filters "Name=name,Values=amzn2-ami-hvm-2.0.*-x86_64-gp2" "Name=state,Values=available" --query 'Images|sort_by(@, &CreationDate)[-1].[ImageId]' --output text
# 결과 (업데이트가 자주되므로 변경될 수 있음
ami-0d1530d2e1de1db7c
# 쿼리된 Image ID를 변수에 넣어 Terraform 사용 시 유동성 있게 사용한다.
$ AL2ID=`aws ec2 describe-images --owners amazon --filters "Name=name,Values=amzn2-ami-hvm-2.0.*-x86_64-gp2" "Name=state,Values=available" --query 'Images|sort_by(@, &CreationDate)[-1].[ImageId]' --output text`
2) Terraform code 작성
- provider : Terraform으로 정의할 Infrastructure Provider를 의미
- resource : 생성할 자원을 의미
# 변수 값을 가지고 오기 위해 IDE가 아닌 shell에서 파일을 생성한다.
# 차후 data 값으로 id 입력
$ cat <<EOT > main.tf
provider "aws" {
region = "ap-northeast-2"
}
resource "aws_instance" "example" {
ami = "$AL2ID"
instance_type = "t2.micro"
}
EOT
command로 입력 시 아래와 같이 변수의 실행 값이 파일에 저장됨
배포 실행
$ terraform init
$ terraform plan
$ terraform apply
- init
.terraform 디렉터리가 생성되고, 해당 디렉터리 구조를 보면
선언된 provider를 사용할 수 있도록 관련 패키지가 생성된다.
- plan
Create 또는 Destory인지 리소스 액션에 대한 심볼이 표시되고,
하위에는 main.tf 파일에 선언된 리소스의 설정이 반영된다.
plan은 리소스를 생성하지 않고, 진행 절차를 확인하는 일종의 검토 기능이다.
- apply
console에 표기되는 부분 중 리소스 정의에 대한 부분은 plan과 동일하고,
진짜 배포할 것인지 확인하는 approve 절차가 있다.
간단히 yes 쳐주면 쇼로록 배포가 된다.
배포가 완료된 후 콘솔과 CLI 에서 Instance 생성 내역을 확인해보자.
- AWS Console
- AWS CLI
$ aws ec2 describe-instances --output table
- Tag 추가
지금 EC2를 배포한 코드에는 instance의 이름이 없다.
instance의 이름을 부여하기 위해 코드를 수정하고 배포해보자.
cat <<EOT > main.tf
provider "aws" {
region = "ap-northeast-2"
}
resource "aws_instance" "example" {
ami = "$AL2ID"
instance_type = "t2.micro"
# 이 부분에 추가로 tags라는 블럭을 추가했다.
tags = {
Name = "t101-study"
}
}
EOT
plan을 수행하면 tags 값이 추가된다는 내용이 보인다.
자원이 새로 생성되거나, 삭제되는 것이 아니고 설정 변경이므로 update 표기된다.
인스턴스 정보를 확인해보면 이렇게 태그가 설정된 것을 확인할 수 있다.
- AWS CLI
- AWS Console
- destory
terraoform으로 생성되고, terraform.tfstate에 기록되어 있는 자원을 삭제한다.
삭제되는 것을 보면 aws nuke 처럼 무자비해보인다...
어떤 것들이 삭제되는지 보여주고 apply 와 동일하게 yes를 입력하면 자원이 바로 삭제된다.
(추가로 yes를 입력하기 싫거나 배포, 삭제가 확실하다면 -auto-approve 옵션을 주면 yes를 입력하는 절차를 생략한다.)
$ terraform destroy
콘솔과 CLI에서도 자원이 잘 삭제된 것을 확인할 수 있다.
Terraform으로 웹 서비스가 올라간 Instance 배포
- Ubuntu AMI를 사용하기 위해 AMI ID 조회
# 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
- Terraform 코드 파일 작성
provider "aws" {
region = "ap-northeast-2"
}
resource "aws_instance" "example" {
ami = "$UBUNTUID"
instance_type = "t2.micro"
# 인스턴스 내부 후속 작업을 위해 user_data 블럭 추가
user_data = <<-EOF
#!/bin/bash
echo "Hello, T101 Study" > index.html
nohup busybox httpd -f -p 8080 &
EOF
tags = {
Name = "terraform-Study-101"
}
}
EOT
- 생성된 파일 배포
Plan 내에 ami, instance_type, tags 값이 표시되어 있고, User_data는 인코딩되어 표시된다.
배포 확인 후 접속 테스트
$ curl --connect-timeout 1 http://43.203.254.108:8080
# 접속 실패 오류 구문
curl: (28) Connection timed out after 1001 milliseconds
** 접속 실패의 이유 **
Terraform 코드를 보면 인스턴스를 생성하고, user_data를 통한 내부 설정만 존재한다.
8080 포트로 통신하기 위한 방화벽 설정이 없어 통신에 실패한 것이다.
- SG 설정을 포함하여 수정된 코드 배포
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"
}
}
## Security group에 ingress(inbound) 정책을 추가하는 구문
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"
}
Terraform 변경 사항에서 SG 추가 내역 확인
Output 블럭으로 공인 IP 확인 및 curl 접속 테스트해보자.
인스턴스 내부 설정이 완료되기 까지는 refused가 발생하지만 내부 설정 완료이 완료되면 정상 접속이 된다.
웹 서비스의 포트를 변경해야 한다면 어떻게 해야할까?
먼저 테라폼 코드 수정이 필요하다.
포트포워딩을 하지 않고, 인스턴스의 Listen 포트로 접속하기 때문에 웹 서비스의 Listen 포트를 수정해야한다.
방화벽 정책 역시 변경된 포트로 허용해야 Instance 내부까지 통신이 도달할 수 있다.
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 9090 &
EOF
tags = {
Name = "Single-WebSrv"
}
}
## Security group에 ingress(inbound) 정책을 추가하는 구문
resource "aws_security_group" "instance" {
name = var.security_group_name
# 서비스 포트가 변경되었으므로 방화벽 정책 변경
ingress {
from_port = 9090
to_port = 9090
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"
}
Terraform 변경점 확인 시 아래와 같이 user_data의 변경과 Ingress 정책의 변경을 확인할 수 있다.
어찌된 일인지 변경된 두개 포트 모두 접속이 되지 않는다.
이유는 user_data가 변경되었기 때문인데,
Terraform에서 EC2를 제어할 때 user_data 속성이 바뀌면 EC2에 변경된 속성값을 반영해야한다.
이때 사용하는 설정은 user_data_replace_on_change 으로 이 설정에는 True와 False 두 옵션이 존재한다.
두 옵션의 비교는 아래와 같다.
설정 | 동작 방식 | 목적 | 사용 상황 |
user_data_replace_on_change = true | user_data 변경 시 인스턴스를 종료하고 새로 생성 | user_data 변경 사항이 인스턴스에 반영되도록 보장 | 중요한 초기화 스크립트나 설정 변경이 있을 때 |
user_data_replace_on_change = false | user_data 변경 시 인스턴스를 재생성하지 않음 | 인스턴스 재생성을 피하고 변경 사항 반영이 필요하지 않을 때 | 인스턴스 재생성이 부담되거나 중요하지 않은 변경 사항일 때 |
정확하게 반영을 시키기 위해 True로 Instance 자체를 recreate해 적용해 보겠다.
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 9090" > index.html
nohup busybox httpd -f -p 9090 &
EOF
user_data_replace_on_change = true
tags = {
Name = "Single-WebSrv"
}
}
resource "aws_security_group" "instance" {
name = var.security_group_name
ingress {
from_port = 9090
to_port = 9090
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"
}
Terraform plan으로 변경 사항을 다시 확인해주고, 배포와 접속 테스트를 해보자.
true로 설정했기 때문에 destroy and create로 재생성한다고 표시된다.
'Cloud > Terraform' 카테고리의 다른 글
[T101] Terraform 101 Study 2주차 (3) (0) | 2024.06.22 |
---|---|
[T101] Terraform 101 Study 2주차 (2) (0) | 2024.06.21 |
[T101] Terraform 101 Study 2주차 (1) (0) | 2024.06.18 |
[T101] Terraform 101 Study 1주차 (3) (0) | 2024.06.15 |
[T101] Terraform 101 Study 1주차 (1) (0) | 2024.06.10 |