Cloud Tech

EKS에서 Atlantis 구성하기

Hanhorang31 2024. 7. 14. 00:31
 

Overview

오픈소스 Terraform Runner 툴인 Atlantis를 이해하고, EKS 환경에서 구성하겠습니다.

 

Atlantis

Atlantis는 Terraform 기반 인프라 코드 변경을 관리하는 자동화 도구로,

GitHub, GitLab, Bitbucket 등과 통합되어 PR(Pull Request) 이벤트를 통해 plan 및 apply 명령을 실행합니다.

Terraform Cloud와 비교하여 Atlantis는 테라폼 부가 기능이 없지만,

비용이 무료이며 자체 호스팅할 수 있다는 장점이 있습니다.

아틀란티스 아키텍처는 다음과 같습니다.

  • VCS Controller(코드 관리 시스템 컨트롤러)에서 코드 관리 툴의 Comment, PR 이벤트를 핸들링하여 테라폼 명령어을 수행합니다. 관련 내용
  • Runner에서 테라폼 명령어를 수행하며 수행 전, 후로 사용자 웹 훅을 설정할 수 있습니다.
  • 구성 일관성을 위해 디렉토리와 워크스페이스를 잠그는 Lock 기능이 제공됩니다. 관련 내용
  • 프로메테우스 또한 같이 구성되어 있어 메트릭 확인이 가능합니다.
  • 자격 증명이 있는 서버에서 Atlantis를 실행하므로 보안 구성이 필수입니다. 아틀란티스 레벨에서는 허용된 저장소와 API만 제한하며, 테라폼 구성 계획도 사전 사용자 계획을 통해 보호할 수 있도록 구성해야 합니다. 관련 내용
 

Events Controller | Atlantis

 

www.runatlantis.io

 

 

Locking | Atlantis

 

www.runatlantis.io

 

 

Security | Atlantis

 

www.runatlantis.io

 

 

Atlantis 배포

EKS에서 아틀란티스를 배포하고, Github Repo 와 연동하여 기능 동작을 테스트하겠습니다.

EKS 1.30 버전 노드(m5.large) 2대 구성 addn 구성(aws-load-balancer-controller, external-dns, ebs-csi-driver)

Github Repo 구성

아틀란티스를 사용하기전 Github repo 구성과 웹 훅 설정을 진행해야 합니다.

  • private 옵션으로 설정하고 repo 생성

접근 토큰 생성

Setting > 최하단 Developer Settings > personal access tokens > Tokens(classic)

  • select scopes에서 repo와 admin:org_hook 권한 설정

웹 훅 시크릿 구성

browserling: Generate Random Strings and Numbers > 32 길이 설정 후 발급

 

깃허브 웹 훅 설정

생성 Repo > Setting > Webhooks > Add Webhook

  • Payload URL은 빈 값으로, Content type은 application/json, Secret은 웹 훅 시크릿 값, SSL verification은 Disable로 클릭 후 생성

웹 훅을 설정하고 Recent Delivery에서 로그를 확인할 수 있습니다.

현재 아틀란티스를 구성하지 않았으므로 502에러가 떨어집니다.

 

 

Atlantis 구성

helm repo add runatlantis https://runatlantis.github.io/helm-charts
helm inspect values runatlantis/atlantis > values.yaml

아틀란티스 구성은 다음과 같이 설정하였습니다.

vi values-atlantis.yaml
---------------

#  add atlantis public domain for :
atlantisUrl: http://horang.link

# Add your terraform repository:
##in my case I'm using the same repository
orgWhitelist: github.com/HanHoRang31/t101-cicd

# If using GitHub, specify like the following: 
github:
  user: t****66@gmail.com
  token: *******************
  secret: *******************

# -- Optionally specify an username and a password for basic authentication.
basicAuth:
  username: "admin"
  password: "1234"

ingress:
  annotations: 
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: ip
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]'
    alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:ap-northeast-2:*******
    alb.ingress.kubernetes.io/success-codes: 200-399
    alb.ingress.kubernetes.io/group.name: "atlantis"
  hosts:
    - host: atlantis.horang.link
      service: atlantis
      paths: ["/*"]


#Specify AWS credentials to be mapped to ~/.aws inside the atlantis container
# to allow atlantis container access AWS:
aws:
   credentials: |
              [default]
              aws_access_key_id = A***************K
              aws_secret_access_key = 0********************
              region = ap-northeast-2
   config: |
     [profile a_role_to_assume]
     role_arn = arn:aws:iam::**************:role/AmazonEKS_EBS_CSI_DriverRole
     source_profile = default
#defaultTFVersion set the default terraform version to be used in atlantis server
## it should be the same as your terraform version to overcome any terraform lock status
defaultTFVersion: 1.8.5
  • 차트 배포시 ebs-csi-driver 배포 및 PVC 설정이 필요합니다.
helm install atlantis runatlantis/atlantis -f values-atlantis.yaml -n atlantis

아틀란티스 구동을 확인하였으면 깃허브 webhook 설정으로 돌아가 URL을 등록합니다.

  • URL 뒤에 /event를 추가해야 합니다.

 

 

연동 테스트

T1014 스터디에서 제공해주신null 프로바이더 내용으로 연동 테스트를 진행하겠습니다.

# git clone
git clone https://github.com/HanHoRang31/t101-cicd.git && cd t101-cicd && tree

# feature branch 생성
git branch test && git checkout test && git branch

# main.tf 파일 작성
echo 'resource "null_resource" "example" {}' > main.tf

