테라폼으로 시작하는 IaC 책을 기준으로 정리하였습니다.
테라폼에서의 조건식은 3항 연산자 형태를 갖는다. 조건은 true
또는 false
로 확인되는 모든 표현식을 사용할 수 있다
예시
# <조건 정의> ? <옳은 경우> : <틀린 경우>
# 조건식 형태 권장 사항
var.example ? 12 : "hello" # 비권장
var.example ? "12" : "hello" # 권장
var.example ? tostring(12) : "hello" # 권장
[도전과제1] 조건문을 활용하여 (각자 편리한) AWS 리소스를 배포하는 코드를 작성해보자!
main.tf
variable "enable_file" {
default = true
}
resource "local_file" "foo" {
count = var.enable_file ? 1 : 0
content = "foo!"
filename = "${path.module}/foo.bar"
}
# Create a VPC for the region associated with the AZ
resource "aws_vpc" "myvpc" {
count = var.enable_file ? 1 : 0
cidr_block = "10.10.0.0/16"
enable_dns_support = true
enable_dns_hostnames = true
tags = {
Name = "repush"
}
}
테라폼은 프로그래밍 언어
적인 특성을 가지고 있어서, 값의 유형을 변경하거나 조합할 수 있는 내장 함수
를 사용 할 수 있다
사용자 정의 함수를 지원하지는 않는다
.[도전과제2] 내장 함수을 활용하여 (각자 편리한) 리소스를 배포하는 코드를 작성해보자!
count + 함수 cidrhost 로 EC2의 ENI 에 10개의 ip를 장착
main.tf
provider "aws" {
region = "ap-northeast-2"
}
resource "aws_vpc" "my_vpc" {
cidr_block = "172.16.0.0/16"
}
data "aws_availability_zones" "available" {
state = "available"
}
locals {
host_ip_count = 10
}
resource "aws_subnet" "my_subnet" {
vpc_id = aws_vpc.my_vpc.id
cidr_block = "172.16.10.0/24"
availability_zone = data.aws_availability_zones.available.names[0]
}
resource "aws_network_interface" "foo" {
count = local.host_ip_count
subnet_id = aws_subnet.my_subnet.id
private_ips = [cidrhost(aws_subnet.my_subnet.cidr_block, count.index + 100)]
}
resource "aws_instance" "foo" {
count = local.host_ip_count
ami = "ami-0162b88b98a9265c6"
instance_type = "t2.micro"
network_interface {
network_interface_id = aws_network_interface.foo[count.index].id
device_index = 0
}
}
output "network_private_ips" {
value = aws_network_interface.foo.*.private_ips
}
output
Outputs:
network_private_ips = [
toset([
"172.16.10.100",
]),
toset([
"172.16.10.101",
]),
toset([
"172.16.10.102",
]),
toset([
"172.16.10.103",
]),
toset([
"172.16.10.104",
]),
toset([
"172.16.10.105",
]),
toset([
"172.16.10.106",
]),
toset([
"172.16.10.107",
]),
toset([
"172.16.10.108",
]),
toset([
"172.16.10.109",
]),
]
프로비저너는 프로바이더와 비슷하게 제공자
로 해석되나, 프로바이더로 실행되지 않는 커맨드
와 파일 복사
같은 역할을 수행
[도전과제3] AWS EC2 배포 시 remote-exec/file 프로비저너 혹은 terraform-provider-ansible를 활용하는 코드를 작성해보자!
main.tf
provider "aws" {
region = "ap-northeast-2"
}
resource "aws_vpc" "my_vpc" {
cidr_block = "172.16.0.0/16"
}
data "aws_availability_zones" "available" {
state = "available"
}
locals {
host_ip_count = 10
}
resource "aws_subnet" "my_subnet" {
vpc_id = aws_vpc.my_vpc.id
cidr_block = "172.16.10.0/24"
availability_zone = data.aws_availability_zones.available.names[0]
}
resource "aws_network_interface" "foo" {
count = local.host_ip_count
subnet_id = aws_subnet.my_subnet.id
private_ips = [cidrhost(aws_subnet.my_subnet.cidr_block, count.index + 100)]
}
resource "aws_instance" "foo" {
count = local.host_ip_count
ami = "ami-0162b88b98a9265c6"
instance_type = "t2.micro"
network_interface {
network_interface_id = aws_network_interface.foo[count.index].id
device_index = 0
}
}
output "network_private_ips" {
value = aws_network_interface.foo.*.private_ips
}
아무 작업도 수행하지 않는 리소스를 구현
[도전과제5] moved 블록을 사용한 테라폼 코드 리팩터링을 수행해보세요
동작 순서
1. 인프라 프로비저닝
2. moved 블록을 활용해 원하는 변경사항 동작
3. moved 블록을 해제하고 바뀐 변경사항만 상태파일과 동기화
resource "local_file" "b" {
content = "foo!"
filename = "${path.module}/foo.bar"
}
# moved {
# from = local_file.a
# to = local_file.b
# }
output "file_content" {
value = local_file.b.content
}
테라폼은 환경 변수
를 통해 실행 방식
과 출력 내용에 대한 옵션을
조절할 수 있다.
Mac/리눅스/유닉스: export <환경 변수 이름>=<값>
Windows CMD: set <환경 변수 이름>=<값>
Windows PowerShell: $Env:<환경 변수 이름>='<값>'
TF_LOG
: 테라폼의 stderr 로그에 대한 레벨을 정의
TF_INPUT
: 값을 false 또는 0으로 설정하면 테라폼 실행 시 인수에 -input=false 를 추가한 것과 동일한 수행 결과를 확인
TF_CLI_ARGS / TF_CLI_ARGS_subcommand
: 테라폼 실행 시 추가할 인수를 정의
TF_DATA_DIR
: State 저장 백엔드 설정과 같은 작업 디렉터리별 데이터를 보관하는 위치를 지정
[도전과제8] kubernetes, helm 프로바이더를 사용해서 리소스를 배포하고 확인해보세요! (wordpress, nginx, tomcat 등) -
main.tf
terraform {
required_providers {
helm = {
source = "hashicorp/helm"
version = "2.11.0"
}
}
}
provider "helm" {
kubernetes {
config_path = "~/.kube/config"
}
}
helm.tf
resource "helm_release" "nginx" {
name = "nginx"
repository = "https://charts.bitnami.com/bitnami"
chart = "nginx"
values = [
file("${path.module}/nginx-values.yaml")
]
}
nginx-values.yaml
replicaCount: 3
service:
type: LoadBalancer