brunch

You can make anything
by writing

C.S.Lewis

by Master Seo Jul 17. 2023

32탄-8. 3주차-테라폼-moved, 프로바이더



<1> moved 블록 = 리소스의 이름만 변경 할때

<2> CLI를 위한 시스템 환경 변수 지정하기

<3> 프로 바이더

<4> 2개 리전에 배포 하기




<1> moved 블록 = 리소스의 이름만 변경 할때


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

}





<2> CLI를 위한 시스템 환경 변수 지정하기


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" }'


필요시 활용하자~




<3> 프로 바이더


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





<4> 2개 리전에 배포 하기


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




다음은 주말 CloudNet 테라폼 스터디 내용 참고하여  정리한 부분입니다.

https://gasidaseo.notion.site/gasidaseo/CloudNet-Blog-c9dfa44a27ff431dafdd2edacc8a1863  



감사합니다.





브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari