とことんDevOps | 日本仮想化技術のDevOps技術情報メディア

DevOpsに関連する技術情報を幅広く提供していきます。

日本仮想化技術がお届けする「とことんDevOps」では、DevOpsに関する技術情報や、日々のDevOps業務の中での検証結果、TipsなどDevOpsのお役立ち情報をお届けします。
主なテーマ: DevOps、CI/CD、コンテナ開発、IaCなど
読者登録と各種SNSのフォローもよろしくお願いいたします。

GitHub ActionsからAWS EKSにデプロイする

第12回 とことんDevOps勉強会で、デプロイまでのActionsがみたいという内容の質問をいただいていたので、実際にAWS EKSにデプロイするところまでのActionsを作成してみます。

devops-blog.virtualtech.jp

CIOpsとGitOps

(ざっくりと)CIの中からデプロイすることをCIOpsといいます。弊社のブログでもいくつか記事が上がっていました。

devops-blog.virtualtech.jp

devops-blog.virtualtech.jp

CIOpsのメリットは、ツールが増えないことや、全てCIの中でやってしまうので構成シンプルという点です。一方デメリットは、CIの中でデプロイなどを行うのでCIに強い権限を持たせる必要があります。

GitOpsのメリットは、GitOpsツールがデプロイを行うのでCIには最低限の権限があればよくなります。CIにテスト以外の設定が混ざらないのでCIの設定がシンプルになります。CIとCDの棲み分けができるためDevとOpsで責任範囲の分担が可能です。

今回はCIの中からEKSにデプロイするのでCIOpsを利用します。

じゅんび

必要なコードを準備しました。

github.com

.
├── .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.yamlappディレクトリ以下のファイルに更新があった時に発火。コンテナイメージのビルドからプッシュまでを行います。
deploy.yamlmanifestディレクトリ以下のファイルに更新があった時に発火してEKSにデプロイします。
つまり、app以下のファイルを更新してアプリケーションコンテナのイメージのビルドまでを行い、ビルドされたイメージタグでmanifestの更新を行うことでデプロイが発火します。

こちらはdeploy.yamlの中です。

gist.github.com

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の設定を行います。設定内容については以下の記事をご覧ください。

devops-blog.virtualtech.jp

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されました。

Package github-ciops · GitHub

マニフェストを更新してみます。 orgpkgnameは環境に合わせて修正しましょう。

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を推奨します。

devops-blog.virtualtech.jp