From 0bf19d3ee589ae0279931ac5da368624685a9d5d Mon Sep 17 00:00:00 2001 From: Richard Wall Date: Tue, 8 Oct 2024 19:50:58 +0100 Subject: [PATCH] Format the numbered list items Signed-off-by: Richard Wall --- .../docs/configuration/acme/dns01/route53.md | 417 ++++++++++-------- 1 file changed, 228 insertions(+), 189 deletions(-) diff --git a/content/docs/configuration/acme/dns01/route53.md b/content/docs/configuration/acme/dns01/route53.md index 65d9028a2b..32109bb68d 100644 --- a/content/docs/configuration/acme/dns01/route53.md +++ b/content/docs/configuration/acme/dns01/route53.md @@ -73,24 +73,22 @@ Using an IAM Role with temporary security credentials is considered best practic 1. You do not have to store the long-term access key (e.g. in a Secret) 2. You don't have to manage [access key rotation](https://docs.aws.amazon.com/glossary/latest/reference/glos-chap.html#keyrotate). -cert-manager supports multiple ways to get the access key -and these can be categorized as either "ambient" or "non-ambient": +cert-manager supports multiple ways to get the access key and these can be categorized as either "ambient" or "non-ambient". ### Ambient Credentials -**Ambient credentials** are credentials which are made available in the cert-manager controller Pod by one of the following mechanisms: -- [EKS IAM Roles for Service Accounts (IRSA)](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html). - cert-manager uses a [Kubernetes ServiceAccount token which is mounted into the cert-manager controller Pod](https://docs.aws.amazon.com/eks/latest/userguide/pod-configuration.html). -- [EKS Pod Identity](https://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html). - cert-manager gets credentials from an [EKS Auth API which runs on every Kubernetes node](https://docs.aws.amazon.com/eks/latest/userguide/pod-id-how-it-works.html). -- [EC2 Instance Metadata Service (IMDS)](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-metadata-security-credentials.html). - cert-manager gets credentials from the `iam/security-credentials/` endpoint of IMDS. -- [Environment variables](https://docs.aws.amazon.com/sdkref/latest/guide/environment-variables.html) - (`AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`). - If those environment variables are present in the cert-manager controller Pod cert-manager will use them.. -- [Shared config and credentials files](https://docs.aws.amazon.com/sdkref/latest/guide/file-format.html) - (`~/.aws/config` and `~/.aws/credentials`). - If those files are mounted into the cert-manager controller Pod, cert-manager will use them. +Ambient credentials are credentials which are made available in the cert-manager controller Pod by one of the following mechanisms: +- [**EKS Pod Identity**](https://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html):
+ where cert-manager gets credentials from an [EKS Auth API which runs on every Kubernetes node](https://docs.aws.amazon.com/eks/latest/userguide/pod-id-how-it-works.html). +- [**EKS IAM Roles for Service Accounts (IRSA)**](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html):
+ where cert-manager uses a Kubernetes ServiceAccount token which is [mounted into the cert-manager controller Pod](https://docs.aws.amazon.com/eks/latest/userguide/pod-configuration.html). +- [**EC2 Instance Metadata Service (IMDS)**](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-metadata-security-credentials.html):
+ where cert-manager gets credentials from the `iam/security-credentials/` endpoint of IMDS. +- [**Environment variables**](https://docs.aws.amazon.com/sdkref/latest/guide/environment-variables.html):
+ where cert-manager loads credentials from `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` environment variables + in the cert-manager controller Pod, if those variables are present. +- [**Shared config and credentials files**](https://docs.aws.amazon.com/sdkref/latest/guide/file-format.html):
+ where cert-manager loads credentials from files (`~/.aws/config` and `~/.aws/credentials`) which are mounted into the cert-manager controller Pod. The advantage of ambient credentials is that they are easier to set up, well documented, and AWS provides ways to automate the configuration. @@ -130,110 +128,151 @@ spec: route53 {}: ``` -Regardless of which ambient mechanism you use, the `route53` section is left empty, because cert-manager (using the AWS SDK for Go V2) can find the credentials, role, and region by looking for environment variables which will be added to the cert-manager Pod. +> ℹ️ Regardless of which ambient mechanism you use, the `route53` section is left empty, +> because cert-manager can find the credentials, role, and region by looking for environment variables +> which will be added to the cert-manager Pod. #### EKS Pod Identity -If you deploy cert-manager on EKS, [Pod Identity](https://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html) is the simplest way to use ambient credentials. -It is a three step process: -1. [Setup the EKS Pod Identity agent](https://docs.aws.amazon.com/eks/latest/userguide/pod-id-agent-setup.html) in your cluster, then +[EKS Pod Identity](https://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html) is the simplest way to use ambient credentials, +if you deploy cert-manager on EKS. +It is a four step process: +1. [Setup the EKS Pod Identity agent](https://docs.aws.amazon.com/eks/latest/userguide/pod-id-agent-setup.html) in your cluster. 2. [Assign an IAM role to the cert-manager Kubernetes service account](https://docs.aws.amazon.com/eks/latest/userguide/pod-id-association.html). -3. Restart the cert-manager Deployment so that the EKS Pod Identity Agent can inject the necessary environment variables into the Pods. +3. Restart the cert-manager Deployment + so that the EKS Pod Identity Agent can inject the necessary environment variables into the Pods. +4. Create a `ClusterIssuer` resource: + + ```yaml + apiVersion: cert-manager.io/v1 + kind: ClusterIssuer + metadata: + name: letsencrypt-prod + spec: + acme: + ... + solvers: + - dns01: + route53 {}: + ``` #### EKS IAM Role for Service Accounts (IRSA) -If you deploy cert-manager on EKS, IAM Roles for Service Accounts (IRSA) is another way to use use ambient credentials. +IAM Roles for Service Accounts (IRSA) is another way to use ambient credentials, +if you deploy cert-manager on EKS. It is more complicated than Pod Identity and requires coordination between the Kubernetes cluster administrator and the AWS account manager. It involves annotating the `cert-manager` ServiceAccount in Kubernetes, and setting up an IAM role, a trust policy and a trust relationship in AWS. -A mutating webhook, which is configured by default on EKS, will automatically setup a mounted service account volume in the cert-manager Pod. +A mutating webhook will automatically setup a mounted service account volume in the cert-manager Pod. + +1. **Create an IAM OIDC provider for your cluster** + + To use IRSA with cert-manager you must first enable the feature for your cluster. + Follow the [official documentation](https://docs.aws.amazon.com/eks/latest/userguide/enable-iam-roles-for-service-accounts.html). + +2. **Create a trust relationship** + + In this configuration an IAM role is mapped to the cert-manager `ServiceAccount` allowing it to authenticate with AWS. + The IAM role you map to the `ServiceAccount` will need permissions on any and all Route53 zones cert-manager will be using. + Create a trust relationship by adding the following trust policy to the IAM role: + + ```json + { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": "sts:AssumeRoleWithWebIdentity", + "Principal": { + "Federated": "arn:aws:iam:::oidc-provider/oidc.eks..amazonaws.com/id/" + }, + "Condition": { + "StringEquals": { + "oidc.eks..amazonaws.com/id/:sub": "system:serviceaccount::" + } + } + } + ] + } + ``` + + Replace the following: + + - `` with the AWS account ID of the EKS cluster. + - `` with the region where the EKS cluster is located. + - `` with the hash in the EKS API URL; this will be a random 32 character hex string (example: `45DABD88EEE3A227AF0FA468BE4EF0B5`) + - `` with the namespace where cert-manager is running. + - `` with the name of the `ServiceAccount` object created by cert-manager. + + + > ℹ️ If you're following the Cross Account example, this trust policy is attached to the cert-manager role in Account X with ARN `arn:aws:iam::XXXXXXXXXXX:role/cert-manager`. + > The permissions policy is the same as above. + +3. **Annotate the cert-manager `ServiceAccount`** + + ```yaml + apiVersion: v1 + kind: ServiceAccount + metadata: + annotations: + eks.amazonaws.com/role-arn: arn:aws:iam::XXXXXXXXXXX:role/cert-manager + ``` + + The cert-manager Helm chart provides a variable for injecting annotations into cert-manager's `ServiceAccount` like so: + + ```yaml + serviceAccount: + annotations: + eks.amazonaws.com/role-arn: arn:aws:iam::XXXXXXXXXXX:role/cert-manager + ``` + + > ℹ️ If you're following the Cross Account example, modify the `ClusterIssuer` with the role from Account Y. -> ℹ️ To use IRSA with cert-manager you must first enable the feature for your cluster. You can do this by -> following the [official documentation(https://docs.aws.amazon.com/eks/latest/userguide/enable-iam-roles-for-service-accounts.html). - -1. **Create a trust relationship** - -In this configuration an IAM role is mapped to the cert-manager `ServiceAccount` allowing it to authenticate with AWS. -The IAM role you map to the `ServiceAccount` will need permissions on any and all Route53 zones cert-manager will be using. -Create a trust relationship by adding the following trust policy to the IAM role: - -```json -{ - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": "sts:AssumeRoleWithWebIdentity", - "Principal": { - "Federated": "arn:aws:iam:::oidc-provider/oidc.eks..amazonaws.com/id/" - }, - "Condition": { - "StringEquals": { - "oidc.eks..amazonaws.com/id/:sub": "system:serviceaccount::" - } - } - } - ] -} -``` - -Replace the following: - -- `` with the AWS account ID of the EKS cluster. -- `` with the region where the EKS cluster is located. -- `` with the hash in the EKS API URL; this will be a random 32 character hex string (example: `45DABD88EEE3A227AF0FA468BE4EF0B5`) -- `` with the namespace where cert-manager is running. -- `` with the name of the `ServiceAccount` object created by cert-manager. - - -> ℹ️ If you're following the Cross Account example above, this trust policy is attached to the cert-manager role in Account X with ARN `arn:aws:iam::XXXXXXXXXXX:role/cert-manager`. -> The permissions policy is the same as above. - -2. **Annotate the cert-manager `ServiceAccount`** - -```yaml -apiVersion: v1 -kind: ServiceAccount -metadata: - annotations: - eks.amazonaws.com/role-arn: arn:aws:iam::XXXXXXXXXXX:role/cert-manager -``` +3. **(optional) Update file system permissions** -The cert-manager Helm chart provides a variable for injecting annotations into cert-manager's `ServiceAccount` like so: + You may also need to modify the cert-manager `Deployment` with the correct file system permissions, so the `ServiceAccount` token can be read. -```yaml -serviceAccount: - annotations: - eks.amazonaws.com/role-arn: arn:aws:iam::XXXXXXXXXXX:role/cert-manager -``` + ```yaml + spec: + template: + spec: + securityContext: + fsGroup: 1001 + ``` -> ℹ️ If you're following the Cross Account example above, modify the `ClusterIssuer` in the same way as above with the role from Account Y. + The cert-manager Helm chart provides a variable for modifying cert-manager's `Deployment` like so: -3. **(optional) Update file system permissions** + ```yaml + securityContext: + fsGroup: 1001 + ``` -You may also need to modify the cert-manager `Deployment` with the correct file system permissions, so the `ServiceAccount` token can be read. +4. **Restart the cert-manager Deployment** -```yaml -spec: - template: - spec: - securityContext: - fsGroup: 1001 -``` + Restart the cert-manager Deployment, so that the webhook can inject the + necessary `volume`, `volumemount`, and environment variables into the Pods. -The cert-manager Helm chart provides a variable for modifying cert-manager's `Deployment` like so: +5. **Create a `ClusterIssuer` resource** -```yaml -securityContext: - fsGroup: 1001 -``` + ```yaml + apiVersion: cert-manager.io/v1 + kind: ClusterIssuer + metadata: + name: letsencrypt-prod + spec: + acme: + ... + solvers: + - dns01: + route53 {}: + ``` ### Non-ambient Credentials -**Non-ambient credentials** are credentials which are explicitly configured on the Issuer or ClusterIssuer resource. +Non-ambient credentials are credentials which are explicitly configured on the Issuer or ClusterIssuer resource. For example: -- *Access key Secret reference*: +- **Access key Secret reference**:
where cert-manager loads a long-term access key from a Kubernetes Secret resource. -- *ServiceAccount reference*: +- **ServiceAccount reference**:
where cert-manager gets a ServiceAccount token (signed JWT) from the Kubernetes API server, and uses the STS AssumeRoleWithWebIdentity endpoint to exchange it for temporary AWS credentials. @@ -250,109 +289,109 @@ such that each `ServiceAccount` is mapped to an IAM role that only has permissio 1. **Create a ServiceAccount** -In order to reference a `ServiceAccount` it must first exist. -Unlike normal IRSA the `eks.amazonaws.com/role-arn` annotation is not required. + In order to reference a `ServiceAccount` it must first exist. + Unlike normal IRSA the `eks.amazonaws.com/role-arn` annotation is not required. -```yaml -apiVersion: v1 -kind: ServiceAccount -metadata: - name: -``` + ```yaml + apiVersion: v1 + kind: ServiceAccount + metadata: + name: + ``` 2. **Create an IAM role trust policy** -For every `ServiceAccount` you want to use for AWS authentication you must first set up a trust policy: - -```json -{ - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": "sts:AssumeRoleWithWebIdentity", - "Principal": { - "Federated": "arn:aws:iam:::oidc-provider/oidc.eks..amazonaws.com/id/" - }, - "Condition": { - "StringEquals": { - "oidc.eks..amazonaws.com/id/:sub": "system:serviceaccount::" - } - } - } - ] -} -``` - -Replace the following: - -- `` with the AWS account ID of the EKS cluster. -- `` with the region where the EKS cluster is located. -- `` with the hash in the EKS API URL; this will be a random 32 character hex string (example: `45DABD88EEE3A227AF0FA468BE4EF0B5`) -- `` with the namespace of the `ServiceAccount` object. -- `` with the name of the `ServiceAccount` object. + For every `ServiceAccount` you want to use for AWS authentication you must first set up a trust policy: + + ```json + { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": "sts:AssumeRoleWithWebIdentity", + "Principal": { + "Federated": "arn:aws:iam:::oidc-provider/oidc.eks..amazonaws.com/id/" + }, + "Condition": { + "StringEquals": { + "oidc.eks..amazonaws.com/id/:sub": "system:serviceaccount::" + } + } + } + ] + } + ``` + + Replace the following: + + - `` with the AWS account ID of the EKS cluster. + - `` with the region where the EKS cluster is located. + - `` with the hash in the EKS API URL; this will be a random 32 character hex string (example: `45DABD88EEE3A227AF0FA468BE4EF0B5`) + - `` with the namespace of the `ServiceAccount` object. + - `` with the name of the `ServiceAccount` object. 3. **Create an RBAC Role and RoleBinding** -In order to allow cert-manager to issue a token using your `ServiceAccount` you must deploy some RBAC to the cluster: - -```yaml -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - name: -tokenrequest - namespace: -rules: - - apiGroups: [''] - resources: ['serviceaccounts/token'] - resourceNames: [''] - verbs: ['create'] ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - name: cert-manager--tokenrequest - namespace: -subjects: - - kind: ServiceAccount - name: - namespace: -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: -tokenrequest -``` - -Replace the following: - -- `` name of the `ServiceAccount` object. -- `` namespace of the `ServiceAccount` object. -- `` name of cert-managers `ServiceAccount` object, as created during cert-manager installation. -- `` namespace that cert-manager is deployed into. + In order to allow cert-manager to issue a token using your `ServiceAccount` you must deploy some RBAC to the cluster: + + ```yaml + apiVersion: rbac.authorization.k8s.io/v1 + kind: Role + metadata: + name: -tokenrequest + namespace: + rules: + - apiGroups: [''] + resources: ['serviceaccounts/token'] + resourceNames: [''] + verbs: ['create'] + --- + apiVersion: rbac.authorization.k8s.io/v1 + kind: RoleBinding + metadata: + name: cert-manager--tokenrequest + namespace: + subjects: + - kind: ServiceAccount + name: + namespace: + roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: -tokenrequest + ``` + + Replace the following: + + - `` name of the `ServiceAccount` object. + - `` namespace of the `ServiceAccount` object. + - `` name of cert-managers `ServiceAccount` object, as created during cert-manager installation. + - `` namespace that cert-manager is deployed into. 4. **Create an Issuer or ClusterIssuer** -You should be ready at this point to configure an Issuer to use the new `ServiceAccount`. -You can see example config for this below: - -```yaml -apiVersion: cert-manager.io/v1 -kind: Issuer -metadata: - name: example -spec: - acme: - ... - solvers: - - dns01: - route53: - region: us-east-1 - role: # This must be set so cert-manager what role to attempt to authenticate with - auth: - kubernetes: - serviceAccountRef: - name: # The name of the service account created -``` + You should be ready at this point to configure an Issuer to use the new `ServiceAccount`. + You can see example config for this below: + + ```yaml + apiVersion: cert-manager.io/v1 + kind: Issuer + metadata: + name: example + spec: + acme: + ... + solvers: + - dns01: + route53: + region: us-east-1 + role: # This must be set so cert-manager what role to attempt to authenticate with + auth: + kubernetes: + serviceAccountRef: + name: # The name of the service account created + ``` #### Referencing a long-term access key within in an Issuer or ClusterIssuer