Terraform 반복문과 조건문, 그리고 예제

Louis·2022년 12월 8일
0

Terraform

목록 보기
5/6
post-thumbnail

Terramform 반복문

테라폼 코드를 사용하다보면 반복되는 리소스 생성 및 리소스에 대한 관리가 필요할 때가 있다.
적은 양의 코드면 쉽게 작성이 가능 하겠지만, 몇십명 몇십개의 리소스를 관리하게 되면 각각의 리소스 생성 코드를 만드는 것은 쉽지 않은 일이다.
이를 효율적으로 사용하기 위해서 테라폼에선 반복문을 지원한다.
다음 내용을 통해서 반복문을 익히고 효율적인 테라폼 운영을 할 수 있었으면 좋겠다.

IAM User 생성

IAM 유저를 생성하려 한다. 3명의 유저를 생성 한다면 다음과 같은 코드로 생성이 가능하다

provider "aws" {
	region = "ap-northeast-2"
}

resource "aws_iam_user" "user_1" {
	name = "user-1"
}

resource "aws_iam_user" "user_2" {
	name = "user-2"
}

resource "aws_iam_user" "user_1" {
	name = "user-2"
}

output "user_arns" {
  value = [
    aws_iam_user.user_1.arn,
    aws_iam_user.user_2.arn,
    aws_iam_user.user_3.arn,
  ]
}

적은 사용자를 관리 할 경우에 위와 같은 코드로 관리가 가능하지만 다수의 사용자를 관리하기는 쉽지 않다.
이를 위해서 반복문을 통해서 많은 사용자 관리를 쉽게 할 수 있다.

count 표현식 사용

meta-arguments는 resource Block Body의 최상단 {count.index}를 사용하여 인덱스 정보를 가져 올 수 있다.
resource, module, data에서 사용 가능하다.

resource "aws_iam_user" "count" {
  count = 3 #meta argument

  name = "count-user-${count.index}"
}

output "count_user_arns" {
  value = aws_iam_user.count.*.arn
}

코드로서 3명을 생성했던 것과 다르게 count를 활용하여서 쉽게 생성 및 결과를 확인 할 수 있다.

for~each 표현식 사용

for_each 표현식을 사용하면 리스트, 집합, 맵을 사용하여 전체 리소스의 여러 복사본 또는 리소스 내 인라인 블록의 여러 복사본을 생성 할 수 있다.

기본 구문은 다음과 같다

resource "<PROVIDER>_<TYPE>" "<NAME>" {
	for_each = <COLLECTION>
    
    [CONFIG ...]
}

set 을 시용한 생성

resource "aws_iam_user" "for_each_set" {
  for_each = toset(
    "for-each-set-user-1"
    "for-each-set-user-2"
    "for-each-set-user-3"
  )

  name = each.key
}

output "for_each_set_user_arns" {
  value = values(aws_iam_user.for_each_set).*.arn
}

set은 List 형식으로 받기 때문에 형변환이 필요하여 toset을 사용한다.
값을 처리 하기 위해서 each, key, each.value가 생성되어서 데이터에 접근 할 수 있다.

map을 이용한 생성

resource "aws_iam_user" "for_each_map" {
  for_each = {
    cab = {
      level = "low"
      manager = "man1"
    }
    bob = {
      level = "mid"
      manager = "man2"
    }
    louis = {
      level = "high"
      manager = "man2"
    }
  }

  name = each.key
	
  tags = each.value
}

정상적으로 생성 되면 Tag Key, Tag Value 값이 생성되어서 활용 가능 하다.

for표현식 사용

리스트를 갖는 코드에서 특정 업무를 수행하기 위해서 테라폼은 for 표현식을 제공한다
count와 for-each는 data, resource, module 에서만 사용 가능한 표현식이였다면
for 표현식은 테라폼에서 expression을 사용 가능 한 모든 곳에서 사용 가능한 문법이다.

기본 구문은 다음과 같다

[for <ITEM> in <LIST> : <OUTPUT>]

[for k, v in var.map : length(k) + length(v)]
  • list : 반복할 리스트
  • item : list의 각 항목에 할당 할 변수의 이름
  • output : item을 어떤 식으로든 변환하는 표현식
  • map 데이터 타입을 활용 key, value 값을 활용해서 사용할 수 있다.
variable "names" {
  description = "A list of names"
  type        = list(string)
  default     = ["gasida", "akbun", "fullmoon"]
}

output "upper_names" {
  value = [for name in var.names : upper(name)]
}

Terraform 조건문

다른 프로그래밍에서 제공하는 3항 연산자 사용 문법에 대해서 테라폼에서도 동일 문법으로 제공해 준다.
3항 연산자를 활용해서 원하는 조건이 true일때와 false를 구분해서 리소스 배포 및 프로세스에 대해서 정의 할 수 있다.

  • 테라폼의 기본 조건식은 다음과 같다
condition ? true_val : false_val
  • condition이 참이면 true_val을 거짓이면 fals_val을 할당하는게 가능하다.
resource "aws_iam_user_policy_attachment" "gurumee_cloudwatch_full_access" {
  count      = var.give_gurumee_cloudwatch_full_access ? 1 : 0
  user       = aws_iam_user.example.0.name
  policy_arn = aws_iam_policy.cloudwatch_full_access.arn
}

resource "aws_iam_user_policy_attachment" "gurumee_cloudwatch_read_only" {
  count      = var.give_gurumee_cloudwatch_full_access ? 0 : 1
  user       = aws_iam_user.example.0.name
  policy_arn = aws_iam_policy.cloudwatch_read_only.arn
}

