Skip to content

Commit

Permalink
update: Various Secrets Manager language fixes (#1159)
Browse files Browse the repository at this point in the history
  • Loading branch information
niallthomson authored Oct 28, 2024
1 parent 93ca612 commit ecfe834
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 50 deletions.
1 change: 0 additions & 1 deletion docs/authoring_content.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ When creating your content you will want to test the commands you specify agains
Many of the convenience scripts we'll use will make calls to AWS APIs so will need to be able to authenticate. Getting AWS credentials in to a container in a portable way can be a challenge, and there are several options available:

1. Set `ASSUME_ROLE` environment variable in the terminal where you run the `make` commands to the ARN of an IAM role that you can assume with your current credentials. This will use the STS service to generate temporary credentials that will be injected in to the container. Example: `export ASSUME_ROLE='arn:aws:iam::1234567890:role/my-role'`
1. Set `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` environment variables in the terminal where you run the `make` commands. It is recommended that these credentials be temporary. These variables will be injected in to the container.
1. If you are developing on an EC2 instance which has an instance profile that provides the necessary IAM permissions then no action is needed as the container will automatically assume the role of the EC2 on which you're authoring your content.

Expand Down
16 changes: 8 additions & 8 deletions website/docs/security/secrets-management/secrets-manager/ascp.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ title: "AWS Secrets and Configuration Provider (ASCP)"
sidebar_position: 422
---

When we ran the `prepare-environment` script detailed in a [previous step](./index.md), it has already installed the AWS Secrets and Configuration Provider (ASCP) for the Kubernetes Secrets Store CSI Driver that's required for this lab.
The `prepare-environment` script we ran in the [previous step](./index.md) has already installed the AWS Secrets and Configuration Provider (ASCP) for the Kubernetes Secrets Store CSI Driver required for this lab.

Lets then, validate if the addons deployed.
Let's validate that the addons were deployed correctly.

Check the Secret Store CSI drive `DaemonSet` and respective `Pods`.
First, check the Secret Store CSI driver `DaemonSet` and its `Pods`:

```bash
$ kubectl -n secrets-store-csi-driver get pods,daemonsets -l app=secrets-store-csi-driver
Expand All @@ -20,7 +20,7 @@ pod/csi-secrets-store-secrets-store-csi-driver-k7m6c 3/3 Running 0
pod/csi-secrets-store-secrets-store-csi-driver-x2rs4 3/3 Running 0 3m57s
```

Check the CSI Secrets Store Provider for AWS driver `DaemonSet` and respective `Pods`.
Next, check the CSI Secrets Store Provider for AWS driver `DaemonSet` and its `Pods`:

```bash
$ kubectl -n kube-system get pods,daemonset -l "app=secrets-store-csi-driver-provider-aws"
Expand All @@ -33,20 +33,20 @@ pod/secrets-store-csi-driver-provider-aws-djtf5 1/1 Running 0 2
pod/secrets-store-csi-driver-provider-aws-dzg9r 1/1 Running 0 2m2s
```

In order to provide access to your secrets stored in AWS Secrets Manager via CSI driver, you'll need a _SecretProviderClass_, which is a namespaced custom resource that's used provide driver configurations and specific parameters that match the information in AWS Secrets Manager.
To provide access to secrets stored in AWS Secrets Manager via the CSI driver, you'll need a _SecretProviderClass_ - a namespaced custom resource that provides driver configurations and specific parameters matching the information in AWS Secrets Manager.

```file
manifests/modules/security/secrets-manager/secret-provider-class.yaml
```

In the above resource, we have two main configurations that we should be focusing. So go ahead and create the resource to explore those specifications.
Let's create this resource and examine its two main configuration sections:

```bash
$ cat ~/environment/eks-workshop/modules/security/secrets-manager/secret-provider-class.yaml \
| envsubst | kubectl apply -f -
```

The _objects_ parameter, which is pointing to a secret named as `eks-workshop/catalog-secret` that we will store in AWS Secrets Manager in the next step. Note that we are using [jmesPath](https://jmespath.org/), to extract a specific key-value from the secret that is JSON-formatted.
First, the _objects_ parameter points to a secret named `eks-workshop/catalog-secret` that we'll store in AWS Secrets Manager in the next step. Note that we're using [jmesPath](https://jmespath.org/) to extract specific key-value pairs from the JSON-formatted secret:

```bash
$ kubectl get secretproviderclass -n catalog catalog-spc -o yaml | yq '.spec.parameters.objects'
Expand All @@ -60,7 +60,7 @@ $ kubectl get secretproviderclass -n catalog catalog-spc -o yaml | yq '.spec.par
objectAlias: password
```

And the _secretObjects_, that will create and/or sync a Kubernetes secret with the data from the secret stored in AWS Secrets Manager. This means that when mounted to a Pod, the SecretProviderClass, will create a Kubernetes Secret, if it doesn't exist yet, and sync the values stored in AWS Secrets Manager with this Kubernetes Secret, in our case, it is named `catalog-secret`.
Second, the _secretObjects_ section defines how to create and sync a Kubernetes secret with data from the AWS Secrets Manager secret. When mounted to a Pod, the SecretProviderClass will create a Kubernetes Secret (if it doesn't exist) named `catalog-secret` and sync the values from AWS Secrets Manager:

```bash
$ kubectl get secretproviderclass -n catalog catalog-spc -o yaml | yq '.spec.secretObjects'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: "Storing secrets in AWS Secrets Manager"
sidebar_position: 421
---

First, we need to store a secret in AWS Secrets Manager, lets do that using the AWS CLI:
Let's begin by creating a secret in AWS Secrets Manager using the AWS CLI. We'll create a secret that contains JSON-encoded credentials with username and password values:

```bash
$ export SECRET_SUFFIX=$(openssl rand -hex 4)
Expand All @@ -17,9 +17,7 @@ $ aws secretsmanager create-secret --name "$SECRET_NAME" \
}
```

The command above is storing a secret with a JSON encoded key/value content, for `username` and `password` credentials.

Validate the new stored secret in the [AWS Secrets Manager Console](https://console.aws.amazon.com/secretsmanager/listsecrets) or using this command:
You can verify that the secret was created successfully by checking either the [AWS Secrets Manager Console](https://console.aws.amazon.com/secretsmanager/listsecrets) or using the AWS CLI. Let's use the CLI to examine the secret's metadata:

```bash
$ aws secretsmanager describe-secret --secret-id "$SECRET_NAME"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: "External Secrets Operator"
sidebar_position: 424
---

Now we can explore integrating with Secrets Managed using the External Secrets operator. This has already been installed in our EKS cluster:
Now let's explore integrating with AWS Secrets Manager using the External Secrets operator. This has already been installed in our EKS cluster:

```bash
$ kubectl -n external-secrets get pods
Expand All @@ -17,14 +17,14 @@ default 0 7m
external-secrets-sa 0 7m
```

As we can see theres a ServiceAccount named `external-secrets-sa` which is tied to an IAM role via [IRSA](../../iam-roles-for-service-accounts/), with access to AWS Secrets Manager for retrieving secrets information.
The operator uses a ServiceAccount named `external-secrets-sa` which is tied to an IAM role via [IRSA](../../iam-roles-for-service-accounts/), providing access to AWS Secrets Manager for retrieving secrets:

```bash
$ kubectl -n external-secrets describe sa external-secrets-sa | grep Annotations
Annotations: eks.amazonaws.com/role-arn: arn:aws:iam::1234567890:role/eks-workshop-external-secrets-sa-irsa
```

In addition to that, we'll need to create a new cluster resource called `ClusterSecretStore` which is a cluster-wide SecretStore that can be referenced by all ExternalSecrets from all namespaces.
We need to create a `ClusterSecretStore` resource - this is a cluster-wide SecretStore that can be referenced by ExternalSecrets from any namespace:

```file
manifests/modules/security/secrets-manager/cluster-secret-store.yaml
Expand All @@ -35,7 +35,7 @@ $ cat ~/environment/eks-workshop/modules/security/secrets-manager/cluster-secret
| envsubst | kubectl apply -f -
```

Take a deeper look at this newly created resources specifications.
Let's examine the specifications of this newly created resource:

```bash
$ kubectl get clustersecretstores.external-secrets.io
Expand All @@ -54,9 +54,9 @@ provider:

```

You can see here, that it's using a [JSON Web Token (jwt)](https://jwt.io/), referenced to the ServiceAccount we just checked, to sync with AWS Secrets Manager.
The ClusterSecretStore uses a [JSON Web Token (JWT)](https://jwt.io/) referenced to our ServiceAccount to authenticate with AWS Secrets Manager.

Let's move forward and create an `ExternalSecret` that describes what data should be fetched from AWS Secrets Manager, how the data should be transformed and saved as a Kubernetes Secret. Then we can patch our `catalog` Deployment to use the External Secret as source for the credentials.
Next, we'll create an `ExternalSecret` that defines what data should be fetched from AWS Secrets Manager and how it should be transformed into a Kubernetes Secret. We'll then update our `catalog` Deployment to use these credentials:

```kustomization
modules/security/secrets-manager/external-secrets/kustomization.yaml
Expand All @@ -70,15 +70,15 @@ $ kubectl kustomize ~/environment/eks-workshop/modules/security/secrets-manager/
$ kubectl rollout status -n catalog deployment/catalog --timeout=120s
```

Check the newly created `ExternalSecret` resource.
Let's examine our new `ExternalSecret` resource:

```bash
$ kubectl -n catalog get externalsecrets.external-secrets.io
NAME STORE REFRESH INTERVAL STATUS READY
catalog-external-secret cluster-secret-store 1h SecretSynced True
```

Verify that the resource has a `SecretSynced` status, which means that it was successfully synchronized from AWS Secrets Manager. Let's take a closer look to this resources specifications.
The `SecretSynced` status indicates successful synchronization from AWS Secrets Manager. Let's look at the resource specifications:

```bash
$ kubectl -n catalog get externalsecrets.external-secrets.io catalog-external-secret -o yaml | yq '.spec'
Expand All @@ -96,9 +96,9 @@ target:
deletionPolicy: Retain
```

Notice the `key` and the `secretStoreRef` parameters pointing to the secret we stored on AWS Secrets Manager, and the `ClusterSecretStore` previously created. Also the `refreshInterval` is set to 1 hours which means that the value from this secret will be checked and refreshed every hour.
The configuration references our AWS Secrets Manager secret via the `key` parameter and the `ClusterSecretStore` we created earlier. The `refreshInterval` of 1 hour determines how often the secret values are synchronized.

But how do we use this ExternalSecret in our Pods? After we create this resource it automatically created a Kubernetes secret with the same name in the namespace.
When we create an ExternalSecret, it automatically creates a corresponding Kubernetes secret:

```bash
$ kubectl -n catalog get secrets
Expand All @@ -108,7 +108,7 @@ catalog-external-secret Opaque 2 1m
catalog-secret Opaque 2 5h40m
```

Take a deeper look in this secret.
This secret is owned by the External Secrets Operator:

```bash
$ kubectl -n catalog get secret catalog-external-secret -o yaml | yq '.metadata.ownerReferences'
Expand All @@ -120,9 +120,7 @@ $ kubectl -n catalog get secret catalog-external-secret -o yaml | yq '.metadata.
uid: b8710001-366c-44c2-8e8d-462d85b1b8d7
```

See that it has an `ownerReference` that points to External Secrets Operator.

Now check that the `catalog` pod is already updated with the values from this new secret, and it's up and running!
We can verify our `catalog` pod is using the new secret values:

```bash
$ kubectl -n catalog get pods
Expand All @@ -144,6 +142,6 @@ $ kubectl -n catalog get deployment catalog -o yaml | yq '.spec.template.spec.co

### Conclusion

In conclusion there is no best option on choosing between **AWS Secrets and Configuration Provider (ASCP)** vs. **External Secrets Operator (ESO)** in order to manage your secrets stored on **AWS Secrets Manager**.
There is no single "best" choice between **AWS Secrets and Configuration Provider (ASCP)** and **External Secrets Operator (ESO)** for managing AWS Secrets Manager secrets.

Both tools have their specific advantages, for example, ASCP can help you avoid exposing secrets as environment variables, mounting them as volumes directly from AWS Secrets Manager into a Pod, the drawback is the need to manage those volumes. In the other hand ESO makes easier the Kubernetes Secrets lifecycle management, having also a cluster wide SecretStore, however it doesn't allow you to use Secrets as volumes. It all depends on your use case, and having both can bring you a lot more flexibility and security with Secrets Management.
Each tool has distinct advantages. ASCP can mount secrets directly from AWS Secrets Manager as volumes, avoiding exposure as environment variables, though this requires volume management. ESO simplifies Kubernetes Secrets lifecycle management and offers cluster-wide SecretStore capability, but doesn't support volume mounting. Your specific use case should drive the decision, and using both tools can provide maximum flexibility and security in secrets management.
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ You can view the Terraform that applies these changes [here](https://github.com/

:::

[AWS Secrets Manager](https://aws.amazon.com/secrets-manager/) allows you to easily rotate, manage, and retrieve sensitive data such as credentials, API keys, certificates, among others. You can use [AWS Secrets and Configuration Provider (ASCP)](https://github.com/aws/secrets-store-csi-driver-provider-aws) for [Kubernetes Secrets Store CSI Driver](https://secrets-store-csi-driver.sigs.k8s.io/) to mount secrets stored in Secrets Manager as volumes in Kubernetes Pods.
[AWS Secrets Manager](https://aws.amazon.com/secrets-manager/) is a service that enables you to easily rotate, manage, and retrieve sensitive data including credentials, API keys, and certificates. Using the [AWS Secrets and Configuration Provider (ASCP)](https://github.com/aws/secrets-store-csi-driver-provider-aws) with the [Kubernetes Secrets Store CSI Driver](https://secrets-store-csi-driver.sigs.k8s.io/), you can mount secrets stored in Secrets Manager as volumes in Kubernetes Pods.

With the ASCP, you can store and manage your secrets in Secrets Manager and then retrieve them through your workloads running on Amazon EKS. You can use IAM roles and policies to limit access to your secrets to specific Kubernetes Pods in a cluster. The ASCP retrieves the Pod identity and exchanges the identity for an IAM role. ASCP assumes the IAM role of the Pod, and then it can retrieve secrets from Secrets Manager that are authorized for that role.
ASCP allows workloads running on Amazon EKS to access secrets stored in Secrets Manager through fine-grained access control using IAM roles and policies. When a Pod requests access to a secret, ASCP retrieves the Pod's identity, exchanges it for an IAM role, assumes that role, and then retrieves only the secrets authorized for that role from Secrets Manager.

Another way to integrate AWS Secrets Manager with Kubernetes Secrets, is through [External Secrets](https://external-secrets.io/). External Secrets is an operator that can integrate and synchronize secrets from AWS Secrets Manager reading the information from it and automatically injecting the values into a Kubernetes Secret with an abstraction that stores and manages the lifecycle of the secrets for you.
An alternative approach for integrating AWS Secrets Manager with Kubernetes is through [External Secrets](https://external-secrets.io/). This operator synchronizes secrets from AWS Secrets Manager into Kubernetes Secrets, managing the entire lifecycle through an abstraction layer. It automatically injects values from Secrets Manager into Kubernetes Secrets.

If you use Secrets Manager automatic rotation for your secrets, you can rely on External Secrets refresh interval or use the Secrets Store CSI Driver rotation reconciler feature to ensure you are retrieving the latest secret from Secrets Manager, depending on the tool you choose to manage secrets inside your Amazon EKS Cluster.
Both approaches support automatic secret rotation through Secrets Manager. When using External Secrets, you can configure a refresh interval to poll for updates, while the Secrets Store CSI Driver provides a rotation reconciler feature to ensure Pods always have the latest secret values.

In this lab following section, we will create a couple of example scenarios of using secrets from AWS Secrets Manager and External Secrets.
In the following sections, we'll explore practical examples of managing secrets using both AWS Secrets Manager with ASCP and External Secrets.
Loading

0 comments on commit ecfe834

Please sign in to comment.