해당 내용은 cloudNet@ 팀의 가시다 님이 진행하는 테라폼 스터디 T101 4기에서 학습한 내용을 정리한 것입니다.
1. Provider-defined functions
- Function 종류 : Built-in Functions, Provider-defined Functions - Link
- Open
- 새로운 Terraform 플러그인 SDK는 OpenTofu에서 직접 사용할 수 있는 공급자 정의 함수에 대한 지원을 추가했다. 공급자 정의 함수는 상태 파일의 크기를 늘리지 않고 작성하는데 필요한 코드가 적기 때문에 데이터 소스를 사용하는 것보다 훨씬 효율적이다.
- 공급자가 사용자의 구성에 따라 사용자 정의 기능을 동적으로 정의할 수 있도록 OpenTofu 전용 기능을 추가했다. 이 업데이트를 통해 라이브 스트림에서 보여지는 것처럼 다른 프로그래밍 언어를 완전히 통합할 수 있다.
실습
- main.tf 파일 작성
문자열 Snake case 로 변환
terraform {
required_providers {
corefunc = {
source = "northwood-labs/corefunc"
version = "1.4.0"
}
}
}
provider "corefunc" {
}
# Snake case 로 변환
output "test" {
value = provider::corefunc::str_snake("Hello world!")
# Prints: hello_world
}
- 실행 후 확인
# 초기화
tofu init
# 프로바이더 정보 확인
tree .terraform
.terraform
└── providers
└── registry.opentofu.org
└── northwood-labs
└── corefunc
# Plan
tofu plan
...
Changes to Outputs:
+ test = "hello_world"
# Apply
tofu apply
...
Enter a value: yes
...
Outputs:
test = "hello_world"
# output
tofu output
# tfstate 파일 확인 : VSCODE에서 열어보기
cat terraform.tfstate | jq
- main.tf 변경 및 실행 확인
문자열 Camel case로 변환
terraform {
required_providers {
corefunc = {
source = "northwood-labs/corefunc"
version = "1.4.0"
}
}
}
provider "corefunc" {
}
output "test" {
value = provider::corefunc::str_camel("Hello world!")
# Prints: hello_world
}
# output
tofu output
# Apply
tofu apply -auto-approve
...
Outputs:
test = "helloWorld"
# tfstate 파일 확인 : VSCODE에서 열어보기
ls -l terraform.tfstate*
2. Loopable import blocks - Docs
- Import : Import 블록을 사용하여 기존 인프라 리소스를 OpenTofu로 가져와 OpenTofu의 관리 하에 둔다.
- Import 블록은 모든 OpenTofu 구성 파일에 추가할 수 있다. 일반적은 패턴은 imports.tf 파일을 만들거나 import 블록을 가져오는 리소스 블록 옆에 배치하는 것이다.
- Import 블록 인수
- to - The instance address this resource will have in your state file
- id - A string with the import ID of the resource
- provider(optional) - An optional custom resource provider
- for_each(optional) - Import several resources by iterating over a map or a set.
import {
to = aws_instance.example
id = "i-abcd1234"
}
resource "aws_instance" "example" {
name = "hashi"
# (other resource arguments...)
}
- Import multiple resources
- for_each 표현식을 사용하여 하나의 import 블록으로 여러 리소스를 가져올 수 있다.
- 이 표현식은 집합, 튜플 또는 맵을 허용하고 each.key 및 each.value 변수를 제공하여 개별 요소에 액세스한다.
실습
- main.tf 파일 작성
data "aws_ami" "ubuntu" {
most_recent = true
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"]
}
filter {
name = "virtualization-type"
values = ["hvm"]
}
owners = ["099720109477"] # Canonical
}
variable "instance_tags" {
type = list(string)
default = ["web", "app"]
}
resource "aws_instance" "this" {
count = length(var.instance_tags)
ami = data.aws_ami.ubuntu.id
instance_type = "t3.micro"
tags = {
Name = var.instance_tags[count.index]
}
}
- 실행 후 확인
# 초기화
tofu init
# 프로바이더 정보 확인
tree .terraform
.terraform
└── providers
└── registry.opentofu.org
└── hashicorp
└── aws
└── 5.60.0
# Apply
tofu apply -auto-approve
# EC2 확인
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
web 3.35.50.179 running
app 43.200.245.83 running
# 확인
tofu state list
tofu state ls
echo "data.aws_ami.ubuntu" | tofu console
tofu show
# tfstate 파일 확인 : VSCODE에서 열어보기
cat terraform.tfstate | jq
...
"provider": "provider[\"registry.opentofu.org/hashicorp/aws\"]",
...
"arn": "arn:aws:ec2:ap-northeast-2::image/ami-01e69ea1a3e0010f9",
...
- 문제 상황 재연 : tfstate 파일 삭제
# 문제 상황 재연 : tfstate 파일 삭제
rm -rf .terraform* terraform.tfstate*
tree
# EC2 확인 : ID 메모
aws ec2 describe-instances --query 'Reservations[*].Instances[*].{InstanceID:InstanceId,PublicIP:PublicIpAddress,Name:Tags[?Key==`Name`]|[0].Value}' --output json | jq -r '.[][] | "\(.InstanceID)\t\(.PublicIP)\t\(.Name)"'
i-0e2d4475790337a81 13.125.183.90 web
i-00a4daebb71942280 3.38.152.103 app
- main.tf 파일 수정 및 실행 확인
아래 ami-id를 바로 위 EC2 확인에서 출력된 ID로 수정해서 입력
data "aws_ami" "ubuntu" {
most_recent = true
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"]
}
filter {
name = "virtualization-type"
values = ["hvm"]
}
owners = ["099720109477"] # Canonical
}
variable "instance_ids" {
type = list(string)
default = ["i-0e2d4475790337a81", "i-00a4daebb71942280"]
}
variable "instance_tags" {
type = list(string)
default = ["web", "app"]
}
resource "aws_instance" "this" {
count = length(var.instance_tags)
ami = data.aws_ami.ubuntu.id
instance_type = "t3.micro"
tags = {
Name = var.instance_tags[count.index]
}
}
import {
for_each = { for idx, item in var.instance_ids : idx => item }
to = aws_instance.this[tonumber(each.key)]
id = each.value
}
# 초기화
tofu init -json
tree .terraform
#
tofu apply -auto-approve
Plan: 2 to import, 0 to add, 0 to change, 0 to destroy.
aws_instance.this[1]: Importing... [id=i-00a4daebb71942280]
aws_instance.this[1]: Import complete [id=i-00a4daebb71942280]
aws_instance.this[0]: Importing... [id=i-0e2d4475790337a81]
aws_instance.this[0]: Import complete [id=i-0e2d4475790337a81]
# 확인
tofu state ls
tofu show
# tfstate 파일 확인 : VSCODE에서 열어보기
cat terraform.tfstate | jq
3. State file encryption - Local
- State and plan Encryption
- OpenTofu는 로컬 스토리지와 백엔드를 사용할 때 모두 휴면상태 및 계획 파일을 암호화 할 수 있다. 또한 terraform_remote_state 데이터 소스와 함께 암호화를 사용할 수도 있다.
실습
- 위에서 실습한 파일을 복사해서 사용
mkdir 8.3 && cd 8.3
cp ../8.2/main.tf .
touch backend.tf
- backend.tf 파일 작성
terraform {
encryption {
key_provider "pbkdf2" "my_passphrase" {
## Enter a passphrase here:
passphrase = "ChangeIt_123abcd"
}
method "aes_gcm" "my_method" {
keys = key_provider.pbkdf2.my_passphrase
}
## Remove this after the migration:
method "unencrypted" "migration" {
}
state {
method = method.aes_gcm.my_method
## Remove the fallback block after migration:
fallback{
method = method.unencrypted.migration
}
## Enable this after migration:
#enforced = true
}
}
}
- 실행 후 tfstate 파일 암호화 확인
#
tofu init -json | jq
tree .terraform
# import 실행
tofu apply -auto-approve
tofu state list
tofu show
# tfstate 파일 확인 : VSCODE에서 열어보기
cat terraform.tfstate | jq
- 좀 더 강력한 보안 정책 적용 : 암호화 되지 않은 환경 변수가 저장되는 것을 차단
- enforced = true
terraform {
encryption {
key_provider "pbkdf2" "my_passphrase" {
## Enter a passphrase here:
passphrase = "ChangeIt_123abcd"
}
method "aes_gcm" "my_method" {
keys = key_provider.pbkdf2.my_passphrase
}
## Remove this after the migration:
method "unencrypted" "migration" {
}
state {
method = method.aes_gcm.my_method
## Remove the fallback block after migration:
fallback{
method = method.unencrypted.migration
}
# Enable this after migration:
enforced = true
}
}
}
- Rolling back encryption : 암호화 -> 평문으로 마이그레이션
terraform {
encryption {
key_provider "pbkdf2" "my_passphrase" {
## Enter a passphrase here:
passphrase = "ChangeIt_123abcd"
}
method "aes_gcm" "my_method" {
keys = key_provider.pbkdf2.my_passphrase
}
## Remove this after the migration:
method "unencrypted" "migration" {
}
state {
method = method.unencrypted.migration
## Remove the fallback block after migration:
fallback{
method = method.aes_gcm.my_method
}
# Enable this after migration:
enforced = false
}
}
}
'DevOps' 카테고리의 다른 글
[T1014-실습] OpenTofu 1.7.0 (2) (0) | 2024.08.04 |
---|---|
[T1014-이론] OpenTofu 소개 (0) | 2024.07.31 |
[T1014-실습] Terraform 으로 AWS EKS 배포하기 (0) | 2024.07.24 |
[T1014-이론] EKS? Kubernetes? Karpenter? Helm? ArgoCD? (1) | 2024.07.24 |
[T1014-실습] Terraform Runner (1) | 2024.07.14 |