Atlantis 배포하기

AWS 환경에 Atlantis 배포하기

Atlantis 인프라 배포

지금부터 Atlantis 실행을 위한 인프라 배포를 해보도록 하겠습니다. Atlantis 코드는 terraform-aws-modules 공식 레포에 공개되어 있어서 이를 활용했습니다. 일부 간단한 설정만 하시면 손쉽게 배포하실 수 있습니다. 본 실습에서는 ECS Fargate를 이용하여 인프라를 배포할 예정입니다.

  • atlantis 인프라 코드는 아래 링크에 있습니다. (terraform/platform/atlantis )

  • 아래 코드는 terraform-aws-atlantis 코드를 fork 해서 일부 수정한 코드입니다.

변수 설정

다른 부분은 따로 고칠 필요가 없고, terraform.tfvars 파일에서 변수만 설정하시면 됩니다. 여러 변수들이 있지만 변경을 하면 좋은 부분만 따로 정리했습니다.

(... 생략 ...)

# DNS
## Route 53 record
route53_zone_name = "example.com"
route53_zone_id   = "zone id of example.com"

# ACM (SSL certificate)
# Specify ARN of an existing certificate or new one will be created and validated using Route53 DNS:
certificate_arn = ""

# Atlantis
# Name of repositories that you want to apply atlantis to
atlantis_allowed_repo_names = ["atlantis-dayone"] 

# Your repository including organization or personal name
atlantis_repo_whitelist = ["github.com/example/*"]

# Specify one of the following block.
# For Github
atlantis_github_user = "dayone"

(... 생략 ...)

배포 진행

terraform initterraform plan 을 통해서 생성되는 리소스를 확인합니다. 이 때 이전에 생성했던 github personal token을 사용하셔야 합니다.

$ terraform plan -parallelism=30
var.atlantis_github_user_token
  GitHub token of the user that is running the Atlantis command

  Enter a value: < personal access token here!! >

Plan: 43 to add, 0 to change, 0 to destroy. 라고 나오면 정상입니다. Plan 결과가 정상으로 나오면 apply를 하시면 됩니다.

Webhook 설정

Apply를 완료하면 아래와 같이 output이 나옵니다. 이중에서 atlantis_url_eventswebhook_secret 을 복사하셔서 Github webhook을 설정합니다.

Apply complete! Resources: 43 added, 0 changed, 0 destroyed.

Outputs:

alb_dns_name = atlantis-xxxx
atlantis_allowed_repo_names = [
  "atlanstis-example",
]
atlantis_url = https://atlantis.feeldayone.com
atlantis_url_events = https://atlantis.feeldayone.com/events
ecs_task_definition = atlantis:2
task_role_arn = arn:aws:iam::xxxxxxxxx:role/atlantis-ecs_task_execution
vpc_id = vpc-xxxxxx
webhook_secret = xxxxx...yyyy

먼저, atlantis를 사용할 Repository -> Settings -> Webhooks 로 들어갑니다.

  • Add webhook 을 클릭합니다.

  • Payload URL란에 atlantis_url_events 에 나온 URL을 입력합니다.

  • Secret 란에 webhook_secret 에 나온 값을 입력합니다.

  • Which events would you like to trigger this webhook? 란에 Let me select individual events 를 선택합니다.

  • 아래 4개의 항목을 체크하신 후에, update webhook을 클릭합니다.

    • Issue comments

    • Pull requests

    • Pull request reviews

    • Pull request review comments

atlantis.yaml 파일 생성

atlantis.yaml 파일은 atlantis에서 사용하는 설정파일입니다. Atlantis가 배포되어 있다고 하더라도, atlantis.yaml 파일에 적용할 디렉토리를 정의하지 않으면 작동하지 않습니다. 따라서 작업을 원하는 디렉토리는 모두 설정해주셔야 합니다.

  • Project에 명시된 스펙에 따라서 atlantis가 변경사항을 파악하여 plan을 실행합니다.

  • Project가 다른 Account에 있는 경우에는 Assume을 해야하는데, 이 때 workflow를 활용하시면 됩니다.

  • 아래는 ID 계정에서 Prod 계정으로 Assume 해서 plan을 실행시켜주는 예시입니다.

  • apply_requirements 부분을 추가하시면 반드시 누군가의 approve가 있을 때만 apply가 가능합니다. 바로 apply하고 싶으신 경우에는 반드시 삭제하고 진행하시기 바랍니다.

