반응형

개요

  • 수많은 삽질을 맞치며...
  • TOBE Architecture
  • Atlantis에 Terragrunt 구성하기
  • Terragrunt 설정하기

수많은 삽질을 마치며...

해당 구성을 완료하기 위해 3일정도 매달렸던 것 같다.

막상 완료해보니 문제는 아래와 같았다.

  • Kubernetes 예제는 많으나, ECS Fargate 예제는 많지 않음
  • Ataltnstis가 구동할때 Terragrunt 옵션을 대신 사용하기
  • CPU Architecture 문제

어떻게 트러블 슈팅을 했는지는... 따로 기재하진 않겠지만 

내가한 삽질만큼 다른사람들이 하지 않길 바라며...

 


TOBE Architecture

Architecture

설정 단계는 아래와 같다.

  1. Git Webhook 설정하기
  2. Atlantis ECS Fargate 구성하기
  3. 잘 설정되었는지 확인하기...

 

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를 사용하기 방법을 읽다보면 아래 문구가 나온다.

응, 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

 

결과화면

관련 Git Repository

반응형

+ Recent posts