Itmom's blog

Terragrunt - DRY and maintainable Terraform code 본문

Development/Devops

Terragrunt - DRY and maintainable Terraform code

Itmom 2022. 2. 17. 01:18

1. Terragrunt란?

Terragrunt는 terraform을 이용한 IaaC를 작성할 때, terraform 코드를 DRY (Don't Repeat Yourself) principle을 지키며 작성할 수 있도록 돕는 wrapper다.

2. Keep your Terraform code DRY

└── live
    ├── prod
    │   ├── app
    │   │   └── main.tf
    │   ├── mysql
    │   │   └── main.tf
    │   └── vpc
    │       └── main.tf
    ├── qa
    │   ├── app
    │   │   └── main.tf
    │   ├── mysql
    │   │   └── main.tf
    │   └── vpc
    │       └── main.tf
    └── stage
        ├── app
        │   └── main.tf
        ├── mysql
        │   └── main.tf
        └── vpc
            └── main.tf

다른 환경에 대한 infrastructure 코드를 작성할 때, 대부분의 환경 설정이 같고 약간의 설정들만 달라도 위와 같이 각 환경마다 별도의 terraform 코드를 작성해줘야 한다. Infrastructure의 규모가 커짐에 따라 중복되는 코드들을 모두 관리해야 하기에, 휴먼 에러가 쉽게 발생할 수 있게 된다. 이에 terragrunt는 중복되는 코드를 하나의 repository에서 관리하고, 설정이 다른 부분만 별도의 코드로 관리할 수 있도록 돕는다.

3. Keep your remote state configuration DRY

Terraform은 여러 사람과 협업할 경우를 고려해 remote state storage 기능을 지원하지만, 각 terraform file마다 사용하고자 하는 backend 설정을 모두 명시해야 한다는 불편함이 있다. Terragrunt는 remote_state와 관련된 설정을 project 단위로 쉽게 통합할 수 있도록 돕는다.

├── backend-app
│   └── main.tf
├── frontend-app
│   └── main.tf
├── mysql
│   └── main.tf
└── vpc
    └── main.tf

만약 project가 위와 같은 구조였다면, 4개의 main.tf에 다음과 같이 backend를 설정하는 코드를 모두 작성했어야 하겠지만,

terraform {
  backend "s3" {
    bucket         = "my-terraform-state"
    key            = "frontend-app/terraform.tfstate"
    region         = "us-east-1"
    encrypt        = true
    dynamodb_table = "my-lock-table"
  }
}

terragrunt 사용 시 tf file은 어떤 backend를 사용할 것인지 명시하는 것만으로도 충분해진다.

terraform {
  # The configuration for this backend will be filled in by Terragrunt
  backend "s3" {}
}

전체 folder structure는 다음과 같이 변할 것이다.

├── terragrunt.hcl
├── backend-app
│   ├── main.tf
│   └── terragrunt.hcl
├── frontend-app
│   ├── main.tf
│   └── terragrunt.hcl
├── mysql
│   ├── main.tf
│   └── terragrunt.hcl
└── vpc
    ├── main.tf
    └── terragrunt.hcl

root에 있는 terragrunt file에 remote_state와 관련된 설정이 포함될 것이고, child terragrunt file들에는

include "root" {
  path = find_in_parent_folders()
}

위와 같이 root에 있는 설정을 사용하게 되며, tf file에는 어떤 backend를 사용할 것인지 명시하기만 하면 된다. 2에서 언급한 내용은 여러 project에서 공통적으로 사용하는 terraform 모듈에 대한 내용인가 하면, 3에서 다룬 내용은 한 project안에서 공통되는 remote_state를 줄이기 위한 설정임을 알아두자!

4. Keep your Terragrunt Architecture DRY

2에서 Terraform 코드가 겹치는 문제는 해소했지만.. project terragrunt 환경 설정이 겹치는 문제는 아직 해소하지 못하고 있다. 당연지사! terragrunt는 이 문제도 쉽게 해결할 수 있도록 include block을 제공하고 있다.

include "env" {
  path = "${get_terragrunt_dir()}/../../_env/app.hcl"
}

위와 같은 형태로 작성할 수 있다!

5. Keep your CLI flags DRY

terraform을 사용하다 보면, cli 사용 시에 extra argument들을 줄 수 있는데, terragrunt는 이러한 부분까지 dry하게 관리할 수 있는 기능을 제공한다! 예를 들어, terraform 모든 command 작동 시에 20 min lock up이 작동하도록 설정하고자 한다면,

terraform {
  # Force Terraform to keep trying to acquire a lock for
  # up to 20 minutes if someone else already has the lock
  extra_arguments "retry_lock" {
    commands = [
      "init",
      "apply",
      "refresh",
      "import",
      "plan",
      "taint",
      "untaint"
    ]

    arguments = [
      "-lock-timeout=20m"
    ]

    env_vars = {
      TF_VAR_var_from_environment = "value"
    }
  }
}

위와 같이 extra arguments를 줄 수 있다.

terragrunt의 내용을 간단하게 살펴보았다. 자세한 terragrunt의 feature들은 다음 post에서 다뤄보겠다! 작년 한 해 blog에 좀 소홀했는데... 올해는 열심히 작성해보려고 한다!

'Development > Devops' 카테고리의 다른 글

bigquery로 로깅 서버 구축  (0) 2022.02.26
ArgoCD를 이용한 CD 시스템 구축  (0) 2022.02.26