1. 도전과제
[도전과제1] EC2 웹 서버 배포 + 리소스 생성 그래프 확인
- Ubuntu 에 apache(httpd) 를 설치하고 index.html 생성(닉네임 출력)하는 userdata 를 작성해서 설정 배포 후 웹 접속 - 해당 테라폼 코드(파일)를 작성
- (옵션) userdata 부분은 별도의 파일을 참조할 수 있게 data 블록을 활용 할 것 → 아래 링크를 참고해보자
- https://developer.hashicorp.com/terraform/tutorials/provision/cloud-init
- 참고 : hashicat-aws | hashicat-azure | hashicat-gcp | hashicat-ncloud → CSP 환경별 HashiCat 샘플 애플리케이션을 커스텀 해보셔도 됩니다!
- 참고 : Intro to Terraform on Azure
2. Lab1 풀이
폴더 구조
.
├── main.tf
├── userdata.sh
└── variables.tf
main.tf
provider "aws" {
region = var.aws_region
}
resource "aws_instance" "web_server" {
ami = var.ubuntu_ami_id
instance_type = var.instance_type
user_data = data.template_file.user_data.rendered
tags = {
Name = "WebServer"
}
vpc_security_group_ids = [aws_security_group.web_sg.id]
}
resource "aws_security_group" "web_sg" {
name_prefix = "web-sg"
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
data "template_file" "user_data" {
template = file("${path.module}/userdata.sh")
vars = {
name = "Younggi"
message = "T101 4기 - Lab1 Ubuntu Deploy"
}
}
variables.tf
variable "aws_region" {
description = "The AWS region to deploy resources in"
default = "us-east-2"
}
variable "instance_type" {
description = "EC2 instance type"
default = "t2.large"
}
variable "ubuntu_ami_id" {
description = "AMI ID for the Ubuntu instance"
default = "ami-01943ba6b3c809b0e"
}
userdata.sh
#!/bin/bash
sudo apt update -y
sudo apt install -y apache2
sudo systemctl start apache2
sudo systemctl enable apache2
echo "Hello, ${name}\n${message}" > /var/www/html/index.html
3. Lab1 해설
template_file 이란?
data 블록
https://developer.hashicorp.com/terraform/tutorials/provision/cloud-init
template_file 공식문서
https://registry.terraform.io/providers/hashicorp/template/latest/docs/data-sources/file
Terraform 0.12 이후 버전에서는 templatefile 함수를 사용하는 것이 더 권장됩니다.
file( ) - 링크
- Terraform에서 파일의 내용을 읽어오는 데 사용되는 내장 함수
- 주어진 경로의 파일을 읽어와 그 내용을 문자열로 반환
${ path.module } - 링크
- Terraform에서 사용되는 내장 변수
- 현재 모듈의 디렉터리 경로
Appendix. #1 - AWS CLI를 사용하여 Ubuntu 20.04 LTS AMI ID 조회
aws ec2 describe-images --region us-east-2 \
--owners 099720109477 \
--filters "Name=name,Values=ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*" "Name=state,Values=available" \
--query 'Images | sort_by(@, &CreationDate)[-1].[ImageId]' \
--output text
- --region us-east-2
- 명령어가 실행될 AWS 리전을 지정
- --owners 099720109477
- 이미지의 소유자를 지정
- 099720109477은 Ubuntu의 공식 AWS 계정 ID
- --filters "Name=name,Values=ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"
- 이미지의 이름이 'ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*'와 일치하는 이미지를 필터링
- "Name=state,Values=available"
- 사용 가능한 상태의 이미지를 필터링
- --query 'Images | sort_by(@, &CreationDate)[-1].[ImageId]'
- JMESPath 쿼리를 사용하여 반환된 이미지 목록에서 생성 날짜를 기준으로 정렬한 후 가장 최근의 이미지 ID만 반환
- --output text
- 출력 형식을 텍스트로 지정
Appendix. #2 - template_file > templatefile
특징 | template_file | templatefile |
사용법 | 데이터 소스로 정의 | 함수로 인라인에서 직접 사용 |
구문 복잡성 | 데이터 소스 정의 후 참조 > 복잡함 | 함수 호출로 직관적 |
버전 | Terraform 0.12 이전에 주로 사용 | Terraform 0.12 이후 내장 함수 |
main.tf
provider "aws" {
region = var.aws_region
}
resource "aws_instance" "web_server" {
ami = var.ubuntu_ami_id
instance_type = var.instance_type
user_data = templatefile("${path.module}/userdata.sh", {
name = "Younggi"
message = "T101 4기 - Lab1 Ubuntu Deploy"
})
tags = {
Name = "WebServer"
}
vpc_security_group_ids = [aws_security_group.web_sg.id]
}
resource "aws_security_group" "web_sg" {
name_prefix = "web-sg"
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}