version: 3
automerge: true
projects:

  # Prod
  - name: test          # 구분을 위한 이름입니다.
    dir: terraform/test # 적용을 위한 디렉토리 경로입니다.
    workspace: default  # 테라폼 workspace 설정입니다.
    terraform_version: 0.12.18 # 테라폼 버전입니다.
    autoplan:           # 아래 명시된 파일을 수정했을 때 자동으로 plan 실행
      when_modified: [  
        "*.tf",
        "terraform.tfvars"
      ]
      enabled: true
    apply_requirements: [approved] 
    workflow: prod      # 아래에 정의된 workflow


#### Workflows #####
#### 여러 Account를 정의하실 수 있습니다. ####
workflows:
  # id
  id:
    plan:
      steps:
      - init:
          extra_args: [
            '-upgrade=true'
          ]
      - plan:
    apply:
      steps:
      - apply

  # Prod
  prod:
    plan:
      steps:
      - init:
          extra_args: [
            '-backend-config="role_arn=<Assume Role ARN>"',
            # We want the latest version of module. In most cases we should be pinning our version of a module.
            '-upgrade=true'
          ]
      - plan:
          extra_args: [
            "-var 'assume_role_arn=<Assume Role ARN>'"
          ]
    apply:
      steps:
      - apply

Cross Account 작업

Mutli-account를 운영하시게 되면, ID 계정에서 여러 account에 assume해서 인프라를 관리하실 수 있습니다. Atlantis를 ID 계정에 배포하신 후에, 각 계정의 assume role을 ID 계정의 atlantis role이 assume할 수 있도록 trust relationships 에 추가하셔야 합니다. 예를 들어보겠습니다.

  • ID 계정의 atlantis role : arn:aws:iam::<id-account-id>:role/atlantis-ecs_task_execution

  • Prod 계정의 assume role : arn:aws:iam::<prod-account-id:role/assume-dayone-prod-admin

이 경우에는 atlantis role이 prod의 assume role을 assume하는 경우입니다. 이 때 두가지가 설정되어야 합니다.

  1. atlantis role은 prod 계정의 role을 assume할 수 있는 권한이 필요합니다. Atlantis는 앞으로 여러 resource를 관리할 예정이기 때문에 AdministratorAccess 를 부여합니다.

  2. Prod 계정의 assume role이 atlantis role을 신뢰할 수 있도록, prod role의 trusted entity에 추가해주셔야 합니다.

Atlantis 실행하기

위와 같이 atlantis.yaml 을 루트 디렉토리에 저장한 후에 아래와 같이 예시 파일을 작성합니다. 위에서 terraform/test 디렉토리를 지정했으므로 실제 디렉토리도 동일하게 만듭니다.

  • Atlantis 예제 코드는 아래 링크에 있습니다.

여기서 하나 중요한 건, assume을 하기 위해서 반드시 assume_role_arn 변수를 넣어주셔야 한다는 것입니다. 해당 변수가 없으면 실행이 되지 않으니 반드시 추가해주시기 바랍니다. 아래 예시는 최초에 인프라 세팅을 위해 init 했던 작업을 atlantis를 통해서 배포하기 위한 코드입니다.

terraform/test/init.tf

provider "aws" {
  region = "ap-northeast-2" # Please use the default region ID
  version = "~> 2.49.0" # Please choose any version or delete this line if you want the latest version
  
  assume_role {
    role_arn     = var.assume_role_arn
    session_name = var.atlantis_user
  }
}

# S3 bucket for backend
resource "aws_s3_bucket" "tfstate" {
  bucket = "${var.account_id}-apnortheast2-tfstate"

  versioning {
    enabled = true # Prevent from deleting tfstate file
  }
}

# DynamoDB for terraform state lock
resource "aws_dynamodb_table" "terraform_state_lock" {
  name           = "terraform-lock"
  hash_key       = "LockID"
  billing_mode   = "PAY_PER_REQUEST"

  attribute {
    name = "LockID"
    type = "S"
  }
}

variable "account_id" {
 default = "dayone-prod-test" # Please use the account alias for id
}



variable "assume_role_arn" {
  description = "The role to assume when accessing the AWS API."
  default     = ""
}

variable "atlantis_user" {
  description = "The username that will be triggering atlantis commands. This will be used to name the session when assuming a role. More information - https://github.com/runatlantis/atlantis#assume-role-session-names"
  default     = "atlantis_user"
}

이제 git branch를 만들고 PR을 날려보겠습니다. 해당 디렉토리의 *.tf 파일이 수정되었기 때문에, 아래와 같이 자동으로 terraform plan 이 실행된 것을 보실 수 있습니다.

이렇게 정상적으로 plan이 완료되면, comment에 atlantis apply 를 입력해서 인프라를 배포합니다.

이후 작업

이후에 추가적으로 atlantis를 적용할 Directory가 있는 경우에는 반드시 해당 directory에 대한 정보를 atlantis.yaml 에 정의하셔야 합니다.

Last updated