Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add external secrets profile with crs kustomization reference #202

Merged
merged 25 commits into from
Dec 15, 2022
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions charts/external-secrets/Chart.lock
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
dependencies:
- name: external-secrets
repository: https://charts.external-secrets.io
version: 0.5.9
digest: sha256:6ec7657d0db83a993b18d1dc29de4f847a9c6f94fb9fb26ea9a5c8ffdd406543
generated: "2022-08-06T00:03:28.220828462Z"
version: 0.6.1
digest: sha256:8cca4f790ab275f82a8bd0a28de14ac780e1fa13871aa692cf77cc05cfee6d53
generated: "2022-12-04T22:34:55.732501451+02:00"
12 changes: 3 additions & 9 deletions charts/external-secrets/Chart.yaml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
apiVersion: v2
name: external-secrets
icon: https://raw.githubusercontent.com/external-secrets/external-secrets/main/assets/round_eso_logo.png
icon: https://raw.githubusercontent.com/external-secrets/external-secrets/main/assets/eso-round-logo.svg
description: A Weaveworks Helm chart for the External Secrets Operator
type: application
version: 0.0.6
version: 0.6.1
dependencies:
- name: external-secrets
version: "0.5.9"
version: "0.6.1"
repository: "https://charts.external-secrets.io"
kubeVersion: ">=1.16.0-0"
home: https://github.com/weaveworks/profiles-catalog
Expand All @@ -16,9 +16,6 @@ sources:
keywords:
- external-secrets
- secrets-manager
- parameter-store
- azure-key-vault
- vault

maintainers:
- name: Weaveworks
Expand All @@ -34,6 +31,3 @@ annotations:
url: https://charts.external-secrets.io
- name: Upstream Project
url: https://github.com/external-secrets/external-secrets
"weave.works/profile-ci": |
- "gke"
- "kind"
234 changes: 234 additions & 0 deletions charts/external-secrets/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
# External Secrets Profile Installation Guide