give_gurumee_cloudwatch_full_access 변수 값에 따라서 액세스 권한을 부여하는 코드이다.

if 문자열 지시자

3한 연산자 표현식과 함께 if 표현식도 제공해 준다.
프로그래밍이 익숙한 사용자라면 if 조건문이 익숙할 텐데 우리가 알고 있는 조건에 해당 할 경우 정해진 코드가 실행이 되고
그 조건에 해당하지 않을 경우 종료가 실행하지 않고 지나가거나 다른 프로세스가 실행 되게 표현 할 수 있다.

  • 기분 구분은 다음과 같다
%{ if <CONDITION> }<TRUEVAL>%{ endif }
  • CONDITION은 boolean 으로 평가되는 표현식이고, TRUEVAL은 CONDITION이 True로 평가되면 렌더링 할 표현식이다.
  • else절을 선택적으로 포함할 수도 있다.
%{ if <CONDITION> }<TRUEVAL>%{ else }<FALSEVAL>%{ endif }
  • FALSEVAL은 CONDITION이 false로 평가되면 렌더링할 표현식입니다.
variable "names" {
  description = "Names to render"
  type        = list(string)
  default     = ["gasida", "akbun", "fullmoon"]
}

output "for_directive" {
  value = "%{ for name in var.names }\${name}, %{ endfor }"
}

output "for_directive_index" {
  value = "%{ for i, name in var.names }(\${i}) \${name}, %{ endfor }"
}

output "for_directive_index_if" {
  value = <<EOF
%{ for i, name in var.names }
  \${name}%{ if i < length(var.names) - 1 }, %{ endif }
%{ endfor }
EOF
}

Outputs:

for_directive = "gasida, akbun, fullmoon, "
for_directive_index = "(0) gasida, (1) akbun, (2) fullmoon, "
for_directive_index_if = <<EOT

  gasida,

  akbun,

  fullmoon

반복문과 조건문 표현식 사용 예제

  • for-each 와 for문을 이용하는 예제를 진행해 보도록 하겠다.
  • 조건식을 사용하여서 원하는 결과 값을 얻는 방법을 같이 진행하도록 하겠다.

terraform.tfvars

  • 회사의 IAM(인력관리)를 위한 구성이다.
  • 사용자 이름, 등급, 역할, 개발자 유/무의 속성을 갖는 tfvars 파일을 생성한다.
users = [
  {
    name = "john"
    level = 7
    role = "재무"
    is_developer = false
  },
  {
    name = "alice"
    level = 1
    role = "인턴 개발자"
    is_developer = true
  },
  {
    name = "tony"
    level = 4
    role = "데브옵스"
    is_developer = true
  },
  {
    name = "cindy"
    level = 9
    role = "경영"
    is_developer = false
  },
  {
    name = "hoon"
    level = 3
    role = "마케팅"
    is_developer = false
  },
]

main.tf

  • 2개의 그룹을 생성한다.
    - developer, employee
  • IAM 사용자 정보를 갖고 와서 for-each문을 사용하여서 map 안에서 for문을 활용해서 user.name을 key로 user 정보를 values 활용 할 수 있도록 구성 하였다.
  • 조건 표현식을 활용해서 developer 값을 활용해서 그룹에 속하도록 하였다.
  • 사용 권한을 체크하기 위해서 level을 두었고 level로 출력을 할때 조건에 해당하는 사람만 출력하는 부분을 작성 하였다.
provider "aws" {
  region = "ap-northeast-2"
}

resource "aws_iam_group" "developer" {
  name = "developer"
}

resource "aws_iam_group" "employee" {
  name = "employee"
}

output "groups" {
  value = [
    aws_iam_group.developer,
    aws_iam_group.employee,
  ]
}

variable "users" {
  type = list(any)
}

resource "aws_iam_user" "this" {
  for_each = {
    for user in var.users :
    user.name => user
  }

  name = each.key

  tags = {
    level = each.value.level
    role  = each.value.role
  }
}

resource "aws_iam_user_group_membership" "this" {
  for_each = {
    for user in var.users :
    user.name => user
  }

  user   = each.key
  groups = each.value.is_developer ? [aws_iam_group.developer.name, aws_iam_group.employee.name] : [aws_iam_group.employee.name]
}

locals {
  developers = [
    for user in var.users :
    user
    if user.is_developer
  ]
}

resource "aws_iam_user_policy_attachment" "developer" {
  for_each = {
    for user in local.developers :
    user.name => user
  }

  user       = each.key
  policy_arn = "arn:aws:iam::aws:policy/AdministratorAccess"

  depends_on = [
    aws_iam_user.this
  ]
}

output "developers" {
  value = local.developers
}

output "high_level_users" {
  value = [
    for user in var.users :
    user
    if user.level > 5
  ]
}

tfi & tfP & tfa

  • 리소스를 검증하고 생성 진행 한다
  • 그룹과 각 사용 유저 별 IAM 정보가 생성 되는 것을 확인 할 수 있다.
  • 콘솔에서 그룹과 IAM 생성 정보를 확인한다.
  • 사용 유저가 생성 되고 for & conditions 조건에 맞게 그룹에 할당 된것을 확인 할 수 있다.

결론

테라폼에는 다양한 반복문과 조건식에 대한 표현식이 있다.
해당하는 표현식을 운영하는 사람의 편의와 필요에 맞게 익혀서 효율적인 운영 환경에 사용 되었으면 좋겠다.

profile
인프라 운영하는 개발자

0개의 댓글