Closed24

Atlantisをk8s上に立ててどんなものか調べる

Futa HirakobaFuta Hirakoba

Atlantisをk8s上に立てる。
https://www.runatlantis.io/docs/deployment.html#kubernetes-manifests

ローカルに建てて実験しない理由としてはGitHubのWebhookを受け取るためにインターネットからアクセスできる必要があるため。チュートリアルではNgrokを入れないといけないが、Ngrokは入れたくないため、インターネットからアクセス可能なServiceを簡単に作れるoktetoを利用する。

Futa HirakobaFuta Hirakoba

k8sリソースのSecretを作成する

echo -n "yourtoken" > token
echo -n "yoursecret" > webhook-secret
kubectl create secret generic atlantis-vcs --from-file=token --from-file=webhook-secret

--from-fileでやるのめんどいな

--from-literal使う。

❯ kubectl create secret generic atlantis-vcs --from-literal=token="${ATLANTIS_GITHUB_PAT}" --from-literal=webhook-secret="${ATLANTIS_WEBHOOK_SECRET}"
secret/atlantis-vcs created

作れたっぽい

Futa HirakobaFuta Hirakoba

マニフェスト書き換え

DeploymentStatefulsetが提供されているが、Statefulsetが推奨されているのでそっちを使う。

サンプルの Statefulset
statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: atlantis
spec:
  serviceName: atlantis
  replicas: 1
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      partition: 0
  selector:
    matchLabels:
      app: atlantis
  template:
    metadata:
      labels:
        app: atlantis
    spec:
      securityContext:
        fsGroup: 1000 # Atlantis group (1000) read/write access to volumes.
      containers:
      - name: atlantis
        image: runatlantis/atlantis:v<VERSION> # 1. Replace <VERSION> with the most recent release.
        env:
        - name: ATLANTIS_REPO_ALLOWLIST
          value: github.com/yourorg/* # 2. Replace this with your own repo allowlist.

        ### GitHub Config ###
        - name: ATLANTIS_GH_USER
          value: <YOUR_GITHUB_USER> # 3i. If you're using GitHub replace <YOUR_GITHUB_USER> with the username of your Atlantis GitHub user without the `@`.
        - name: ATLANTIS_GH_TOKEN
          valueFrom:
            secretKeyRef:
              name: atlantis-vcs
              key: token
        - name: ATLANTIS_GH_WEBHOOK_SECRET
          valueFrom:
            secretKeyRef:
              name: atlantis-vcs
              key: webhook-secret
        ### End GitHub Config ###

        ### GitLab Config ###
        - name: ATLANTIS_GITLAB_USER
          value: <YOUR_GITLAB_USER> # 4i. If you're using GitLab replace <YOUR_GITLAB_USER> with the username of your Atlantis GitLab user without the `@`.
        - name: ATLANTIS_GITLAB_TOKEN
          valueFrom:
            secretKeyRef:
              name: atlantis-vcs
              key: token
        - name: ATLANTIS_GITLAB_WEBHOOK_SECRET
          valueFrom:
            secretKeyRef:
              name: atlantis-vcs
              key: webhook-secret
        ### End GitLab Config ###

        ### Bitbucket Config ###
        - name: ATLANTIS_BITBUCKET_USER
          value: <YOUR_BITBUCKET_USER> # 5i. If you're using Bitbucket replace <YOUR_BITBUCKET_USER> with the username of your Atlantis Bitbucket user without the `@`.
        - name: ATLANTIS_BITBUCKET_TOKEN
          valueFrom:
            secretKeyRef:
              name: atlantis-vcs
              key: token
        ### End Bitbucket Config ###

        ### Azure DevOps Config ###
        - name: ATLANTIS_AZUREDEVOPS_USER
          value: <YOUR_AZUREDEVOPS_USER> # 6i. If you're using Azure DevOps replace <YOUR_AZUREDEVOPS_USER> with the username of your Atlantis Azure DevOps user without the `@`.
        - name: ATLANTIS_AZUREDEVOPS_TOKEN
          valueFrom:
            secretKeyRef:
              name: atlantis-vcs
              key: token
        - name: ATLANTIS_AZUREDEVOPS_WEBHOOK_USER
          valueFrom:
            secretKeyRef:
              name: atlantis-vcs
              key: basic-user
        - name: ATLANTIS_AZUREDEVOPS_WEBHOOK_PASSWORD
          valueFrom:
            secretKeyRef:
              name: atlantis-vcs
              key: basic-password
        ### End Azure DevOps Config ###

        - name: ATLANTIS_DATA_DIR
          value: /atlantis
        - name: ATLANTIS_PORT
          value: "4141" # Kubernetes sets an ATLANTIS_PORT variable so we need to override.
        volumeMounts:
        - name: atlantis-data
          mountPath: /atlantis
        ports:
        - name: atlantis
          containerPort: 4141
        resources:
          requests:
            memory: 256Mi
            cpu: 100m
          limits:
            memory: 256Mi
            cpu: 100m
        livenessProbe:
          # We only need to check every 60s since Atlantis is not a
          # high-throughput service.
          periodSeconds: 60
          httpGet:
            path: /healthz
            port: 4141
            # If using https, change this to HTTPS
            scheme: HTTP
        readinessProbe:
          periodSeconds: 60
          httpGet:
            path: /healthz
            port: 4141
            # If using https, change this to HTTPS
            scheme: HTTP
  volumeClaimTemplates:
  - metadata:
      name: atlantis-data
    spec:
      accessModes: ["ReadWriteOnce"] # Volume should not be shared by multiple nodes.
      resources:
        requests:
          # The biggest thing Atlantis stores is the Git repo when it checks it out.
          # It deletes the repo after the pull request is merged.
          storage: 5Gi
サンプルの Service
service.yaml
apiVersion: v1
kind: Service
metadata:
  name: atlantis
spec:
  type: ClusterIP
  ports:
  - name: atlantis
    port: 80
    targetPort: 4141
  selector:
    app: atlantis
Futa HirakobaFuta Hirakoba

GITHUB_USERの指定

  • <YOUR_GITHUB_USER>を書き換える。
    • korosuke613
  • ユーザ名から@を抜く。
  • ATLANTIS_GITLAB_*ATLANTIS_BITBUCKET_*ATLANTIS_AZUREDEVOPS_*の環境変数をすべて削除する
Futa HirakobaFuta Hirakoba

リポジトリのホワイトリスト追加

忘れてた。実行できるリポジトリを自分のリポジトリに制限する。
*でやるのちょっとって感じがするけど一旦これでいく

value: github.com/yourorg/*value: github.com/korosuke613/*に。

Futa HirakobaFuta Hirakoba

デプロイ

できるか!?

❯ kubectl apply -f service.yaml -f statefulset.yaml
service/atlantis created
statefulset.apps/atlantis created

ストレージ5GB使い切って草。

statefulset.yaml の .volumeClaimTemplates
  volumeClaimTemplates:
    - metadata:
        name: atlantis-data
      spec:
        accessModes: ["ReadWriteOnce"] # Volume should not be shared by multiple nodes.
        resources:
          requests:
            # The biggest thing Atlantis stores is the Git repo when it checks it out.
            # It deletes the repo after the pull request is merged.
            storage: 5Gi

毎回削除するらしいから5Giもいらない説ある?まあこのまま進めてみる

Futa HirakobaFuta Hirakoba

Webhook設定

https://www.runatlantis.io/docs/configuring-webhooks.html#github-github-enterprise

Orgで設定しろって言われてるけど今自分のアカウント上で使おうとしてるからそれできねえ笑
リポジトリのWebhookでもできるだろうか

Futa HirakobaFuta Hirakoba

korosuke613/atlantis-example に Webhook 追加

  • Payload URL: https://hogehoge/events
  • Content type: application/json
  • Let me select individual events
    • Pull request reviews
    • Pushes
    • Issue comments
    • Pull requests
Futa HirakobaFuta Hirakoba

色々めも

良かったこと

  • k8sで運用するのは割と簡単
  • Webhookはシークレットがかかっているので GitHub <-> Atlantis 間の通信は安心
  • plan結果いい感じで出るし楽
  • なんか設定が豊富
  • セキュリティの話もある

懸念

  • BotユーザもしくはGitHub Appを作る必要がある
    • Botは色々あるのでGitHub Appを作ればいい。個人だとめんどいかも?
  • プルリク作られるだけでplanしてしまう。コメントでapplyできてしまう
    • パブリックリポジトリでは使えない(それはそう)
    • ユーザ制限はできる?
  • GitHubがWebhook飛ばすためのパブリックなURLが必要
    • サービスを表に出さないといけない
  • GUI上から Apply の有効無効ができてしまう。GUI上から Lock の解除ができてしまう。GUI上からプルリクのタイトルが見えてしまう
    • 設定でオフにできる?
    • もしくはIP制限できる?
      • これはデプロイする側で制限すれば良い。kubernetesでそれできるんだっけ?
      • GitHubのWebhookはIPアドレスレンジを公開してる
    • BASIC認証なら可能

その他

  • レプリカ数2にして実行したけどボリューム分かれてるからもちろん別podにつながったら死んだ。
    • ていうかTerraformの性質上複数Podでの運用はそもそも間違ってるだろうな。Atlantisのロックの仕組み機能しなくなるし。

Futa HirakobaFuta Hirakoba

なんとなく調査できたので次は会社のOrgでAppも作ったりネットワーク考えたりしてやってみるかな〜
このスクラップはClose

Futa HirakobaFuta Hirakoba

参考情報

Terraform を自動実行したいなら Atlantis - Qiita

https://qiita.com/chroju/items/f77e8391d6ef7c7cb59a

  • 色々書いてくれてる
  • applyの実行に条件をつけられる
  • conftestによるチェックもできる
  • required_versionを読んでくれる

tfmigrate + Atlantis でTerraformリファクタリング機能をCI/CDに組み込む - Qiita

https://qiita.com/minamijoyo/items/36d89cab4cd9f26fc098

  • GitHubのWebhookはIPアドレスレンジを公開してるので、これと社内ネットワークからのアクセスのみ許可するのはあり
  • apply 後に自動でマージするautomergeは使えそう。
  • 設定のカテゴリの話も
  • tfmigrateの組み込み方も
このスクラップは2021/12/25にクローズされました