개요
- 수많은 삽질을 맞치며...
 - TOBE Architecture
 - Atlantis에 Terragrunt 구성하기
 - Terragrunt 설정하기
 
수많은 삽질을 마치며...
해당 구성을 완료하기 위해 3일정도 매달렸던 것 같다.
막상 완료해보니 문제는 아래와 같았다.
- Kubernetes 예제는 많으나, ECS Fargate 예제는 많지 않음
 - Ataltnstis가 구동할때 Terragrunt 옵션을 대신 사용하기
 - CPU Architecture 문제
 
어떻게 트러블 슈팅을 했는지는... 따로 기재하진 않겠지만
내가한 삽질만큼 다른사람들이 하지 않길 바라며...
TOBE Architecture

설정 단계는 아래와 같다.
- Git Webhook 설정하기
 - Atlantis ECS Fargate 구성하기
 - 잘 설정되었는지 확인하기...
 
Atlantis 에 Terragrunt 구성하기
Git Webhook 설정하기
이건 사실 별거없다.
기존 많은 블로그들의 글을 참조해도 상관없다.
내가 기재한 Github에 README.md를 참조하자
여기서 중요한건 Secret은 사용해야 하기때문에 꼭 기억 / 저장해두도록...
https://github.com/zkfmapf123/atlantis-fargate
Atlantis ECS Fargate 구성하기
Atlantis는 ECS Fargate Module을 제공한다.
https://registry.terraform.io/modules/terraform-aws-modules/atlantis/aws/2.5.0
하지만 이미 나는 ALB도 이미있고, Route53도 구축된상태라
몇몇부분 수정하였다.
- 기존과 특이점
- Cluster는 이미 존재했음 (코드 참조)
 - ALB도 이미 존재했음 (코드 참조)
 - environments.ATLANTIS_REPO_CONFIG_JSON (하단 설명)
 - secrets.AWS_ACCESS_KEY_ID (하단 설명)
 - secrets.AWS_SECRET_ACCESS_KEY (하단 설명)
 
 
variable "atlantis_attr" {
  default = {
    devops_prefix   = "devops"
    security_prefix = "security"
    name            = "atlantis"
    port            = "4141"
    host_header     = ["HOST_HEADER"]
  }
}
#################################################### Listner Target Group ####################################################
resource "aws_lb_target_group" "atlantis_ecs_tg" {
  name        = "${var.atlantis_attr.devops_prefix}-${var.atlantis_attr.name}-tg"
  port        = var.atlantis_attr.port
  protocol    = "HTTP"
  target_type = "ip"
  vpc_id      = var.vpc_id
  health_check {
    path                = "/"
    port                = var.atlantis_attr.port
    protocol            = "HTTP"
    healthy_threshold   = 3
    unhealthy_threshold = 3
    matcher             = "200-301"
    timeout             = 30
    interval            = 40
  }
  deregistration_delay = 60
}
resource "aws_lb_listener_rule" "atlantis_443_rule" {
  listener_arn = local.alb.security_alb.listener_443_arn
  priority     = "100"
  action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.atlantis_ecs_tg.arn
  }
  condition {
    host_header {
      values = var.atlantis_attr.host_header
    }
  }
}
#################################################### Atlantis ####################################################
module "atlantis" {
  source = "terraform-aws-modules/atlantis/aws"
  name = "${var.atlantis_attr.devops_prefix}-${var.atlantis_attr.name}"
  # ECS Container Definition
  atlantis = {
    environment = [
      {
        name  = "ATLANTIS_GH_USER"
        value = "[리뷰 사용자 이메일]"
      },
      {
        name  = "ATLANTIS_REPO_ALLOWLIST"
        value = "[Atlantis Webhook 설정한 GIT 주소]"
      },
      {
        name : "ATLANTIS_REPO_CONFIG_JSON", ## 이건 왜 필요한지 이따 설명
        value : jsonencode(yamldecode(file("${path.module}/server-atlantis.yaml"))),
      }
    ]
    secrets = [
      {
        name      = "ATLANTIS_GH_TOKEN"
        valueFrom = "[Github Access Token]"
      },
      {
        name      = "ATLANTIS_GH_WEBHOOK_SECRET"
        valueFrom = "[Webhook 때 지정한 SecretKey]"
      },
      {
        name      = "AWS_ACCESS_KEY_ID"
        valueFrom = "[이건 왜 필요한지 이따 설명]"
      },
      {
        name      = "AWS_SECRET_ACCESS_KEY"
        valueFrom = "[이건 왜 필요한지 이따 설명]"
      },
    ]
  }
  # ECS Service
  service = {
    task_exec_secret_arns = [
      "SSM ARNS",
 
    ]
    # Provide Atlantis permission necessary to create/destroy resources
    tasks_iam_role_policies = {
      AdministratorAccess = "arn:aws:iam::aws:policy/AdministratorAccess"
    }
  }
  service_subnets = local.was_subnet_ids
  vpc_id          = var.vpc_id
  # Cluster -> 이미 나는 Clustr가 존재햇음
  create_cluster = false
  cluster_arn = local.alb.security_alb.ecs_cluster_arn
  # ALB -> 이미 나는 ALB가 존재했음
  create_alb            = false
  alb_target_group_arn  = aws_lb_target_group.atlantis_ecs_tg.arn
  alb_security_group_id = local.alb.alb_sg_id
  tags = {
    Environment = "prd"
    Terraform   = "true"
    System      = "ecs"
  }
}
output test {
  value = "atlantis"
}
environments.ATLANTIS_REPO_CONFIG_JSON
이건 아틀란티스 서버자체에 Config 파일이다.
해당 Config 파일에서는 여러가지 옵션을 수정할 수 있지만 우리가 지금 당장 필요한건 Action 을 Custom으로 수정하도록 하는 옵션을 설정해야 한다. (Terragrunt를 실행하기 위해)
// server.atlantis.yaml
repos:
  - id: /.*/
    allow_custom_workflows: true ## 이걸 true로 해줘야함
    allowed_overrides:
      - apply_requirements
      - workflow
    apply_requirements:
      - approved
    workflow: default
