第12回 とことんDevOps勉強会で、デプロイまでのActionsがみたいという内容の質問をいただいていたので、実際にAWS EKSにデプロイするところまでのActionsを作成してみます。
CIOpsとGitOps
(ざっくりと)CIの中からデプロイすることをCIOpsといいます。弊社のブログでもいくつか記事が上がっていました。
CIOpsのメリットは、ツールが増えないことや、全てCIの中でやってしまうので構成シンプルという点です。一方デメリットは、CIの中でデプロイなどを行うのでCIに強い権限を持たせる必要があります。
GitOpsのメリットは、GitOpsツールがデプロイを行うのでCIには最低限の権限があればよくなります。CIにテスト以外の設定が混ざらないのでCIの設定がシンプルになります。CIとCDの棲み分けができるためDevとOpsで責任範囲の分担が可能です。
今回はCIの中からEKSにデプロイするのでCIOpsを利用します。
じゅんび
必要なコードを準備しました。
.
├── .github
│ └── workflows
│ ├── build-and-push.yaml
│ └── deploy.yaml
├── .gitignore
├── .tool-versions
├── README.md
├── app
│ ├── Dockerfile
│ └── index.html
├── cluster.yaml
├── manifest
│ ├── deployment.yaml
│ ├── kustomization.yaml
│ └── service.yaml
└── terraform
├── .terraform.lock.hcl
├── main.tf
├── outputs.tf
└── versions.tf
6 directories, 15 files
.github以下はActionsです。
build-and-push.yamlはappディレクトリ以下のファイルに更新があった時に発火。コンテナイメージのビルドからプッシュまでを行います。
deploy.yamlはmanifestディレクトリ以下のファイルに更新があった時に発火してEKSにデプロイします。
つまり、app以下のファイルを更新してアプリケーションコンテナのイメージのビルドまでを行い、ビルドされたイメージタグでmanifestの更新を行うことでデプロイが発火します。
こちらはdeploy.yamlの中です。
21行目でkubectlコマンドをインストールし、30行目でkubectl apply -k manifestしています。
23行目でAWSへの認証を通して、28行目でKUBECONFIGの値を生成しています。
.tool-versionsと同じディレクトリでasdf installすると必要なツールがインストールされます。もし、別の方法で用意する場合は以下のツールをインストールしてください。
- aws-cli
- eksctl
- gh
- kubectl
- terraform
awsコマンドで操作対象のAWSに接続できているか確認します。
aws sts get-caller-identity
cluster.yamlにEKSを起動するための設定が書かれているので確認しましょう。
設定に問題がなければEKSクラスターを用意します。
eksctl create cluster -f cluster.yaml
少し時間がかかります。
GitHub ActionsからAWSを操作できるようOIDCの設定を行います。設定内容については以下の記事をご覧ください。
OIDCの設定をするためterraformディレクトリ以下に移動します。
cd terraform
Terraformを初期化します。
terraform init
実行計画を確認します。
terraform plan
どんなリソースが作成されるか出力されるので、問題ないか確認しましょう。
問題なければリソースを作成します。
terraform apply
GitHub Actionsで使う変数を設定します。
cluster.yamlの値を変更していなければpocを、クラスター名を変更している場合はその名前を入力してください。
gh variable set cluster_name
以下の作業はterraformディレクトリ内で作業します。
terraform output -raw role | gh variable set assume_role
terraform output -raw region | gh variable set aws_region
eksctl create iamidentitymapping --cluster poc --arn $(terraform output -raw role) --group system:masters --username admin
デプロイしてみる
それではデプロイしてみましょう。
まずはコンテナイメージのビルドが必要です。appディレクトリにあるindex.htmlの修正してみます。
diff --git a/app/index.html b/app/index.html
index c2917a3..0858716 100644
--- a/app/index.html
+++ b/app/index.html
@@ -3,7 +3,7 @@
</head>
<body>
<h1>
- <font color="green">
+ <font color="red">
RED
</font>
</h1>
この変更をcommit & pushでGitHubに送ってやると……

GitHub Container RegistryにPushされました。

マニフェストを更新してみます。
orgとpkgnameは環境に合わせて修正しましょう。
org=virtualtech-devops pkgname=github-ciops pkgid=$(gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" /orgs/$org/packages/container/$pkgname/versions -q '.[0].id') tag=$(gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" /orgs/$org/packages/container/$pkgname/versions/$pkgid -q '.metadata.container.tags[] | select(.!="latest")') kubectl create deployment app --image ghcr.io/$org/$pkgname:$tag -r 1 --dry-run=client -o yaml > manifest/deployment.yaml
タグが更新されました。
diff --git a/manifest/deployment.yaml b/manifest/deployment.yaml
index 03803f9..b4b3b38 100644
--- a/manifest/deployment.yaml
+++ b/manifest/deployment.yaml
@@ -18,7 +18,7 @@ spec:
app: app
spec:
containers:
- - image: ghcr.io/virtualtech-devops/github-ciops:894d24b
+ - image: ghcr.io/virtualtech-devops/github-ciops:0e90650
name: github-ciops
resources: {}
status: {}
この変更をまたまたcommit & pushでGitHubに送ってやります。

今度はデプロイが動きました。
とりあえず今回は環境を用意するのが目的ではないので、適当にPort forwardでアクセスしちゃいます。
kubectl port-forward services/app 3000:80
http://localhost:3000にアクセスすると文字の色が変化したのがわかります。

↓↓↓

まとめ
CIの設定を見ればどうやってデプロイしてるのかっというのがみやすくなり構成の理解は進むのですが、CIの中でAWSへの接続設定やKUBECONFIGの準備、kubectlのインストールまでを行う必要がありCIの設定自体は複雑になります。Argo CDなどのツールを使ってCDはCDツールに任せるというのも一つの手です。個人的にはGitOpsを推奨します。
