Atlantisをk8s上に立ててどんなものか調べる
Atlantisをk8s上に立てる。
ローカルに建てて実験しない理由としてはGitHubのWebhookを受け取るためにインターネットからアクセスできる必要があるため。チュートリアルではNgrokを入れないといけないが、Ngrokは入れたくないため、インターネットからアクセス可能なServiceを簡単に作れるoktetoを利用する。
先に以下をする必要あった。
- GitHubのアクセストークン生成
- Webhookシークレット生成
Git Host Access Credentials | Atlantis
Appで作りたいところだけどとりあえずPATでいいや
-
repo
を許可 -
Expires
をとりあえず7日に設定 -
ATLANTIS_GITHUB_PAT
という名前で.envrc
に保存
Webhook Secrets | Atlantis
-
ruby -rsecurerandom -e 'puts SecureRandom.hex(32)'
で生成 -
ATLANTIS_WEBHOOK_SECRET
という名前で.envrc
に保存
デプロイしてく
Secret
を作成する
k8sリソースの例
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
作れたっぽい
マニフェスト書き換え
Deployment
とStatefulset
が提供されているが、Statefulset
が推奨されているのでそっちを使う。
サンプルの Statefulset
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
apiVersion: v1
kind: Service
metadata:
name: atlantis
spec:
type: ClusterIP
ports:
- name: atlantis
port: 80
targetPort: 4141
selector:
app: atlantis
イメージ書き換え
runatlantis/atlantis:v<VERSION>
のバージョンを入れる。
現在の最新は 0.17.6
Release v0.17.6 · runatlantis/atlantis
runatlantis/atlantis:v0.17.6
GITHUB_USER
の指定
-
<YOUR_GITHUB_USER>
を書き換える。- korosuke613
- ユーザ名から
@
を抜く。 -
ATLANTIS_GITLAB_*
、ATLANTIS_BITBUCKET_*
、ATLANTIS_AZUREDEVOPS_*
の環境変数をすべて削除する
OktetoのIngressを使う
oktetoでサービスを公開するには.metadata.annotations.dev.okteto.com/auto-ingress
を"true"
にしないといけない
リポジトリのホワイトリスト追加
忘れてた。実行できるリポジトリを自分のリポジトリに制限する。
*
でやるのちょっとって感じがするけど一旦これでいく
value: github.com/yourorg/*
をvalue: github.com/korosuke613/*
に。
デプロイ
できるか!?
❯ kubectl apply -f service.yaml -f statefulset.yaml
service/atlantis created
statefulset.apps/atlantis created
ストレージ5GB使い切って草。
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もいらない説ある?まあこのまま進めてみる
デプロイできた
認証無しで誰でも Enable/Disable 切り替えられるのいかんな笑
Webhook設定
Orgで設定しろって言われてるけど今自分のアカウント上で使おうとしてるからそれできねえ笑
リポジトリのWebhookでもできるだろうか
サンプルリポジトリをfork
runatlantis/atlantis-example: A simple terraform project to use along with atlantis bootstrap mode
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
プルリク作ってみる
Initial commit by korosuke613 · Pull Request #1 · korosuke613/atlantis-example
作った
お〜
plan結果をコメントしてくれた。
ただこれプルリク作るだけでplan実行できちゃうの考えものだな。
普通はパブリックリポジトリでやらないからしょうがないか
atlantis apply
でapply
したぞ〜
色々めも
良かったこと
- 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のロックの仕組み機能しなくなるし。
- ていうかTerraformの性質上複数Podでの運用はそもそも間違ってるだろうな。Atlantisのロックの仕組み機能しなくなるし。
最終的なプルリク
feat: Atlantis on k8s by korosuke613 · Pull Request #18 · korosuke613/playground
なんとなく調査できたので次は会社のOrgでAppも作ったりネットワーク考えたりしてやってみるかな〜
このスクラップはClose
参考情報
Terraform を自動実行したいなら Atlantis - Qiita
- 色々書いてくれてる
- applyの実行に条件をつけられる
- conftestによるチェックもできる
- required_versionを読んでくれる
tfmigrate + Atlantis でTerraformリファクタリング機能をCI/CDに組み込む - Qiita
- GitHubのWebhookはIPアドレスレンジを公開してるので、これと社内ネットワークからのアクセスのみ許可するのはあり
- apply 後に自動でマージする
automerge
は使えそう。 - 設定のカテゴリの話も
- tfmigrateの組み込み方も