1
개요 ?
테라폼의 State에 기록되는 리소스 주소의 이름이 변경되면, 기존 리소스는 삭제되고 새로운 리소스가 생성된다.
테라폼 리소스를 선언하다 보면, 이름만 변경하면 좋은 경우가 있다.
예를 들어,
리소스 이름의 변경
count 처리 반복문을 fo each로 처리
리소스가 모듈로 이동되며 참조되는 주소가 변경되는경우.
moved 사용하자!!
테라폼에서 구분하는 리소스 이름이 a 일 경우 b로만 바꿀 경우 사용한다.
실제 내용은 동일 한 경우 이다.
참고자료
https://developer.hashicorp.com/terraform/language/modules/develop/refactoring#moved-block-syntax
moved 를 사용한 리펙토링 실습
https://developer.hashicorp.com/terraform/tutorials/configuration-language/move-config
2
cd
mkdir 314
cd 314
3
vi main.tf
resource "local_file" "a" {
content = "foo!"
filename = "${path.module}/foo.bar"
}
output "file_content" {
value = local_file.a.content
}
//
local 프로바이더의 file 이라는거로 이름을 a
컨텐츠를 foo!
파일이름은 foo.bar
아웃풋은 컨텐츠 내용을 출력하는것.
output "file_content" {
4
terraform init && terraform plan && terraform apply -auto-approve
cat foo.bar ; echo
foo!
#
terraform state list
local_file.a
echo "local_file.a" | terraform console
-------------------------------------------------------------
5
a를 b로 변경 해보자~
vi main.tf
resource "local_file" "b" {
content = "foo!"
filename = "${path.module}/foo.bar"
}
output "file_content" {
value = local_file.b.content
}
6
terraform plan
...
Plan: 1 to add, 0 to change, 1 to destroy.
a를 삭제하고 b를 새로 만들려고 한다~~
-------------------------------------------------------------
7
moved 사용 해서 a를 b로 바꾸자.
rm -rf main.tf
vi main.tf
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
}
//
ls
terraform.tfstate 파일을 가지고 있다.
// 이미 terraform.tfstate 파일에 a정보를 가지고 있어, 해당 내용을 참조 한다.
cat terraform.tfstate | jq
8
terraform plan
Terraform will perform the following actions:
# local_file.a has moved to local_file.b
resource "local_file" "b" {
id = "4bf3e335199107182c6f7638efaad377acc7f452"
# (10 unchanged attributes hidden)
}
Plan: 0 to add, 0 to change, 0 to destroy.
//삭제하는게 없다.
9
terraform apply -auto-approve
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
terraform state list
local_file.b
echo "local_file.b" | terraform console
10
정상 변경되었으니 작업 내용은 주석처리 하자.
vi main.tf
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
}
https://developer.hashicorp.com/terraform/cli/config/environment-variables
1
Mac/리눅스/유닉스: export <환경 변수 이름>=<값>
Windows CMD: set <환경 변수 이름>=<값>
Windows PowerShell: $Env:<환경 변수 이름>='<값>'
2
trace, debug, info, warn, error, off를 설정할 수 있고 관련 환경 변수가 없는 경우 off와 동일하다.
테라폼 실행시 로깅 레벨 조정을 확인하자 ?
TF_LOG=info terraform plan
3
TF_VAR_name <변수 이름>을 사용하면 , 디폴트로 선언된 변수 값을 대체 한다. // 우선 순위 ^^
export TF_VAR_region=us-west-1
export TF_VAR_ami=ami-049d8641
export TF_VAR_alist='[1,2,3]'
export TF_VAR_amap='{ foo = "bar", baz = "qux" }'
필요시 활용하자~
1
테라폼 동작 원리
이미지 출처 https://malwareanalysis.tistory.com/619
2
프로바이더 종류
https://registry.terraform.io/browse/providers
aws 프로바이더
https://registry.terraform.io/providers/hashicorp/aws/latest
ncloud 프로바이더
https://registry.terraform.io/providers/NaverCloudPlatform/ncloud/latest
3
AWS 등 프로바이더 생략을 해도, 리소스 이름으로 확인하여 프로바이더 설정은 자동 처리된다.
provider "aws" {
region = "ap-southeast-1"
}
resource "aws_instance" "app_server1" {
ami = "ami-06b79cf2aee0d5c92"
instance_type = "t2.micro"
}
3
서울리전, 싱가포르 모두 EC2를 배포 하고 싶다. ?
아래 예제는 서울리전, 싱가포르 리전 모두 디폴트 VPC에 배포하는 예제이다.
디폴트 VPC 환경에서 작업이 필요하다.
│ Error: creating EC2 Instance: VPCIdNotSpecified: No default VPC for this user. GroupName is only supported for EC2-Classic and default VPC.
│ status code: 400, request id: 353fbc73-4aa6-4bb6-9cd5-bef927fa8002
cd
mkdir 41
cd 41
4
하나는 싱가포르 리전 배포
하나는 서울 리전에 배포
vi main.tf
provider "aws" {
region = "ap-southeast-1"
}
provider "aws" {
alias = "seoul"
region = "ap-northeast-2"
}
resource "aws_instance" "app_server1" {
ami = "ami-06b79cf2aee0d5c92"
instance_type = "t2.micro"
}
resource "aws_instance" "app_server2" {
provider = aws.seoul
ami = "ami-0ea4d4b8dc1e46212"
instance_type = "t2.micro"
}
설명?
// 싱가포르에 서버 생성
provider "aws" {
region = "ap-southeast-1"
}
resource "aws_instance" "app_server1" {
ami = "ami-06b79cf2aee0d5c92"
instance_type = "t2.micro"
}
// 서울리전에 서버 생성 , aws.seoul
provider "aws" {
alias = "seoul"
region = "ap-northeast-2"
}
resource "aws_instance" "app_server2" {
provider = aws.seoul
ami = "ami-0ea4d4b8dc1e46212"
instance_type = "t2.micro"
}
// 멀티리전에 리소스를 배포 하는것이다.
// ec2 를 싱가포르와 서울에 배포 할 경우이다.
#
terraform init && terraform plan
Plan: 2 to add, 0 to change, 0 to destroy.
terraform apply -auto-approve
Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
#
terraform state list
aws_instance.app_server1
aws_instance.app_server2
echo "aws_instance.app_server1.public_ip" | terraform console
echo "aws_instance.app_server2.public_ip" | terraform console
aws ec2 describe-instances --filters Name=instance-state-name,Values=running --output table
aws ec2 describe-instances --filters Name=instance-state-name,Values=running --output table --region ap-southeast-1
5
AWS 콘솔에서 확인 해보자.
6
# 삭제
terraform destroy -auto-approve
1
cd
mkdir 43
cd 43
2
파일 생성 : 리전 별 AMI ID값이 다르므로, 필터를 활용하자
// 우분트로 데이터 소스 사용 , 리전을 명확히 지정해주자.
vi provider_data.tf
provider "aws" {
region = "ap-northeast-2"
alias = "region_1"
}
provider "aws" {
region = "ap-southeast-1"
alias = "region_2"
}
data "aws_region" "region_1" {
provider = aws.region_1
}
data "aws_region" "region_2" {
provider = aws.region_2
}
data "aws_ami" "ubuntu_region_1" {
provider = aws.region_1
most_recent = true
owners = ["099720109477"] # Canonical
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
}
}
data "aws_ami" "ubuntu_region_2" {
provider = aws.region_2
most_recent = true
owners = ["099720109477"] # Canonical
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
}
}
3
vi ec2.tf
: 리전, ami 참조
resource "aws_instance" "region_1" {
provider = aws.region_1
ami = data.aws_ami.ubuntu_region_1.id
instance_type = "t2.micro"
}
resource "aws_instance" "region_2" {
provider = aws.region_2
ami = data.aws_ami.ubuntu_region_2.id
instance_type = "t2.micro"
}
4
# [터미널1] ap-northeast-2 = 서울
while true; do aws ec2 describe-instances --region ap-northeast-2 --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
# [터미널2] ap-southeast-1 = 싱가포르
while true; do aws ec2 describe-instances --region ap-southeast-1 --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
# init & plan & apply
terraform init && terraform plan && terraform apply -auto-approve
terraform state list
# 확인
aws ec2 describe-instances --region ap-northeast-2 --query "Reservations[*].Instances[*].{PublicIPAdd:PublicIpAddress,InstanceName:Tags[?Key=='Name']|[0].Value,Status:State.Name}" --filters Name=instance-state-name,Values=running --output text
aws ec2 describe-instances --region ap-southeast-1 --query "Reservations[*].Instances[*].{PublicIPAdd:PublicIpAddress,InstanceName:Tags[?Key=='Name']|[0].Value,Status:State.Name}" --filters Name=instance-state-name,Values=running --output text
콘솔에서 확인
서울리전
싱가포르 리전
5
만들어진 ec2 삭제
terraform destroy -auto-approve
6
명령서버 삭제
클라우드 포메이션에서 스택 제거
https://brunch.co.kr/@topasvga/3382
전체 보기
https://brunch.co.kr/@topasvga/3347
https://gasidaseo.notion.site/gasidaseo/CloudNet-Blog-c9dfa44a27ff431dafdd2edacc8a1863
감사합니다.