EKSをTerraformで構築するチュートリアルを作ってみた

この記事を書いたメンバー:

緑川京太

EKSをTerraformで構築するチュートリアルを作ってみた

目次


技術顧問室の緑川です。

半年ほど自身でEKSを運用していく中で、どこまでをTerraform管理にするか、どういったコンポーネントに分割すると運用・変更しやすいのかといった答えが一旦出たので、チュートリアル資料としてまとめてみました。

このチュートリアルでは、EKSクラスタをTerraformで構築し、サンプルのサービスとしてKeycloakをデプロイし、ALBで公開するところまでを行います。


ソースコード

チュートリアルのソースコードはこちらです。このチュートリアルはvscodeのDevcontainerを起動して実施する前提となっています。

チュートリアル自体の内容は以下のリポジトリに任せて、この記事では構成や実際に出来上がるものを見せたいと思います。


GitHub - ng3rdstmadgke/terraform-tutorial-eks

Contribute to ng3rdstmadgke/terraform-tutorial-eks development by creating an account on GitHub.

github.com

og_img

設計

普段Terraformを実装するときは一発ですべてのリソースが出来上がるように実装するのですが、EKSはネットワーク, EKSクラスタ, ノードグループ, アドオン, Helmチャート, アプリケーションなど、様々なライフサイクル(生存期間)の要素で構成され、それらがKubernetesという仕組みを介して複雑に結合しているため、依存関係の問題で不整合が頻繁に発生します。

当初は一発ですべてのリソースが出来上がるような設計でTerraformを実装しましたが、運用中たびたび発生する不整合があまりにも辛かったので、今回のチュートリアルではリソースをライフサイクルごとに分類し、ライフサイクルが近いリソースをコンポーネントにまとめ、独立して変更・デプロイできるようにしました。

今回作成するリソースをライフサイクル毎のレイヤーで整理すると下記のようになります。

注目してほしいのは、上のレイヤーになるほど頻繁に変更される点で、レイヤーごとににリソースの生存期間が異なります。コンポーネントはこの生存期間を意識して分割していきます。


ライフサイクルが近いリソースをまとめて下記のコンポーネントに分類しました。

コンポーネント要素
baseいろいろなコンポーネントで利用される共通変数など
networkVPC, サブネットなど
clusterEKSクラスタ
node-groupEKSのノードグループ, 起動テンプレートなど
addonEKSのアドオン
pluginhelmでインストールするチャートに付随するリソース
serviceEKSにデプロイするサービスに付随するリソース

これらのコンポーネントを循環依存がないように依存関係を構築していきます。

サンプルコードのデプロイ手順

前準備

cd sample/

tfstateを保存するs3バケットの作成

TFSTATE_BUCKET="tfstateの保存先バケット"

aws s3api create-bucket \
  --bucket $TFSTATE_BUCKET \
  --region ap-northeast-1 \
  --create-bucket-configuration LocationConstraint=ap-northeast-1

tfvarsファイルに tfstateの保存先バケットを設置

sample/terraform/components/tfvars/common.tfvars

tfstate_region = "ap-northeast-1"
# tfstateの保存先バケット
tfstate_bucket = "tfstateの保存先バケット"

sample/terraform/components/tfvars/backend.tfvars

region         = "ap-northeast-1"
# tfstateの保存先バケット
bucket         = "tfstateの保存先バケット"
# tfstateのロック
use_lockfile  = true
# tfstateの暗号化
encrypt = true

プロジェクト名とステージの定義

# プロジェクト名
PROJECT_NAME=sample
# ステージ名
STAGE=dev

baseコンポーネントのデプロイ

共通変数などを定義します。

# trerraformのデプロイ
make tf-plan PROJECT_NAME=$PROJECT_NAME STAGE=$STAGE COMPONENT=base
make tf-apply PROJECT_NAME=$PROJECT_NAME STAGE=$STAGE COMPONENT=base

networkコンポーネントのデプロイ

eksを構築するvpcとサブネットを構築します。

# trerraformのデプロイ
make tf-plan PROJECT_NAME=$PROJECT_NAME STAGE=$STAGE COMPONENT=network
make tf-apply PROJECT_NAME=$PROJECT_NAME STAGE=$STAGE COMPONENT=network

clusterコンポーネントのデプロイ

eksクラスタを作成します。

# trerraformのデプロイ
make tf-plan PROJECT_NAME=$PROJECT_NAME STAGE=$STAGE COMPONENT=cluster
make tf-apply PROJECT_NAME=$PROJECT_NAME STAGE=$STAGE COMPONENT=cluster

# クラスタ名を変数として控えておく
CLUSTER_COMPONENT_DIR=$PROJECT_DIR/sample/terraform/components/cluster
CLUSTER_NAME=$(terraform -chdir=$CLUSTER_COMPONENT_DIR output -raw cluster_name)
aws eks update-kubeconfig --name $CLUSTER_NAME

node-groupコンポーネントのデプロイ

node-groupとその周辺リソースを作成します。

make tf-plan PROJECT_NAME=$PROJECT_NAME STAGE=$STAGE COMPONENT=node-group
make tf-apply PROJECT_NAME=$PROJECT_NAME STAGE=$STAGE COMPONENT=node-group

addonコンポーネントのデプロイ

Pod Identity AgentやEBS CSI Driverなどのアドオンをインストールします。

make tf-plan PROJECT_NAME=$PROJECT_NAME STAGE=$STAGE COMPONENT=addon
make tf-apply PROJECT_NAME=$PROJECT_NAME STAGE=$STAGE COMPONENT=addon

