cert-manager: DNS01 Challenge via AWS Route53 on AWS EKS 1.15 not working
Describe the bug: When doing Let’s Encrypt validation via Route53 running on EKS 1.15 with IRSA getting AccessDenied
E0708 12:18:28.403757 1 controller.go:143] cert-manager/controller/challenges "msg"="re-queuing item due to error processing" "error"="error instantiating route53 challenge solver: unable to assume role: AccessDenied: User: arn:aws:sts::XXXXXXXXXXXX:assumed-role/ajetstack-cert-manager/1594210708202645062 is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::XXXXXXXXXXXX:role/jetstack-cert-manager\n\tstatus code: 403, request id: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" "key"="example/example-internal.our-domain.com-4004189744-1292225756-1302369230"
Expected behaviour: Issued LE cert via DNS01 validation
Steps to reproduce the bug: Create following cluster-issuer and ingress ClusterIssuer object:
---
apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
name: r53-letsencrypt-prod
namespace: cert-manager
spec:
acme:
email: DevOpsSupport@our-domain.com
privateKeySecretRef:
name: r53-letsencrypt-prod
server: https://acme-v02.api.letsencrypt.org/directory
solvers:
- selector:
dnsZones:
- "our-domain.com"
dns01:
route53:
region: eu-central-1
role: arn:aws:iam::XXXXXXXXXXXX:role/jetstack-cert-manager
Ingress object:
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
cert-manager.io/acme-challenge-type: dns01
cert-manager.io/cluster-issuer: r53-letsencrypt-prod
kubernetes.io/ingress.class: nginx-ingress-internal
nginx.ingress.kubernetes.io/proxy-body-size: 10m
labels:
app.kubernetes.io/component: jenkins-master
app.kubernetes.io/instance: jenkins
app.kubernetes.io/managed-by: Tiller
app.kubernetes.io/name: jenkins
helm.sh/chart: jenkins-1.3.6
name: jenkins-internal
namespace: jenkins
spec:
rules:
- host: jenkins.our-domain.com
http:
paths:
- backend:
serviceName: jenkins
servicePort: 8080
tls:
- hosts:
- jenkins.our-domain.com
secretName: jenkins.our-domain.com
Anything else we need to know?: IRSA working properly, tested. Same role for R53 working good from CLI
IAM policy(veeery broad):
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Action": [
"route53:ListResourceRecordSets",
"route53:ChangeResourceRecordSets"
],
"Resource": "arn:aws:route53:::hostedzone/*"
},
{
"Sid": "",
"Effect": "Allow",
"Action": "route53:GetChange",
"Resource": "arn:aws:route53:::change/*"
},
{
"Sid": "",
"Effect": "Allow",
"Action": "route53:ListHostedZones*",
"Resource": "*"
}
]
}
EDIT Thrust relationship:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::XXXXXXXXXXXX:oidc-provider/oidc.eks.eu-central-1.amazonaws.com/id/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"oidc.eks.eu-central-1.amazonaws.com/id/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:sub": "system:serviceaccount:cert-manager:cert-manager"
}
}
}
]
}
Plus trust relationships working as needed (tested with pod)
SA object:
---
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
arn:aws:iam::XXXXXXXXXXXX:role/jetstack-cert-manager
creationTimestamp: "2020-07-08T12:12:55Z"
labels:
app: cert-manager
app.kubernetes.io/component: controller
app.kubernetes.io/instance: cert-manager
app.kubernetes.io/managed-by: Tiller
app.kubernetes.io/name: cert-manager
helm.sh/chart: cert-manager-v0.15.2
name: cert-manager
namespace: cert-manager
resourceVersion: "46367502"
selfLink: /api/v1/namespaces/cert-manager/serviceaccounts/cert-manager
uid: 45d3a11b-feaa-4b7a-a91e-146454ad770a
secrets:
- name: cert-manager-token-nfqpv
Environment details::
- Kubernetes version: v1.15.11
- Cloud-provider/provisioner: AWS EKS
- cert-manager images: deployed from quay.io official ones
- cert-manager version: v0.15.2 (did not worked on 12.x, 13.x, 14.x aswell)
- Install method: helm
- LBL: ELB Internal /kind bug
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 3
- Comments: 21 (3 by maintainers)
Commits related to this issue
- add clarity of role use for eks clusterissuer the only route53 dn01 clusterissuer example prior to this change specifies a role in each solver example, however in a single-account eks setup where the... — committed to johndietz/website by deleted user 4 years ago
- add clarity of role use for eks clusterissuer the only route53 dn01 clusterissuer example prior to this change specifies a role in each solver example, however in a single-account eks setup where the... — committed to johndietz/website by deleted user 4 years ago
- Issuer with IRSA needs ambient credentials flag This should help reduce the amount of time people might waste trying to figure out how to resolve the following error: ``` error instantiating rout... — committed to rossigee/website-1 by rossigee 3 years ago
- Issuer with IRSA needs ambient credentials flag This should help reduce the amount of time people might waste trying to figure out how to resolve the following error: ``` error instantiating rout... — committed to rossigee/website-1 by rossigee 3 years ago
I was running into the same issue, I added this to my values.yaml
It appears that by default the namespace Issuers do not allow using “ambient” credentials, this let’s them.
I got it working. I’ve described my installation procedure below. Hope can help solve your issues too @johndietz and @JanisOrlovs .
CertManager
This section describes how to install and setup cert-manager on an AWS EKS cluster. It will integrate with Route53 DNS for issuing DNS-based certificate challenges.
IAM Open ID Connect provider for the cluster
This is required for associating k8s Service Accounts with AWS IAM roles and policies. This is considered more secure than allowing the worker nodes to access AWS services (e.g. S3 Buckets, Route53 DNS, etc.).
More info about the command above can be found here.
AWS IAM Policy
Create an AWS IAM policy named AllowExternalDNSUpdates and attach the following permissions to it:
Less can probably do but the above works well if you want to use the same policy with e.g. external-dns.
Check the cert-manager docs if you wish to limit the policy to specific Route53 resources.
Create the AWS IAM Role
Create an IAM Service Account thats allowed to perform DNS updates (Route53). This is required in order to use DNS-based certificate challenges.
Attach the AllowExternalDNSUpdates policy to the role
This assumes that a policy named AllowExternalDNSUpdates already exists at arn:aws:iam::XXXXXXXXXXXX:policy/AllowExternalDNSUpdates (created in an earlier step)
Trust relationship
Assign a trust relationship to the newly created IAM role in AWS web console, allowing you to map kubernetes service accounts to AWS IAM roles. It should look something like this, with the values in <value> replaced accordingly:
You can find the value at Principal.Federated at https://console.aws.amazon.com/iam/home?region=eu-north-1#/providers (replace eu-north-1 with your region). You can extract the <aws-account-id> and <eks-hash> from that string too.
Cert manager custom values
Create a file called cert-manager.values.yaml This will cause the cert-manager ServiceAccount to be annotated with the newly created cert-manager AWS IAM role.
Note the securityContext part which is a fix if you experience the issue described in issue #2147.
Install CertManager from Helm template
Start by checking that you have the correct <aws-account-id> in cert-manager.values.yaml, then run the command below: Add the jetstack/cert-manager helm repo first if it’s not present.
ClusterIssuer
Create a ClusterIssuer which can be used to issue Lets Encrypt certificates in all namespaces.
Save the following yaml into a file called letsencrypt.clusterissuer.yaml
Apply the manifest to your cluster:
What does your ClusterIssuer look like @johndietz? I was seeing some AssumeRole errors until I removed the “role” entry from my dns01 solver.
Update: tried v0.15.2 with a
ClusterIssuerand it is working with IRSA, whereas before I was using anIssuerwith v1.0.3 and it was not.fsGroup: 1001, andrunAsUser: 1001is also set in thesecurityContextof the Helm chart.It seems that something may have broken in between releases or something w.r.t IRSA was not accurately captured in the docs.
Follow up: v1.0.3 of the helm chart is working with a
ClusterIssuerand IRSA, but the same setup with aIssuerdoes not workI’ve got the same issue as @metral with
v1.0.3of the chart: it works fine with a ClusterIssuer, but I get an error when using an Issuer.Hi,
I am seeing something similar.
Error when describing challenge resources
ClusterIssuer
Trust Relationship
Service Account
I’ve annotated the cert-manager service account as described here.
Security Context
I also tried updating the security context as described here.
Environment
kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v0.14.1/cert-manager.yamlfollowed by annotating cert-manager service account.Thanks for clarifying, @anarsen. Took a while to figure out how to force it to use the eks.amazonaws.com/role-arn: arn:aws:iam::<aws-account-id>:role/cert-manager from the annotation in stead of an assumed role.