만약, allow_custom_workflows 값을 true로 하지 않는다면
뭔가 계속 설정해도 terraform 으로만 실행하게 된다 (이걸로 하루정도 날렸던 것 같음)
secrets.AWS_ACCESS_KEY_ID / secrets.AWS_SECRET_ACCESS_KEY (Optional)
이건 무슨 옵션이지 하는 사람도 있을텐데,
Atlantis에 꼭 넣어야 하는 환경변수는 아니지만 현재 우리회사는 Multi Account로 관리되고 있기때문에
Terraform 사용자 계정을 AssumeRole을 통해서 접근하는 방안을 채택하였다.
자세한내용은 아래 블로그참조
https://zkfmapf999.tistory.com/31
Terragrunt 설정하기
자 위 방법대로 구성하면 아주 멋있는 Atlantis 가 생성된다.
그럼 저 이미지에서 Terragrunt를 구성하려면 어떻게 해야될까?
Terragrunt를 구동할 수 있는 이미지 만들기
Atlantis 공식문서 Terragrunt를 사용하기 방법을 읽다보면 아래 문구가 나온다.

그럼... 만들어야지
잘 읽어보면 terragrunt 파일을 만들어서 /usr/local/bin 파일에 넣은것 뿐이지만...
진짜 서치 여러군데 해봤는데 아무것도 없어서 만들었음
## 2025.2.14 dobby.lee
FROM ghcr.io/runatlantis/atlantis:latest
USER root
RUN apk update && apk add --no-cache curl jq \
    && TERRAGRUNT_VERSION=$(curl -sL https://api.github.com/repos/gruntwork-io/terragrunt/releases/latest | jq -r .tag_name) \
    && curl -L -o /usr/local/bin/terragrunt https://github.com/gruntwork-io/terragrunt/releases/download/${TERRAGRUNT_VERSION}/terragrunt_linux_amd64 \
    && chmod +x /usr/local/bin/terragrunt
# 환경 변수 설정
ENV ATLANTIS_GH_USER=test
ENV ATLANTIS_REPO_ALLOWLIST=test
ENV ATLANTIS_GH_TOKEN=test
ENV ATLANTIS_GH_WEBHOOK_SECRET=test
ENV AWS_ACCESS_KEY_ID=test
ENV AWS_SECRET_ACCESS_KEY=test
RUN mkdir -p /home/atlantis/.atlantis/bin \
    && chown -R atlantis:atlantis /home/atlantis/.atlantis
RUN chown -R atlantis:atlantis /home/atlantis/.atlantis
USER atlantis
ENTRYPOINT ["atlantis", "server"]
혹시... amd64로 변환해야한다면 buildx를 쓰거나 위 download 파일을 바꾸시길
Repository 설정 수정하기
자 여기까지 했으면 다했음
뭐만 남았냐...
이제 Atlantis가 구동될 Repository에 명령어만 Terragrunt로 변환시켜 주면된다.
Repository 기준 root path에 위치시키자
version: 3
projects:
- dir: [terragrunt.hcl이 존재하는 path]
  workflow: terragrunt
workflows:
  terragrunt:
    plan:
      steps:
      - env:
          name: TERRAGRUNT_TFPATH
          command: 'echo "terraform${ATLANTIS_TERRAFORM_VERSION}"'
      - env:
          name: TF_IN_AUTOMATION
          value: 'true'
      - run:
          command: terragrunt plan -input=false -out=$PLANFILE
          output: strip_refreshing
    apply:
      steps:
      - env:
          name: TERRAGRUNT_TFPATH
          command: 'echo "terraform${ATLANTIS_TERRAFORM_VERSION}"'
      - env:
          name: TF_IN_AUTOMATION
          value: 'true'
      - run: terragrunt apply $PLANFILE
결과화면

'Architecture > IaC + CICD' 카테고리의 다른 글
| IaC Dream Architecture (나의 꿈 === 공상) (0) | 2025.06.21 | 
|---|---|
| IaC 고도화 프로젝트 - 1 (+ github aciton) (0) | 2025.02.08 | 
| Terragrunt 이슈 (terragrunt destroy) (0) | 2025.01.19 | 
| 나만의 테라폼을 사용하는 방법 (굉장히 주관적) (1) | 2024.12.22 |