GitOpsを進める中でSecretの管理にExternal Secrets Operatorを採用したので導入手順を簡単に書いていきます。
※実際のコードから一部抜粋しています
IaC: Pulumi (TypeScript)
k8s構成管理: Kustomize
k8s Cluster: GKE Autopilot ※Standardの場合はクラスターの設定が別途必要に見える
https://external-secrets.io/v0.9.0/introduction/getting-started/
https://external-secrets.io/latest/provider/google-secrets-manager/
1. Pulumi で Workload Identity の設定
pulumi.ts
import * as pulumi from '@pulumi/pulumi';
import * as gcp from '@pulumi/gcp';
const externalSecretsNamespaceName = 'external-secrets';
const gcpSaName = 'external-secrets';
const gcpSaEmail = `${gcpSaName}@${gcpProject}.iam.gserviceaccount.com`;
const k8sSaName = 'external-secrets';
// IAM サービス アカウントを作成
const gcpSa = new gcp.serviceaccount.Account(`${gcpSaName}-sa`, {
accountId: gcpSaName,
displayName: gcpSaName,
project: gcpProject,
});
// IAM サービス アカウントにロールを付与
const gcpSaSecretManagerBinding = new gcp.projects.IAMBinding(
`${gcpSaName}-iam-binding`,
{
members: [pulumi.interpolate`serviceAccount:${gcpSaEmail}`],
role: 'roles/secretmanager.secretAccessor',
project: gcpProject,
},
{ dependsOn: [gcpSa] }
);
// Kubernetes サービス アカウントが IAM サービス アカウントの権限を借用できるようにする
const k8sSaAndGcpSaWorkloadIdentityUserBinding =
new gcp.serviceaccount.IAMBinding(
'external-secrets-workload-identity-iam-binding',
{
serviceAccountId: gcpSa.name,
role: 'roles/iam.workloadIdentityUser',
members: [
pulumi.interpolate`serviceAccount:${gcpProject}.svc.id.goog[${externalSecretsNamespaceName}/${k8sSaName}]`,
],
},
{ dependsOn: [gcpSa] }
);
2. External Secrets Operatorをインストール
External Secrets Operator用のnamespace
namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: external-secrets
今回はhelmを使います
$ kustomize build kustomization-dir/pass --enable-helm | kubectl apply -f -
kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- namespace.yaml
helmCharts:
- name: external-secrets
repo: https://charts.external-secrets.io
version: v0.9.0
namespace: external-secrets
3. ServiceAccount & ClusterSecretStore
external-secrets-operator.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: external-secrets
namespace: external-secrets
annotations:
iam.gke.io/gcp-service-account: example@example-project.iam.gserviceaccount.com
---
apiVersion: external-secrets.io/v1beta1
kind: ClusterSecretStore
metadata:
name: gcp-cluster-secret-store
spec:
provider:
gcpsm:
projectID: example-project
auth:
workloadIdentity:
clusterLocation: asia-northeast1
clusterName: example-cluster
serviceAccountRef:
name: external-secrets
namespace: external-secrets
4. ExternalSecretでSecretを作成
あとはSecret Managerに登録してあるシークレットを使ってk8s Secretを生成するだけです
secret.yaml
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: example-es
spec:
secretStoreRef:
kind: ClusterSecretStore
name: gcp-cluster-secret-store
target:
name: example
creationPolicy: Owner
dataFrom:
- extract:
key: sm-key