Resource block
- resource block은 resource "type" "name" 구문으로 이뤄진다.
- type은 provider의 지정에 따라 달라진다. aws로 하면 aws_instance, aws_vpc 등의 type을 입력할 수 있다.
- name은 해당하는 resource type과 매칭되는 유니크한 명칭을 입력하면 된다.
똑같은 name이라고 하더라도 type이 다르면 ok, 똑같은 name 똑같은 type은 no no hot hot.
#구문
resource "type" "name" { }
#예시
}
|
- 레지스트리에서 argument reference 부분을 보면, 필수요소(required)와 선택적요소(optional)가 있다.
물론, vpc는 그런거 없다. optional만 있다.
(https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc)
- 예시를 위해 aws_iam_policy resource의 argument reference를 알아본다.
required라고 명시된 policy는 꼭 포함되어야 하는 인수이다.
- Arguments는 Resource를 구성하는 값들이다. 이를 input으로 친다면, Attribute는 output에 해당한다.
vpc의 Attribute는 아래와 같다.
- 왜 output이라고 하는지 살펴보자.
Attribute Reference 중 id는 vpc의 id값을 나타낸다.
vpc_id값이 aws_subnet의 required인데, aws_vpc의 attribute인 id를 참조하여 값을 넣어줬다.
output 맞제?
provider "aws" {
region = "ap-northeast-1"
}
resource "aws_vpc" "kgw_tf_vpc" {
cidr_block = "10.0.0.0/16"
}
resource "aws_subnet" "kgw_tf_subnet" {
cidr_block = "10.0.1.0/24"
vpc_id = aws_vpc.kgw_tf_vpc.id
}
|
- 구문은 아래와 같다.
<Resource Type>.<Name>.<Attribute>
Resource Type : aws_vpc
Name : kgw_tf_vpc Attribute : id |
- 지금까지 알아본 Resource Block의 Arguments(인수)들은 Resource를 생성하는데 필요한 요소이다.
그렇다면 Resource 공통적인 Arguments들도 있지 않을까?
ㅇㅇ 있음.
그거시 바로 Meta-Arguments라는 것이다.
1) depends_on
- terraform은 종속성을 가지고 프로비저닝을 수행한다. 기본적으론 테라폼이 알아서 하고, 소스 순서를 바꿔도 동일하다.
하지만 resource들의 실행 순서를 정하고 싶을때, depends_on을 통해서 정해줄 수 있다.
명시적 종속성이라고 대충 네이밍을 해보자.
- 아래 코드를 실행하면 어떤 순서로 생성될까?
resource "aws_s3_bucket" "kgw_tf_s3" {
bucket = "kgw_bucket"
acl = "private"
}
resource "aws_instance" "kgw_tf_ec2" {
ami = "ami-0e9bfdb247cc8de84"
instance_type = "t2.micro"
}
|
- 종속성 그래프는 아래와 같다.
- 아래 코드를 실행하면 어떤 순서로 생성될까?
resource "aws_s3_bucket" "kgw_tf_s3" {
bucket = "kgw_bucket"
acl = "private"
}
resource "aws_instance" "kgw_tf_ec2" {
ami = "ami-0e9bfdb247cc8de84"
instance_type = "t2.micro"
depends_on = [
aws_s3_bucket.kgw_tf_s3
]
}
|
- 종속 그래프가 달라졌다. 종속성에 따라 순서가 정해진다.
- 이 depends_on meta_argumets는 terraform이 종속성을 파악하기 어려운 상황에서 사용하면 된다. 당연히 특수한 경우이므로 comment 작성은 필수다. 마지막으로 굳이 depends_on을 쓰지 않고도 종속성을 명시적으로 수정할 수 있는 방안을 소개하고자 한다.
- 이처럼 s3의 bucket 이름을 ec2의 tags값을 참조하는 코드를 작성하면 자연스레 종속성을 지정할 수 있다.
resource "aws_s3_bucket" "kgw_tf_s3" {
bucket = aws_instance.kgw_tf_ec2.tags.name
acl = "private"
}
resource "aws_instance" "kgw_tf_ec2" {
ami = "ami-0e9bfdb247cc8de84"
instance_type = "t2.micro"
tags = {
name = "testkimtest"
}
}
|
2) count
- 일반적으로 resource는 한번만 생성되지만, count meta-arguments를 사용하면 두려움은 없다.
- resource 안에 count를 숫자를 명시해주면, 그만큼 반복 생성된다.
- 아래는 s3를 3개 생성하는 코드이다.
resource "aws_s3_bucket" "kgw_tf_s3" {
count = 3
bucket = "testkim-${count.index+1}"
acl = "private"
}
|
- 결과 확인
- count를 써서 생성한 리소스들은 당연한 얘기지만, 소스 코드에서 name이 같기 때문에 인덱스 값을 붙여줘야한다.
aws_s3_bucket.kgw_tf_s3[index].bucket |
3) for_each
- count와 동일하게 다양한 리소스를 여러 개 생성할 수 있게 해준다.
- 다른점이라곤 map 이나 set을 값으로 가질 수 있다.
- set : 유일한 값을 요소로 갖는 list. ex) [1, 2, 3]
each.key = member 값 each.value = member 값 - map : key = value 형식의 list each.key = key 값 each.value = value 값 |
# toset 사용
resource "aws_iam_user" "new-account" {
for_each = toset( ["kgw", "testkim", "kimtest", "testkimtest"] )
name = each.key
tags = {
"dev" = each.value
}
}
# map 사용
resource "aws_iam_user" "new-account-new" {
for_each = {
"kimkim" = "kimkim"
"testtest" = "testtest"
}
name = each.key
tags = {
"dev" = each.value
}
}
|
- 결과 확인
- for-each를 써서 생성한 리소스들은 당연한 얘기지만, 소스 코드에서 name이 같기 때문에 key 값을 붙여줘야한다.
aws_iam_user.new-account[key].name |
4) provider
- provider를 여러개 지정할 수 있다.
- 우선 default provider를 지정해주고, 추가로 설정하는 provider는 alias를 선언하여 alternate로 생성했다.
- resource 구문안에서 provider를 지정해서 alternate provider를 사용할 수 있다.
# default provider
provider "aws" {
region = "ap-northeast-2"
}
# alternate provider
provider "aws" {
alias = "tokyo"
region = "ap-northeast-1"
}
# Ec2 instance - Seoul
resource "aws_instance" "kgw_tf_ec2-seoul" {
ami = "ami-0e9bfdb247cc8de84"
instance_type = "t2.micro"
}
# Ec2 instance - Tokyo
resource "aws_instance" "kgw_tf_ec2-tokyo" {
provider = aws.tokyo
ami = "ami-03f4fa076d2981b45"
instance_type = "t2.micro"
}
|
- 결과확인
Seoul
Tokyo
5) lifecycle
- 말그대로 리소스의 생애주기를 설정하는 인자다. 3개 있다.
- create_before_destory : terraform 기본 동작이 update가 불가할 경우 리소스를 삭제하고 다시 생성한다. 이 과정에서 해당인자를 사용하면, 먼저 리소스 생성 후에 기존 리소스를 삭제한다.
# create_before_destroy
resource "aws_instance" "kgw_tf_ec2_1" {
ami = "ami-0e9bfdb247cc8de84"
instance_type = "t2.micro"
lifecycle {
create_before_destroy = true
}
}
|
- 결과확인 : ami ubuntu에서 amazon-linux로 수정 후 terraform apply.
instance 신규 생성 후 기존 instance 삭제 하는 것 확인
- prevent_destroy : destroy를 못하게 한다. error발생한다.
# create_before_destroy
resource "aws_instance" "kgw_tf_ec2_1" {
ami = "ami-0e9bfdb247cc8de84"
instance_type = "t2.micro"
lifecycle {
create_before_destroy = true
}
}
|
- 결과 확인 : 삭제가 안된다.ㄷㄷ
- ignore_changes : terraform과 console 등 다양한 방법으로 관리하고 있을 경우, console에서 수정한 값들은 terraform에 반영되지 않았을 것이다. 이에 terraform은 코드 내용 대로 다시 원복한다.
그래서 ignore_changes로 인해 변경을 무시하여 원복 되지 않게끔 하는 것.
다른 인자들과 다르게 list 타입이며, list에 적은 arguments는 terraform에서 무시하여 update를 진행하지 않는다.
# ignore_changes
resource "aws_instance" "kgw_tf_ec2_3" {
ami = "ami-0e9bfdb247cc8de84"
instance_type = "t2.micro"
lifecycle {
ignore_changes = [tags]
}
}
|
- tags value를 변경
- 결과확인 : terraform apply 이후에 ingnore_changes = [tags]로 인해 해당 instance만 설정이 유지되는 것을 확인했다.
'네트워크 & 클라우드 > 자동화' 카테고리의 다른 글
Terraform 기초 6 - Variables (0) | 2022.12.01 |
---|---|
Terraform 기초 5 - Data Block (0) | 2022.12.01 |
Terraform 기초 3 - Backend (1) | 2022.12.01 |
Terraform 기초 2 - Terraform/Provider Block (0) | 2022.11.27 |
Terraform 기초 1 - 설치 및 기본 명령어 (0) | 2022.11.23 |