**Table Of Contents**
- [External Secrets Profile Installation Guide](#external-secrets-profile-installation-guide)
- [Introduction](#introduction)
- [Components](#components)
- [Controller](#controller)
- [Custom Resource Definitions (CRDs)](#custom-resource-definitions-crds)
- [SecretStore](#secretstore)
- [ExternalSecret](#externalsecret)
- [Note](#note)
- [CRs](#crs)
- [Profile Components](#profile-components)
- [How to install with WGE on Kubernetes Cluster](#how-to-install-with-wge-on-kubernetes-cluster)
- [Bootstrapping leaf cluster](#bootstrapping-leaf-cluster)
- [Notes on the creating the leaf cluster](#notes-on-the-creating-the-leaf-cluster)
- [Create Service Account on AWS](#create-service-account-on-aws)

## Introduction

External Secrets Operator is a Kubernetes operator that integrates external secret management systems like AWS Secrets Manager, HashiCorp Vault, Google Secrets Manager, Azure Key Vault and many more. The operator reads information from external APIs and automatically injects the values into a Kubernetes Secret.
For more information refer to the docs [here](https://external-secrets.io/v0.6.1/)

## Components

The External Secrets operator consists of 3 main parts as the following

### Controller

The External Secrets Operator extends Kubernetes with Custom Resources, which define where secrets live and how to synchronize them. The controller fetches secrets from an external API and creates Kubernetes secrets. If the secret from the external API changes, the controller will reconcile the state in the cluster and update the secrets accordingly.

### Custom Resource Definitions (CRDs)

The operator needs 2 predefined CRDs to be installed on the cluster to be able to operate.

#### SecretStore

The idea behind the SecretStore resource is to separate concerns of authentication/access and the actual Secret and configuration needed for workloads

#### ExternalSecret

An ExternalSecret declares what data to fetch. It has a reference to a SecretStore which knows how to access that data. The controller uses that ExternalSecret as a blueprint to create secrets.

#### Note

The previous CRDs are namespaced, There is also a global, cluster-wide SecretStore that can be referenced from all namespaces. You can use it to provide a central gateway to your secret provider which are (ClusterSecretStore, ClusterExternalSecret)

### CRs

In order to use the operator you will need to define the SecretStore and the ExternalSecret(s) you will use. You can define one or more and add them to a GitRepository. Then a Kustomization will reference them to be installed on the cluster

## Profile Components

1- [The HelmChart for External Secrets Operator](Chart.yaml)

2- [Kustomization Reference to secret stores CRs](templates/secret-stores-kustomization.yaml)


## How to install with WGE on Kubernetes Cluster

- Create namespace for external secrets

```bash
kubectl create ns external-secrets
```

- Create AWS secret for authenticating the store to be installed on the managment cluster


```bash
kubectl create secret generic awssm-secret --from-literal access-key=$KEY --from-literal secret-access-key=$SECRET -n flux-system
```

**Note**: In AWS provided clusters we can use service account/pod identity instead of key/value creds. [here](https://external-secrets.io/v0.6.1/provider/aws-secrets-manager/)

- Git token to access the private repository of secrets

```bash
kubectl create secret -n external-secrets generic ssh-creds --from-file=./identity --from-file=./identity.pub --from-file=./known_hosts
```

- Edit values file to the secret ref and path in values.yaml for your secrets repository

### Bootstrapping leaf cluster

- To authenticate the secret store on a leaf cluster with key/secret creds you will need to create a [ClusterResourceSet](https://docs.gitops.weave.works/docs/cluster-management/getting-started/#automatically-install-a-cni-with-clusterresourcesets) having the AWS secret and it will be on the leaf cluster through the [bootstrapping process](https://docs.gitops.weave.works/docs/cluster-management/getting-started/#add-a-cluster-bootstrap-config)

```bash
kubectl create secret generic aws-sm-crs-secret --from-literal access-key=$KEY --from-literal secret-access-key=$SECRET --type=addons.cluster.x-k8s.io/resource-set
```

- Cluster Resource secret to be bootstrapped in the leaf cluster under bootstrap. Make sure to add the cluster selector label `secretmanager: aws` under GitOpsCluster in the cluster template

```yaml
apiVersion: addons.cluster.x-k8s.io/v1alpha3
kind: ClusterResourceSet
metadata:
name: awssm-crs
namespace: default
spec:
clusterSelector:
matchLabels:
secretmanager: aws
resources:
- kind: Secret
name: aws-sm-crs-secret
```


- To add the ssh creds to flux to be able to access private repository you will need to create a [ClusterResourceSet](https://docs.gitops.weave.works/docs/cluster-management/getting-started/#automatically-install-a-cni-with-clusterresourcesets) having the SSH Creds and it will be on the leaf cluster through the [bootstrapping process](https://docs.gitops.weave.works/docs/cluster-management/getting-started/#add-a-cluster-bootstrap-config)

```bash
kubectl create secret generic ssh-creds-crs-secret --from-file=./identity --from-file=./identity.pub --from-file=./known_hosts --type=addons.cluster.x-k8s.io/resource-set
```

- Cluster Resource secret to be bootstrapped in the leaf cluster under bootstrap

```yaml
apiVersion: addons.cluster.x-k8s.io/v1alpha3
kind: ClusterResourceSet
metadata:
name: ssh-creds
namespace: default
spec:
clusterSelector:
matchLabels:
secretmanager: aws
resources:
- kind: Secret
name: ssh-creds-crs-secret
```

### Notes on the creating the leaf cluster

- It should have flux bootstrapped on it. using cluster bootstrap config and it should have labels matching the cluster template.

- ClusterResourceSet has cluster selector labels to choose which cluster to be installed on and it should have labels matching the cluster template.

Full guide to bootstrap leaf cluster with flux with template [here](https://www.notion.so/weaveworks/Guide-How-To-Secrets-Management-with-flux-ad91b52e3ba5415c97e2235ae394bf4f)


## Create Service Account on AWS

1- Create IAM Policy on AWS console for secrets managment

**Example**

```json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"secretsmanager:GetResourcePolicy",
"secretsmanager:GetSecretValue",
"secretsmanager:DescribeSecret",
"secretsmanager:ListSecretVersionIds"
],
"Resource": [
"arn:aws:secretsmanager:<region>:<account-id>:secret:<secret-path>"
]
}
]
}
```

**Note**: secret path could be something like `/dev/*`

2- Add Identity Provider on AWS console with the URL of the cluster OIDC

Get cluster OIDC from:

```bash
aws eks describe-cluster --name <cluster-name --query "cluster.identity.oidc.issuer" --output text --region <cluster-region>
```

Also Add audience to `sts.amazonaws.com`

3- Add Role on AWS console with the following Trust Relationship and attach the previous policy

```json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::<account-id>:oidc-provider/oidc.eks.<region>.amazonaws.com/id/<cluster-oidc-id>" # aws-arn
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"oidc.eks.<region>.amazonaws.com/id/<cluster-oidc-id>:aud": "sts.amazonaws.com",
"oidc.eks.<region>.amazonaws.com/id/<cluster-oidc-id>:sub": "system:serviceaccount:<service-account-namespace>:<service-account-name>"
}
}
}
]
}
```

4- Add Service Account Resource next to the secret store

**Example Service Account**

```yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: <service-account-name>
namespace: <service-account-namespace>
annotations:
eks.amazonaws.com/role-arn: "arn:aws:iam::<account-id>:role/<role-name>"
```

**Example Secret Store**

```yaml
apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
name: <secret-store-name>
namespace: <secret-store-namespace>
spec:
provider:
aws:
service: SecretsManager
region: <aws-region>
auth:
jwt:
serviceAccountRef:
name: <service-account-name>
```
45 changes: 45 additions & 0 deletions charts/external-secrets/templates/secret-stores-kustomization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{{- if .Values.secretStores.enabled }}
{{- if not .Values.secretStores.sourceRef }}
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: GitRepository
metadata:
name: external-secrets
namespace: external-secrets
spec:
interval: 10s
url: {{ .Values.secretStores.url }}
{{- if or .Values.secretStores.tag .Values.secretStores.branch }}
ref:
{{- if .Values.secretStores.tag }}
tag: {{ .Values.secretStores.tag }}
{{- end }}
{{- if .Values.secretStores.branch }}
branch: {{ .Values.secretStores.branch }}
{{- end }}
{{- end }}
{{- if .Values.secretStores.secretRef }}
secretRef:
name: {{ .Values.secretStores.secretRef }}
{{- end }}
{{- end }}
---
apiVersion: kustomize.toolkit.fluxcd.io/v1beta1
kind: Kustomization
metadata:
name: external-secrets
namespace: external-secrets
spec:
interval: 10m0s
{{- if not .Values.secretStores.sourceRef }}
sourceRef:
kind: GitRepository
name: external-secrets
namespace: external-secrets
{{- else }}
sourceRef:
{{- toYaml .Values.secretStores.sourceRef | nindent 4 }}
{{- end }}
path: {{ .Values.secretStores.path }}
prune: true
validation: client
{{- end }}
12 changes: 12 additions & 0 deletions charts/external-secrets/values.yaml
Original file line number Diff line number Diff line change
@@ -1,2 +1,14 @@
external-secrets:
installCRDs: true

secretStores:
enabled: true
url: ssh://git@github.com/weaveworks/secret-stores # url for the git repository that contains the SecretStores
# tag: v1.0.0 # if you would like to download your secrets from specific tag
branch: main # if you would like to download your secrets from specific branch
path: ./clusters/secrets/management/ # could be a path to the secrets dir or a kustomization.yaml file for the SecretStore in the GitRepository
secretRef: ssh-creds # Name of the K8s secret with private repo auth credentials (private key, pub key, known hosts)
# sourceRef: # Could specify a name for an existing GitSource reference instead of creating a new one
# kind: GitRepository
# name: external-secrets
# namespace: external-secrets