はじめに
Amazon EKSでExternal Secretsを利用する方法をまとめます。
External Secretsは、AWS Secrets Managerに登録された秘匿情報をAmazon EKSのSecretに同期させるKubernetesオペレーターです。
※2021/11/03に非推奨化となりました。
Mac環境を想定しています。
実行環境の準備
-
AWS CLIの設定
AWS CloudFormationを動かすためのAWS CLIの設定を参考にしてください。 -
EKSクラスタの構築
Macでeksctlを利用してAmazon EKSのクラスターを構築するを参考にしてください。 -
EKSのコンテキストの設定
MacにてAmazon EKSの設定をするを参考にしてください。 -
Helmの設定
Amazon EKSでHelmを利用するを参考にしてください。 -
ArgoCDの設定
Amazon EKSでArgoCDを利用するを参考にしてください。
Secrets Managerの作成
- Secrets Managerを作成する
※今回はakane/private-password
という名前にするaws secretsmanager create-secret \ --name akane/private-password \ --secret-string XXXXXXXX
IAM OIDC IDプロバイダの作成
クラスター用の IAM OIDC プロバイダーの作成を参考にしてください。
-
クラスター名を設定する
CLUSTER_NAME=${クラスター名}
-
IDプロバイダを作成する
eksctl utils associate-iam-oidc-provider \ --cluster ${CLUSTER_NAME} \ --approve
-
IDプロバイダのARNを取得する
OIDC_ARN=$(aws iam list-open-id-connect-providers \ --query "OpenIDConnectProviderList[*].Arn" \ --output text \ | grep $( \ aws eks describe-cluster \ --name ${CLUSTER_NAME} \ --query "cluster.identity.oidc.issuer" \ --output text \ | cut -d '/' -f 5 \ ) )
-
IDプロバイダ名を取得する
OIDC_NAME=$(aws iam get-open-id-connect-provider \ --query "Url" \ --output text \ --open-id-connect-provider-arn \ $( \ aws iam list-open-id-connect-providers \ --query "OpenIDConnectProviderList[*].Arn" \ --output text \ | grep $( \ aws eks describe-cluster \ --name ${CLUSTER_NAME} \ --query "cluster.identity.oidc.issuer" \ --output text \ | cut -d '/' -f 5 \ ) \ ) )
IAMロールの作成
-
IAMロールを作成する
※今回はロール名をakane-dev-external-secrets-role
にしています。ROLE_POLICY=$(echo -n '{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "'; echo -n "${OIDC_ARN}"; echo -n '" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "'; echo -n "${OIDC_NAME}"; echo -n ':sub": "system:serviceaccount:default:external-secrets" } } } ] }') aws iam create-role \ --role-name akane-dev-external-secrets-role \ --assume-role-policy-document "${ROLE_POLICY}"
-
ポリシーを作成する
※今回はポリシー名をakane-dev-external-secrets-policy
にしています。
※今回はSecrets Managerのプレフィクスはakane
にしています。export ACCOUNT_ID=$(aws sts get-caller-identity --output text --query Account) POLICY=$(echo -n '{ "Version": "2012-10-17", "Statement": [ { "Effect" : "Allow", "Action" : [ "secretsmanager:GetSecretValue", "secretsmanager:DescribeSecret" ], "Resource" : [ "arn:aws:secretsmanager:ap-northeast-1:'; echo -n "${ACCOUNT_ID}"; echo -n ':secret:akane/*" ] } ] }') aws iam create-policy \ --policy-name akane-dev-external-secrets-policy \ --policy-document "${POLICY}"
-
ポリシーをロールにアタッチする
export ACCOUNT_ID=$(aws sts get-caller-identity --output text --query Account) aws iam attach-role-policy \ --role-name akane-dev-external-secrets-role \ --policy-arn arn:aws:iam::${ACCOUNT_ID}:policy/akane-dev-external-secrets-policy
環境設定
※事前にKubernetesクラスターのコンテキストの設定をします。
※ArgoCDのインストールが必要です。
-
external-secrets.yaml
を作成する
※targetRevisionは0.6.0
としていますが、最新バージョンはExternal Secretsで確認してください。
※IAMロールのARNを設定します。external-secrets.yamlapiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: external-secrets namespace: argocd finalizers: - resources-finalizer.argocd.argoproj.io spec: project: default source: repoURL: 'https://charts.external-secrets.io' targetRevision: 0.6.0 helm: values: | serviceAccount: name: "external-secrets" env: AWS_REGION: "ap-northeast-1" parameters: - name: serviceAccount.annotations.eks\.amazonaws\.com/role-arn value: "${IAMロールのARN}" chart: external-secrets destination: server: 'https://kubernetes.default.svc' namespace: default syncPolicy: automated: prune: true
-
クラスターに適用する
kubectl apply -f external-secrets.yaml
Secretを作成する
※今回はakane
というNamespaceでSecretを作成します。
-
akane-namespace.yaml
を作成するakane-namespace.yamlkind: Namespace apiVersion: v1 metadata: name: akane labels: name: akane
-
akane-secrets.yaml
を作成する
※remoteRef.keyにSecrets Managerのシークレット名を記載します。
※今回はakane/private-password
という名前です。akane-secrets.yamlapiVersion: external-secrets.io/v1beta1 kind: SecretStore metadata: name: akane namespace: akane spec: provider: aws: service: SecretsManager region: ap-northeast-1 --- apiVersion: external-secrets.io/v1beta1 kind: ExternalSecret metadata: name: akane-secret namespace: akane spec: refreshInterval: 1m secretStoreRef: name: akane kind: SecretStore target: name: akane-secret creationPolicy: Owner data: - secretKey: private-password remoteRef: key: akane/private-password
-
クラスターに適用する
kubectl apply -f akane-namespace.yaml kubectl apply -f akane-secrets.yaml
Secretを確認する
-
Secretの内容を取得する
kubectl get secret -n akane akane-secret -o yaml
※下記のようなdataが表示されると思います。
data: private-password: WFhYWFhYWFg=
-
base64でデコードする
※Secrets Managerに登録したXXXXXXXX
が表示されます。echo "WFhYWFhYWFg=" | base64 -D
クリーンアップ
-
クラスターから削除する
kubectl delete -f akane-secrets.yaml kubectl delete -f akane-namespace.yaml kubectl delete -f external-secrets.yaml
-
ポリシーをロールからデタッチする
export ACCOUNT_ID=$(aws sts get-caller-identity --output text --query Account) aws iam detach-role-policy \ --role-name akane-dev-external-secrets-role \ --policy-arn arn:aws:iam::${ACCOUNT_ID}:policy/akane-dev-external-secrets-policy
-
ポリシーを削除する
export ACCOUNT_ID=$(aws sts get-caller-identity --output text --query Account) aws iam delete-policy \ --policy-arn arn:aws:iam::${ACCOUNT_ID}:policy/akane-dev-external-secrets-policy
-
IAMロールを削除する
aws iam delete-role \ --role-name akane-dev-external-secrets-role
-
Secrets Managerを削除する
aws secretsmanager delete-secret \ --secret-id akane/private-password \ --force-delete-without-recovery
-
IAM OIDC IDを削除する
eksctl delete cluster
を実行するとクラスターと一緒に削除されます。