0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Amazon EKSでExternal Secretsを利用する

Last updated at Posted at 2022-10-24

はじめに

Amazon EKSでExternal Secretsを利用する方法をまとめます。
External Secretsは、AWS Secrets Managerに登録された秘匿情報をAmazon EKSのSecretに同期させるKubernetesオペレーターです。

※2021/11/03に非推奨化となりました。

Mac環境を想定しています。

実行環境の準備

  1. AWS CLIの設定
    AWS CloudFormationを動かすためのAWS CLIの設定を参考にしてください。

  2. EKSクラスタの構築
    Macでeksctlを利用してAmazon EKSのクラスターを構築するを参考にしてください。

  3. EKSのコンテキストの設定
    MacにてAmazon EKSの設定をするを参考にしてください。

  4. Helmの設定
    Amazon EKSでHelmを利用するを参考にしてください。

  5. ArgoCDの設定
    Amazon EKSでArgoCDを利用するを参考にしてください。

Secrets Managerの作成

  1. Secrets Managerを作成する
    ※今回は akane/private-password という名前にする
    aws secretsmanager create-secret \
      --name akane/private-password \
      --secret-string XXXXXXXX
    

IAM OIDC IDプロバイダの作成

クラスター用の IAM OIDC プロバイダーの作成を参考にしてください。

  1. クラスター名を設定する

    CLUSTER_NAME=${クラスター名}
    
  2. IDプロバイダを作成する

    eksctl utils associate-iam-oidc-provider \
      --cluster ${CLUSTER_NAME} \
      --approve
    
  3. 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 \
      )
    )
    
  4. 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ロールの作成

  1. 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}"
    
  2. ポリシーを作成する
    ※今回はポリシー名を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}"
    
  3. ポリシーをロールにアタッチする

    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のインストールが必要です。

  1. external-secrets.yamlを作成する
    ※targetRevisionは0.6.0としていますが、最新バージョンはExternal Secretsで確認してください。
    ※IAMロールのARNを設定します。

    external-secrets.yaml
    apiVersion: 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
    
    
  2. クラスターに適用する

    kubectl apply -f external-secrets.yaml
    

Secretを作成する

※今回はakaneというNamespaceでSecretを作成します。

  1. akane-namespace.yaml を作成する

    akane-namespace.yaml
    kind: Namespace
    apiVersion: v1
    metadata:
      name: akane
      labels:
        name: akane
    
  2. akane-secrets.yaml を作成する
    ※remoteRef.keyにSecrets Managerのシークレット名を記載します。
    ※今回は akane/private-password という名前です。

    akane-secrets.yaml
    apiVersion: 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
    
  3. クラスターに適用する

    kubectl apply -f akane-namespace.yaml
    kubectl apply -f akane-secrets.yaml
    

Secretを確認する

  1. Secretの内容を取得する

    kubectl get secret -n akane akane-secret -o yaml
    

    ※下記のようなdataが表示されると思います。

    data:
      private-password: WFhYWFhYWFg=
    
  2. base64でデコードする
    ※Secrets Managerに登録したXXXXXXXXが表示されます。

    echo "WFhYWFhYWFg=" | base64 -D
    

クリーンアップ

  1. クラスターから削除する

    kubectl delete -f akane-secrets.yaml
    kubectl delete -f akane-namespace.yaml
    kubectl delete -f external-secrets.yaml
    
  2. ポリシーをロールからデタッチする

    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
    
  3. ポリシーを削除する

    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
    
  4. IAMロールを削除する

    aws iam delete-role \
      --role-name akane-dev-external-secrets-role
    
  5. Secrets Managerを削除する

    aws secretsmanager delete-secret \
      --secret-id akane/private-password \
      --force-delete-without-recovery
    
  6. IAM OIDC IDを削除する
    eksctl delete clusterを実行するとクラスターと一緒に削除されます。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?