Nubes et Stella

Terraform #06 (Conditional/For) 본문

DevOps/Terraform

Terraform #06 (Conditional/For)

SeongYeong Han 2023. 10. 19. 23:43

01. Terraform 조건문(Conditional)

테라폼에는 프로그래밍에서와 비슷하게 조건문을 사용할 수 있다. 대표적인 조건 문법인 "Condition ? If_True : If_ False" 형태로 구현될 수 있다.

 

테라폼 문서 : https://developer.hashicorp.com/terraform/language/expressions/conditionals

 

Conditional Expressions - Configuration Language | Terraform | HashiCorp Developer

Conditional expressions select one of two values. You can use them to define defaults to replace invalid values.

developer.hashicorp.com


아래의 예시 코드는 Terraform의 Conditional을 간단하게 구현한 코드이다.

  • line 16 : Variable 값인 is_john이 True일 경우 "Hello John!"가, False 라면 "Hello!"가 message 변수에 들어간다.
  • line 19~21 : output 레이블을 사용하여 해당 message 변수를 출력한다.
  1 provider "aws" {
  2   region = "ap-northeast-2"
  3 }
  4
  5
  6 /*
  7  * Conditional Expression
  8  * Condtion ? If_True : If_False
  9  */
 10 variable "is_john" {
 11   type = bool
 12   default = true
 13 }
 14
 15 locals {
 16   message = var.is_john ? "Hello John!" : "Hello!"
 17 }
 18
 19 output "message" {
 20   value = local.message
 21 }

 

아래의 예시 코드는 Terraform의 Conditional을 사용하여 AWS의 인터넷 게이트웨이를 생성한다.

  • line 14 : Variable.internet_gateway_enabled 값이 True일 경우 count에 1 False일 경우 0이 들어간다.
  • line 13~17 : 1이 들어가면 1번 실행되기 때문에 aws_internet_gateway 가 생성된다.
  1 /*
  2  * Count Trick for Conditional Resource
  3 */
  4 variable "internet_gateway_enabled" {
  5   type = bool
  6   default = true
  7 }
  8
  9 resource "aws_vpc" "this" {
 10   cidr_block = "10.0.0.0/16"
 11 }
 12
 13 resource "aws_internet_gateway" "this" {
 14   count = var.internet_gateway_enabled ? 1 : 0
 15
 16   vpc_id = aws_vpc.this.id
 17 }

 

 

02. Terraform For Expression

테라폼에서의 For 문은 count 와 for_each와 달리 테라폼에서 Expression 가능한 모든 곳에서 사용가능한 문법이다.아래 몇가지 표현방식에 대해서 알아본다.

 

테라폼 문서 : https://developer.hashicorp.com/terraform/language/expressions/for

 

For Expressions - Configuration Language | Terraform | HashiCorp Developer

For expressions transform complex input values into complex output values. Learn how to filter inputs and how to group results.

developer.hashicorp.com

 

가. map으로 부터 키와 밸류값을 받아서 리스트로 리턴

map 변수로 부터 키와 값을 받아서 각각의 길이를 합한 값을 리스트로 출력

[for k, v in var.map : length(k) + length(v)]

 

나. 리스트로 부터 인덱스와 값을 받아서 리스트로 리턴

list 변수로부터 인덱스 번호와 값을 받아서 문자열로 출력

[for i, v in var.list : "${i} is ${v}"]

 

다. 리스트로부터 값을 받아와서 map형식으로 리턴

list 변수로부터 값을 받은 후 s(키) => upper(s)(밸류) 로 전환하여 map으로 출력

{for s in var.list : s => upper(s)}

 

라. for 문과 if 문을 조합

리스트로 부터 값을 받아서 대문자로 출력하는데, 이 때 빈값(" ")이 아니여야 한다.

[for s in var.list : upper(s) if s != ""]

  • 아래의 내용은 terraform.tfvars 파일의 내용이며 users 라는 Variable을 정의한 것이다.
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
  },
]
  • line 9~11, 13~15 : aws IAM 그룹 2개를 생성한다. 이 때 그룹명은 "developer" 와 "employee" 로 설정한다.
  • line 33~37 : Variable users 의 요소들을 user에 담고 map형식의 user의 name 값을 Key값으로 전체를 Values로 return한다.
  • line 39~45 : each.key(user.name)값을 IAM 계정의 이름으로 설정한다. tags로는 level, role 값을 각각 Variable users의 level, role 값을 가져와서 넣는다.
  • line 47~55 : 각 그룹에 계정을 넣는 블록이다. user에 계정을 넣고, groups에 Conditional을 활용하여 Variable Users 중에서 is_developer 값을 확인하여 true이면 employee, developer 그룹에 모두 넣고, False이면 employee 그룹에만 넣는다.
  1 provider "aws" {
  2   region = "ap-northeast-2"
  3 }
  4
  5 /*
  6  * Groups
  7  */
  8
  9 resource "aws_iam_group" "developer" {
 10   name = "developer"
 11 }
 12
 13 resource "aws_iam_group" "employee" {
 14   name = "employee"
 15 }
 16
 17 output "groups" {
 18   value = [
 19     aws_iam_group.developer,
 20     aws_iam_group.employee,
 21   ]
 22 }
 23
 24
 25 /*
 26  * Users
 27  */
 28
 29 variable "users" {
 30   type = list(any)
 31 }
 32
 33 resource "aws_iam_user" "this" {
 34   for_each = {
 35     for user in var.users :
 36     user.name => user
 37   }
 38
 39   name = each.key
 40
 41   tags = {
 42     level = each.value.level
 43     role  = each.value.role
 44   }
 45 }
 46
 47 resource "aws_iam_user_group_membership" "this" {
 48   for_each = {
 49     for user in var.users :
 50     user.name => user
 51   }
 52
 53   user   = each.key
 54   groups = each.value.is_developer ? [aws_iam_group.developer.name, aws_iam_group.employee.name] : [aws_iam_group.employee.name]
 55 }
  • line 65~77 : aws_iam_user_policy_attachment 리소스 블록을 사용하여 developer 계정에 대해서 Admin 접속 권한을 부여한다.
  • line 74~76 : depends_on 속성을 사용하여 aws_iam_user.this 리소스에 대해서 의존성을 생성한다. 이렇게 되면 aws_iam_user.this 리소스가 생성되어야만 권한부여 리소스가 생성된다.
 58 locals {
 59  developers = [
 60   for user in var.users :
 61   user
 62   if user.is_developer
 63  ]
 64 }
 
 65 resource "aws_iam_user_policy_attachment" "developer" {
 66   for_each = {
 67     for user in local.developers :
 68     user.name => user
 69   }
 70
 71   user       = each.key
 72   policy_arn = "arn:aws:iam::aws:policy/AdministratorAccess"
 73
 74   depends_on = [
 75     aws_iam_user.this
 76   ]
 77 }
 78
 79 output "developers" {
 80   value = local.developers
 81 }
 82
 83 output "high_level_users" {
 84   value = [
 85     for user in var.users :
 86     user
 87     if user.level > 5
 88   ]
 89 }
  • 위 테라폼 코드를 통해서 생성된 사용자와, 각 사용자들의 그룹, 권한을 확인할 수 있다.

 

- END -

'DevOps > Terraform' 카테고리의 다른 글

Terraform #08 (taint/Workspace)  (0) 2023.10.24
Terraform #07 (Backend/State)  (0) 2023.10.23
Terraform #05 (count/for_each)  (1) 2023.10.18
Terraform #04 (Variable/Output/Local)  (1) 2023.10.09
Terraform #03  (0) 2023.09.27