[Terraform docs : Best Practices] Naming conventions

박종배·2023년 4월 12일
0
post-thumbnail

참고


General conventions

  • resource name, data source name, variable name, output 등에 대쉬(-) 대신에 언더바(_)를 쓰자.
  • 소문자와 숫자를 쓰자.
  • 단, 몇몇 resource들은 대쉬를 쓸 수 없거나 카멜케이스를 꼭 써야하는 케이스들이 있음을 인지하자.

Resource and data source arguments

  1. 부분적이든 완전히든 resource name에 resource type을 반복하지 말자.
    • e.g.
      # good
      'resource' "aws_route_table" "public" {}
      
      # bad
      'resource' "aws_route_table" "public_route_table" {}
      
      # bad
      'resource' "aws_route_table" "public_aws_route_table" {}
  2. resource name은 더 설명할 수 있거나 보편적인 단어가 없을 때, 또는 해당 리소스 모듈이 이 유형의 단일 리소스만 생성할 때에 웬만해서 this를 쓰자. (e.g. AWS VPC 모듈에서는 aws_nat_gateway 타입은 단일 리소스이고 aws_route_table 타입은 리소스를 여러 개 만들 수 있는데 이 경우에 aws_route_table은 더 설명할 수 있는 이름을 써야 하므로 private, public, database 등으로 사용해야 함.
  3. 이름에는 꼭 단수 명사를 쓰자.
  4. 인자의 값이나 사람에게 노출되는 값에는 대쉬 -를 쓰자. (e.g. RDS instance의 내부 DNS name)
  5. tags, depends_on, lifecycle 인자를 해당 resource에서 지원하고 필요한 경우에는 이 언급 순서로 마지막에 꼭 넣고 각 인자마다 빈 칸 하나를 꼭 개행하자.
    • e.g.
      ### good
      resource "aws_nat_gateway" "this" {
        count = 2
      
        allocation_id = "..."
        subnet_id     = "..."
      
        tags = {
          Name = "..."
        }
      
        depends_on = [aws_internet_gateway.this]
      
        lifecycle {
          create_before_destroy = true
        }
      }
      
      ### bad
      resource "aws_nat_gateway" "this" {
        count = 2
      
        tags = "..."
      
        depends_on = [aws_internet_gateway.this]
      
        lifecycle {
          create_before_destroy = true
        }
      
        allocation_id = "..."
        subnet_id     = "..."
      }
  6. count / for_each인자로 조건문을 사용할 때, length 등의 표현식보다는 boolean 값을 쓰자.
    • e.g.
      ### outputs.tf
      resource "aws_nat_gateway" "that" {    # Best
        count = var.create_public_subnets ? 1 : 0
      }
      
      resource "aws_nat_gateway" "this" {    # Good
        count = length(var.public_subnets) > 0 ? 1 : 0
      }

Variables

  1. 되도록 terraform registry에서 module을 사용하고 이 때, variable을 새로 만들지 말고 module 안에 있는 variable에 대한 name, description, default 등을 활용하자.
  2. variable validation이 제한적임.
  3. variable type이 list()map() 이면 변수 이름을 복수형으로 하자.
  4. variable 블록에서 description, type, default, validation 순서로 key를 정렬하자.
  5. description은 무조건 넣기.
  6. type으로 object() 는 각 key 마다 정적인 타입을 지정해줘야 하는게 아니라면 되도록 쓰지말고 간단한 타입(e.g. number, string, list(), map(), any)을 지정해주자.
  7. 만약, object()에서 각 필드들이 똑같은 자료형을 갖는다고 하면 map(map(string)) 처럼 사용하자.
  8. 만약, object()에서 특정 depth에 대한 type validation을 안하고 싶다거나 하나의 key에 여러 개의 자료형을 허용해야 한다면 any 자료형을 쓰자.
  9. {} 값은 map 뿐만이 아니라 object 자료형도 될 수 있는데 tomap(…)을 통해 map 자료형으로 만들어 주자. 추가적으로 여기서 object 자료형으로 만들어주는 방법은 없음.

Outputs

모듈 밖에서 사용한다는 것을 감안하여 일관되고 이해가능하게 작성하자. 예를 들면, 해당 속성의 type이나 attribute를 입력하자.

  1. output의 이름에는 포함하고 있는 속성이 뭔지도 나타내야 함. 보통 정해진 형식이 있음.

  2. output 이름의 권고되는 구조

    {name}_{type}_{attribute}

    • {name} : provider prefix 없이 resource나 data source의 이름. (e.g. aws_subnetsubnet, aws_vpcvpc)
    • {type} : 리소스의 타입.
    • {attribute} : output에 의해 리턴되는 속성.
  3. output의 리턴값이 보간 함수(interpolation func, "${}"(중괄호) 안에 위치한 변수)를 쓰거나 리소스 여러 개를 활용한다면 가능한한 일반적이고 포괄적인 이름을 쓰자.

  4. output의 리턴값이 list라면 복수형 이름을 쓰자.

  5. description은 무조건 넣기.

  6. 민감한 인자는 설정하지 말자.

  7. element(concat(…)) 보다 try()를 쓰자.

e.g.

// good
output "security_group_id" {
  description = "The ID of the security group"
  value       = try(aws_security_group.this[0].id, aws_security_group.name_prefix[0].id, "")
}

// good : Use plural name if the returning value is a list
output "rds_cluster_instance_endpoints" {
  description = "A list of all cluster instance endpoints"
  value       = aws_rds_cluster_instance.this.*.endpoint
}

// bad
output "this_security_group_id" {
  description = "The ID of the security group"
  value       = element(concat(coalescelist(aws_security_group.this.*.id, aws_security_group.web.*.id), [""]), 0)
}
profile
기록하는 엔지니어 되기 💪

0개의 댓글