# add commit push
git add main.tf && git commit -m "add main.tf" && git push origin test

403 에러로 발생합니다. atlantis 파드 로그를 확인하면, 아틀란티스 서버에 repo 허용이 필요합니다.

아틀란티스 서버 구성을 repo 허용 내용을 추가합니다.

vi values-atlantis.yaml
---
..
..
defaultTFVersion: 1.8.5

repoConfig: |
  ---
  repos:
  - id: /.*/
    apply_requirements: []
    workflow: default
    allowed_overrides: []
    allow_custom_workflows: false
  - id: github.com/HanHoRang31/t101-cicd
    apply_requirements: [approved, mergeable]
    workflow: default
  workflows:
    default:
      plan:
        steps: [init, plan]
      apply:
        steps: [apply]
  metrics:
    prometheus:
      endpoint: /metrics
----

# 아틀란티스 서버 config 업데이트 
kubectl delete pods/atlantis-0 -n atlantis
helm upgrade -i atlantis runatlantis/atlantis -f values-atlantis.yaml -n atlantis

다시 웹 훅을 테스트하면 200 결과를 확인할 수 있습니다.

다만, PR 을 다시 생성하여 요청하는 경우 다음과 같이 Lock을 확인할 수 있습니다.

Lock은 충돌 방지, 최신 상태의 인프라 반영을 목적으로 구성되어 있습니다.

필자의 경우는 연동 단계에서 이전 PR Close Event가 아틀란티스로 전달하지 못해 발생한 현상이였습니다.

Lock은 아틀란티스 서버에서 해제가 가능합니다.

해제 후 깃 PR 에 comment를 달아 동작을 확인합니다.

아틀란티스 관련 명령어는 커맨트로 확인이 가능합니다.

그 외 명령어는 공식 문서를 참고해주세요.

 

Using Atlantis | Atlantis

 

www.runatlantis.io

 

 

프로메테우스 연동

아틀란티스는 다음의 프로메테우스 메트릭을 노출합니다.

차트 수정을 통해 프로메테우스에서 메트릭을 가져오도록 구성하겠습니다.

먼저, 아틀란티스 구성을 다음과 같이 수정하여 servicemonitor를 배포합니다.

vi values-atlantis.yaml
---
..
..
  metrics:
    prometheus:
      endpoint: /metrics
      
servicemonitor:
  # -- To enable a Prometheus servicemonitor, set enabled to true,
  #   and enable the metrics in this file's repoConfig
  #   by setting a value for metrics.prometheus.endpoint.
  enabled: true   
----
# 아틀란티스 배포
helm upgrade -i atlantis runatlantis/atlantis -f values-atlantis.yaml -n atlantis

이어서, 프로메테우스 스택을 배포하겠습니다.

# 모니터링
kubectl create ns monitoring
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
MyDomain=<도메인>

# 파라미터 파일 생성
cat < monitor-values.yaml
prometheus:
  prometheusSpec:
    podMonitorSelectorNilUsesHelmValues: false
    serviceMonitorSelectorNilUsesHelmValues: false
    retention: 5d
    retentionSize: "10GiB"

  ingress:
    enabled: true
    ingressClassName: alb
    hosts: 
      - prometheus.$MyDomain
    paths: 
      - /*
    annotations:
      alb.ingress.kubernetes.io/scheme: internet-facing
      alb.ingress.kubernetes.io/target-type: ip
      alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]'
      alb.ingress.kubernetes.io/success-codes: 200-399
      alb.ingress.kubernetes.io/load-balancer-name: monitoring
      alb.ingress.kubernetes.io/group.name: study
      alb.ingress.kubernetes.io/ssl-redirect: '443'

grafana:
  defaultDashboardsTimezone: Asia/Seoul
  adminPassword: prom-operator

  ingress:
    enabled: true
    ingressClassName: alb
    hosts: 
      - grafana.$MyDomain
    paths: 
      - /*
    annotations:
      alb.ingress.kubernetes.io/scheme: internet-facing
      alb.ingress.kubernetes.io/target-type: ip
      alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]'
      alb.ingress.kubernetes.io/success-codes: 200-399
      alb.ingress.kubernetes.io/load-balancer-name: monitoring
      alb.ingress.kubernetes.io/group.name: study
      alb.ingress.kubernetes.io/ssl-redirect: '443'

defaultRules:
  create: false
kubeControllerManager:
  enabled: false
kubeEtcd:
  enabled: false
kubeScheduler:
  enabled: false
alertmanager:
  enabled: false
EOT

# 배포
helm install kube-prometheus-stack prometheus-community/kube-prometheus-stack --version 45.27.2 \
--set prometheus.prometheusSpec.scrapeInterval='15s' --set prometheus.prometheusSpec.evaluationInterval='15s' \
-f monitor-values.yaml --namespace monitoring

프로메테우스에서 메트릭 수집 확인시, 401 에러가 확인됩니다.

401에러는 servicemonitor 설정시, 아틀란티스 auth(사용자정보)를 설정하지 않아 발생하였습니다.

아래 값를 참고하여 servicemonitor 정보를 수정합니다.

kubectl edit servicemonitor/atlantis -n atlantis

추가 후 프로메테우스를 확인하면 정상적으로 메트릭을 수집하는 것을 확인할 수 있습니다.

아쉬운 점은 그라파나 대시보드 랩에 Atlantis 관련 대시보드를 찾을 수 없었습니다.

추후 필요한 사항이 있으면 대시보드를 직접 구성해야겠네요.