<참고> 테라폼으로 시작하는 IaC - 김민수, 김재준, 이규석, 이유종 저 한빛미디어
모든 실습은 Mac OS 기준으로 작성되었습니다
2장 실행환경 구성
Terraform 설치 - 실습1
# tfenv - version 관리
brew install tfenv
# tfenv - 설치 가능한 버전 리스트
tfenv list-remote
# tfenv - 특정 버전( 1.5.2 )설치
tfenv install 1.5.2
# tfenv로 설치되어있는 버전 확인
tfenv list
# Terraform 명령어를 터미널에서 자동완성되도록 설정
terraform -install-autocomplete
# 위 스크립트 실행시
# Error executing CLI: Did not find any shells to install 라고 나오는 경우
# 쉘 설정파일 먼저 만든 후 다시 스크립트 실행
touch ~/.zshrc
# 실습에 사용될 Tool 설치
brew install tree jq watch
IDE 설치 및 구성 - Visual Studio Code 사용
- 다운로드 및 설치 - 링크
- 확장도구 (Extention) 추가
AWS CLI 설치 및 자격증명 설정
# aws cli 설치 및 버전 확인
brew install awscli
aws --verion
# 자격증명 설정
aws configure
AWS Access Key ID [********************]:
AWS Secret Access Key [********************]:
Default region name [ap-northeast-2]:
Default output format [None]:
Default VPC에 EC2 1대 배포 - 실습2
ami-06b79cf2aee0d5c92 를 기준으로 생성
# 작업 경로 만들고 이동하기
mkdir ec2-test
cd ec2-test
# ami가 자주 바뀌기때문에 id를 찾아주어야 함
# aws ec2 describe-images --owners self amazon
aws ec2 describe-images --owners self amazon --query 'Images[*].[ImageId]' --output text
aws ssm get-parameters-by-path --path /aws/service/ami-amazon-linux-latest
aws ssm get-parameters-by-path --path /aws/service/ami-amazon-linux-latest --query "Parameters[].Name"
aws ssm get-parameters-by-path --path /aws/service/ami-amazon-linux-latest --query "Parameters[].Value"
# 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
# 배포 코드 파일 작성
cat <<EOT > main.tf
provider "aws" {
region = "ap-northeast-2"
}
resource "aws_instance" "example" {
ami = "ami-06b79cf2aee0d5c92"
instance_type = "t2.micro"
}
EOT
# 배포 - 초기화
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
# 리소스 삭제
terraform destroy -auto-approve
terraform init
3장 기본 사용법
주요 커맨드
# 실습 디렉터리 생성 후 이동
mkdir workspaces
cd workspaces
# 테라폼 실행
terraform
Usage: terraform [-version] [-help] <command> [args]
...
# VS Code 폴더 생성 (03.start) → 새파일 생성 (main.tf)
resource "local_file" "abc" {
content = "abc!"
filename = "${path.module}/abc.txt"
}
# Help
terraform console -help
terraform init -help
# 초기화
terraform init
ls -al
tree .terraform
# plan - 테라폼으로 적용할 인프라의 변경 사항에 관한 실행 계획을 생성
terraform plan
# -detailed-exitcode : **plan 추가 옵션**으로, 파이프라인 설계에서 활용 가능, exitcode가 환경 변수로 구성됨
# -auto-approve 자동 승인 기능 부여 옵션
# plan 결과를 시스템 코드로 출력
terraform plan -detailed-exitcode
# 코드 확인 : 0(변경 사항이 없는 성공), 1(오류가 있음), 2(변경 사항이 있는 성공)
echo $?
2
# (참고) apply 결과에 적용 시도
terraform apply -auto-approve -detailed-exitcode
# apply - 실행
terraform apply
# plan 결과를 지정된 파일(바이너리 형태) 이름으로 생성
terraform plan -out=tfplan
cat tfplan
file tfplan
# apply 실행 : 실행계획이 있으므로 즉시 적용됨
terraform apply tfplan
ls -al abc.txt
# 코드파일 수정
resource "local_file" "abc" {
content = "abc!"
filename = "${path.module}/abc.txt"
}
resource "local_file" "dev" {
content = "def!"
filename = "${path.module}/def.txt"
}
# apply 실행 : 변경(신규 추가) 부분만 반영 확인
terraform apply
...
# local_file.dev will be created
+ resource "local_file" "dev" {
...
Enter a value: yes
# 확인
terraform state list
tree
ls *.txt
# 변경 이전의 실행 계획 적용 시도 > 어떻게 될까요?
terraform apply tfplan
...
# 다시 추가 코드 내용을 삭제
resource "local_file" "abc" {
content = "abc!"
filename = "${path.module}/abc.txt"
}
# 실행 > 어떻게 되나요?
terraform apply
...
Enter a value: yes
...
# 확인
terraform state list
tree
ls *.txt
# 현재 배포된 리소스 확인
terraform state list
local_file.abc
# 다시 생성 : 파일 생성 시간 확인
ls -l abc.txt
terraform apply -replace=local_file.abc -auto-approve
ls -l abc.txt
terraform apply -replace=local_file.abc -auto-approve
ls -l abc.txt
# 제거
terraform destroy
...
Enter a value: yes
...
# 확인
terraform state list
ls *.txt
# 적용 후 코드 파일 내용 확인
terraform fmt
default VPC에 웹 서버 배포 - 실습3
EC2 1대를 배포하면서 userdata 에 웹 서버 설정 → 간단한 애플리케이션 설정 자동화
# 파일 작성
cat <<EOT > main.tf
provider "aws" {
region = "ap-northeast-2"
}
resource "aws_instance" "example" {
ami = "ami-0e9bfdb247cc8de84"
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
# 배포
# plan
terraform plan
+ user_data = "d91ca31904077f0b641b5dd5a783401396ffbf3f"
# apply 실행
# plan/apply
terraform plan
terraform apply -auto-approve
#terraform graph
# 웹서버 접속 - 새 터미널에서 실행
# [터미널3] 변수 지정
PIP=<각자 자신의 EC2 IP>
PIP=xxx.xxx.xxx.xxx
while true; do curl --connect-timeout 1 http://$PIP:8080/ ; echo "------------------------------"; date; sleep 1; done
# 리소스 삭제
terraform destroy -auto-approve
HCL
// 한줄 주석 방법1
# 한줄 주석 방법2
/*
라인
주석
*/
locals {
key1 = "value1" # = 를 기준으로 키와 값이 구분되며
myStr = "TF ♡ UTF-8" # UTF-8 문자를 지원한다.
multiStr = <<EOF
Multi
Line
String
with anytext
EOF
boolean1 = true # boolean true
boolean2 = false # boolean false를 지원한다.
deciaml = 123 # 기본적으로 숫자는 10진수,
octal = 0123 # 0으로 시작하는 숫자는 8진수,
hexadecimal = "0xD5" # 0x 값을 포함하는 스트링은 16진수,
scientific = 1e10 # 과학표기 법도 지원한다.
# funtion 호출 예
myprojectname = format("%s is myproject name", var.project)
# 3항 연산자 조건문을 지원한다.
credentials = var.credentials == "" ? file(var.credentials_file) : var.credentials
}
>> VS Code test
3.3 테라폼 블록
terraform {
required_version = "~> 1.3.0" # 테라폼 버전
required_providers { # 프로바이더 버전을 나열
random = {
version = ">= 3.0.0, < 3.1.0"
}
aws = {
version = "4.2.0"
}
}
cloud { # Cloud/Enterprise 같은 원격 실행을 위한 정보
organization = "<MY_ORG_NAME>"
workspaces {
name = "my-first-workspace"
}
}
backend "local" { # state를 보관하는 위치를 지정
path = "relative/path/to/terraform.tfstate"
}
}
# version = Major.Minor.Patch
version = 1.3.4
테라폼 버전 required_version
cd ..
cd 03.start
# 현재 버전 정보 확인
terraform version
Terraform v1.5.1
# main.tf 파일 수정
terraform {
required_version = "< 1.0.0"
}
resource "local_file" "abc" {
content = "abc!"
filename = "${path.module}/abc.txt"
}
#init
# 실행 결과는?
terraform init
...
# 코드파일 수정
terraform {
required_version = ">= 1.0.0"
}
resource "local_file" "abc" {
content = "abc!"
filename = "${path.module}/abc.txt"
}
# 실행 결과는?
terraform init
...
프로바이더 버전
terraform {
required_version = ">= 1.0.0"
required_providers {
local = {
source = "hashicorp/local"
version = ">=10000.0.0"
}
}
}
resource "local_file" "abc" {
content = "123!"
filename = "${path.module}/abc.txt"
}
# 실행 결과는?
terraform init -upgrade
# local 프로바이더 버전을 >= 2.0.0으로 수정
terraform {
required_version = ">= 1.0.0"
required_providers {
local = {
source = "hashicorp/local"
version = ">= 2.0.0"
}
}
}
resource "local_file" "abc" {
content = "123!"
filename = "${path.module}/abc.txt"
}
# 실행 결과는?
terraform init -upgrade
3.4 리소스
# 03.end 디렉터리를 신규 생성 후 열기 → main.tf 파일 생성
cd ..
rm -rf 03.start
mkdir 03.end
cd 03.end
# 파일
resource "local_file" "abc" {
content = "123"
filename = "${path.module}/abc.txt"
}
resource "aws_instance" "web" {
ami = "ami-a1b2c3d4"
instance_type = "t2.micro"
}
# init
terraform init
tree .terraform
종속성 - VS Code 확장 graphviz 설치
resource "local_file" "abc" {
content = "123!"
filename = "${path.module}/abc.txt"
}
resource "local_file" "def" {
content = "456!"
filename = "${path.module}/def.txt"
}
# apply
terraform apply -auto-approve
# 리소스 확인
ls *.txt
terraform state list
# graph 확인 > graph-1.dot 파일 선택 후 오른쪽 상단 DOT 클릭
terraform graph
terraform graph > graph-1.dot
# 모든 리소스 제거
terraform destroy -auto-approve
ls *.txt
terraform state list
리소스 참조값을 설정해 두 개의 리소스 간 암시적 종속성 부여
# main.tf
resource "local_file" "abc" {
content = "123!"
filename = "${path.module}/abc.txt"
}
resource "local_file" "def" {
content = local_file.abc.content
filename = "${path.module}/def.txt"
}
# apply 커맨드 생성에 순서가 발생한 종속성 있는 두 개의 리소스
terraform apply -auto-approve
ls *.txt
terraform state list
cat abc.txt
cat def.txt
diff abc.txt def.txt
# graph 확인 > graph-2.dot 파일 선택 후 오른쪽 상단 DOT 클릭
terraform graph
terraform graph > graph-2.dot
리소스의 속성을 주입하지 않아도 두 리소스 간에 종속성이 필요한 경우에, depends_on 선언으로 적용 가능
resource "local_file" "abc" {
content = "123!"
filename = "${path.module}/abc.txt"
}
resource "local_file" "def" {
depends_on = [
local_file.abc
]
content = "456!"
filename = "${path.module}/def.txt"
}
#apply
terraform destroy -auto-approve
terraform apply -auto-approve
...
# graph 확인 > graph-3.dot 파일 선택 후 오른쪽 상단 DOT 클릭
terraform graph
terraform graph > graph-3.dot
'Terraform > Study_과제' 카테고리의 다른 글
7주차 - 워크플로 (0) | 2023.08.20 |
---|---|
6주차 - 협업 (0) | 2023.08.11 |
4주차 - State & 모듈 (0) | 2023.07.29 |
3주차 - Terraform 기본 사용 3/3 (0) | 2023.07.23 |
2주차 - Terraform 기본 사용 2/3 (0) | 2023.07.15 |