pluginコンポーネントのデプロイ

AWS Load Balancer Controllerや Secrets Store CSI Driverなど、Helmでインストールするプラグインに必要なAWSリソースを作成します。

make tf-plan PROJECT_NAME=$PROJECT_NAME STAGE=$STAGE COMPONENT=plugin
make tf-apply PROJECT_NAME=$PROJECT_NAME STAGE=$STAGE COMPONENT=plugin

metrics-serverをHelmでインストール

# リポジトリ追加
helm repo add metrics-server https://kubernetes-sigs.github.io/metrics-server/

# リポジトリのアップデート
helm repo update metrics-server

# インストール
helm upgrade --install metrics-server metrics-server/metrics-server \
  --version "3.12.2" \
  --namespace "kube-system" \
  --create-namespace

AWS Load Balancer ControllerをHelmでインストール

# リポジトリ追加
helm repo add eks https://aws.github.io/eks-charts

# リポジトリのアップデート
helm repo update eks

# インストール
helm upgrade --install aws-load-balancer-controller eks/aws-load-balancer-controller \
  --version "1.11.0" \
  --namespace "kube-system" \
  --create-namespace \
  --values $PROJECT_DIR/sample/plugin/albc/tmp/values.yaml

Secrets Store CSI DriverをHelmでインストール

# リポジトリ追加
helm repo add secrets-store-csi-driver https://kubernetes-sigs.github.io/secrets-store-csi-driver/charts

# リポジトリのアップデート
helm repo update

# インストール
helm upgrade --install csi-secrets-store secrets-store-csi-driver/secrets-store-csi-driver \
  --version "1.4.7" \
  --namespace kube-system \
  --create-namespace \
  --set "syncSecret.enabled=true" \
  --set "enableSecretRotation=true"

ASCP (aws secrets store csi provider)をHelmでインストール

# リポジトリ追加
helm repo add aws-secrets-manager https://aws.github.io/secrets-store-csi-driver-provider-aws

# リポジトリのアップデート
helm repo update

# インストール
helm upgrade --install secrets-provider-aws aws-secrets-manager/secrets-store-csi-driver-provider-aws \
  --version "0.3.10" \
  --namespace kube-system \
  --create-namespace

serviceコンポーネントのデプロイ

keycloakに必要なAWSリソース(RDS, SecretsManagerなど)をデプロイします。

make tf-plan PROJECT_NAME=$PROJECT_NAME STAGE=$STAGE COMPONENT=service
make tf-apply PROJECT_NAME=$PROJECT_NAME STAGE=$STAGE COMPONENT=service

keycloakをEKSにデプロイします。

kubectl apply -f $PROJECT_DIR/sample/service/keycloak/tmp/app.yaml

keycloakはデフォルトでhttpでログインできないので、ログインできるように設定します。

# k9sでkeycloak コンテナのshellを起動
k9s

keycloakコンテナのshellでsslRequired設定を無効化します。

# SecretsManager (/<app_name>/<ステージ>/keycloak) のユーザー名とパスワードでログイン
/opt/keycloak/bin/kcadm.sh config credentials \
    --server http://localhost:8080 \
    --realm master \
    --user $KEYCLOAK_ADMIN \
    --password $KEYCLOAK_ADMIN_PASSWORD

# sslRequiredを無効化
/opt/keycloak/bin/kcadm.sh update realms/master -s sslRequired=NONE

exit

動作確認

ALBのエンドポイントにブラウザでアクセスしてログインできることを確認します。

# ALBのURLを確認
kubectl -n keycloak get ing

# ログイン情報を確認
CLUSTER_NAME=$(terraform -chdir=$PROJECT_DIR/sample/terraform/components/base output -raw cluster_name)
aws secretsmanager get-secret-value --secret-id /$CLUSTER_NAME/keycloak --query "SecretString" --output text | jq "."


後片付け

keycloakの削除

kubectl delete -f $PROJECT_DIR/sample/service/keycloak/tmp/app.yaml

チャートの削除

helm uninstall -n kube-system csi-secrets-store
helm uninstall -n kube-system secrets-provider-aws
helm uninstall -n kube-system aws-load-balancer-controller
helm uninstall -n kube-system metrics-server

Terraformリソースの削除

# プロジェクト名
PROJECT_NAME=sample
# ステージ名
STAGE=dev

make tf-destroy PROJECT_NAME=$PROJECT_NAME STAGE=$STAGE COMPONENT=service && \
make tf-destroy PROJECT_NAME=$PROJECT_NAME STAGE=$STAGE COMPONENT=plugin && \
make tf-destroy PROJECT_NAME=$PROJECT_NAME STAGE=$STAGE COMPONENT=addon && \
make tf-destroy PROJECT_NAME=$PROJECT_NAME STAGE=$STAGE COMPONENT=node-group && \
make tf-destroy PROJECT_NAME=$PROJECT_NAME STAGE=$STAGE COMPONENT=cluster && \
make tf-destroy PROJECT_NAME=$PROJECT_NAME STAGE=$STAGE COMPONENT=network && \
make tf-destroy PROJECT_NAME=$PROJECT_NAME STAGE=$STAGE COMPONENT=base













カテゴリー
タグ

Pick upピックアップ

Search記事を探す

キーワード

SAPシステムや基幹システムのクラウド移行・構築・保守、
DXに関して
お気軽にご相談ください

03-6260-6240 (受付時間 平日9:30〜18:00)