-
Notifications
You must be signed in to change notification settings - Fork 2.6k
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
AWS cross account access with OIDC provider in EKS & externalDNS not working #1608
Comments
yes, I have run into the exact same issue. all roles are correctly configured for cross-account trust; however, the external-dns operators fails to assume the trusting role. |
A short update on this: we also tested it with the latest release with the same error messages. Can anyone tell me if this is a bug or we are doing something wrong? For me it looks like a bug but maybe I am mistaken. And if it is a bug, I will of course file a bug report. THX for any hint on this because it is preventing us from using externalDNS. Which would be very helpful if we could use it in our Setup. |
I would be interested in how ALB ingress controller handles this. We can probably do the same here. |
@linki the ALB basically has the same IAM setup. The difference between the ALB ingress controller and externalDNS is that externalDNS needs to do a cross account access to create the DNS record. The resources the ALB creates are in the same AWS account. From the various documentations and hints I have read externalDNS can do a cross account access or can use the OIDC provider. But I never found something where people use both. That's why I think there is a problem with the combination cross account access and OIDC provider. Or we simply do not understand how to set this up. As AWS is promoting the OIDC provider for EKS more and more people will use this to authenticate a Kubernetes Cluster against AWS IAM. And I think it will be helpful for others to have a working example in the docs for this. |
Same issue here! |
Same issue here as well. Have yet to find a configuration that supports cross account hosted zones. |
I tried following https://aws.amazon.com/blogs/containers/cross-account-iam-roles-for-kubernetes-service-accounts/
And I get:
|
FYI related to #524 |
@aidan-melen THX for the info but what does this mean for us? I see this is a commit from 2018 that was merged in 2018. So for me this would mean we are doing something wrong if the AWS cross account access really works. Then I would like to know what is not correct in the described setup above? And what would be a working example? |
I was going to jump into the GO code this weekend if I have time. |
@aidan-melen ah now I see that you have committed some code for this problem. I missed your entry at the end. Thanks a lot and I hope that it will fix our problem. As I am not a programmer I am not helpful at coding but willing to test it on our setup. And I will write some documentation when it works. |
I tested it in our setup and it seems to work fine. Here's what I did. Let's assume we want to run ExternalDNS in account A managing records in account B. We want to use the IAM role in account A Head over to account B (the target account) and create the IAM role you want to assume. In the following this target IAM role is denoted with the ARN Then go back to AWS account A and annotate ExternalDNS' ServiceAccount in cluster A with:
Note, this should already be the case in your setup. Then start ExternalDNS in cluster A with:
For the IAM role for ExternalDNS in cluster A, add the permission to assume the role in account B: {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::B:role/external-dns-cross-account"
}
]
} Normally this role would have Route53 permissions to manage DNS records in account A but that wasn't needed. For the OIDC stuff to work you need to keep the Trust Relationship to the OIDC provider and the StringsEqual stuff. This should already be there and can be left unchanged. Then go to the IAM role in account B that you created at the beginning and that you want to assume. As a reminder this is denoted as ARN Give it permission to manage DNS records just like the IAM role for ExternalDNS in account A normally has, e.g.: {
"Version": "2012-10-17",
"Statement": [
{
"Action": "route53:*",
"Resource": "*",
"Effect": "Allow"
}
]
} Then add a Trust Relation to the IAM role in account A with:
Note that I removed the Trust Relationship to Note, the IAM role in account B can be a "plain" IAM role. It must have permissions to modify DNS records as well as a Trust Relationship back to account A. If you want to assume another ServiceAccount's IAM role, such as ExternalDNS' role in a different account, then the role will also have the Trust Relationship to the OIDC provider. Both cases worked fine for me. In my setup the target account has its own Kubernetes cluster with its own OIDC provider. I'm certain that this doesn't interfere with the experiment but who knows. Unfortunately, I can't delete it at the moment without causing some disruption. To summarize you basically need to:
This was tested with Let me know if that helped you or if you still get stuck. |
Thanks @linki @aidan-melen the Annotated the service account with the role on account A which grants assume role permission for the account B role which is granting route53 access. The trust policy on account B is set to the root user on account A. I didn't have to use the Federated StringsEqual part, which might not be optimal. I could probably change that over once all clusters are using OIDC but some of them aren't yet I'm leaving it as is for now.
It's working perfectly. Thanks very much. |
@linki THX for this example. I will try this next week and let you know if it succeeded. This week I am busy with other stuff. I think that I am also missing the --aws-assume-role=arn:aws:iam::B:role/external-dns-cross-account start parameter. Sounds promising. |
@linki we are facing similar issues. Trying to follow your guidance. How are you creating your IAM Roles. CLI, Terraform, or Console? We are using Terraform. Also are you on EKS non-fargate or EKS Fargate? |
IS there a way to pass External-Id for assuming the role in cross account? |
So far we had no time to test this. Hopefully a colleague of mine will have time soon to test it. |
I followed these directions to set up an identity provider and attach it to the role (following pretty much the same steps for the policy and role in the docs), and I was able to get cross-account ExternalDNS working for me. The ExternalDNS service account gets deployed with the annotation pointing to that role and it just works for us. Just needed to rollout the deployment again after making the update. |
To me it looks like the author of this issue did set up the trust relationship incorrectly. Also the error messages points out that the initial role has no permission to assume the cross-account role (which is required beside the trust relationship on the target role). |
What @linki says. That's how I do this (and did yesterday the last time) and how it's supposed to work. |
To add my 5 cents here. I have done exactly the same steps as @linki described and run into the problem anyway (access denied, cannot assume role, as above). The cause was that I have provided the role ARN to be assumed between quotation marks (e.g. --aws-assume-role="arn:aws:iam::123456789012:role/role-to-be-assumed"). So basically, there is an error in args in the comment above, which cause the problem @michazt reported. After removing the quotation masks, everything works fine. |
I closed this issue because we resolved it somehow. We could not resolve the original problem described by me here but we did the latest approach recommended by AWS described here: https://aws.amazon.com/premiumsupport/knowledge-center/amazon-eks-cluster-access/ |
Just in case anyone comes across this issue trying to do the same thing. I found a way easier way to do this. Following this guide I was able to get it to work with ODIC and without needing roles on the AWS account with the EKS Cluster. See: https://aws.amazon.com/blogs/containers/cross-account-iam-roles-for-kubernetes-service-accounts/ I have it completely working in terraform with 2 copies of external-dns running, one for each account. You don't even need to use the assume role option in external-dns. |
we just spent 4 hours on this and this was the issue. |
In my case I had to remove this part, because if it was non-empty it seemed to skip IRSA mechanism and ignored annotation placed on the K8s service account I deploy external-dns with chart version 5.4.15, app 0.10.1. I am deploying using Helm. Specifically I had to remove Helm param: At the end, if I describe the |
That doc pretty much covers it: Pay attention to:
|
Hey guys, I need help. I have been stuck on this problem for 3 days. I followed exactly what @linki said, but it is still not working. This is what I have. Account A has deployed ExtrnalDNS and account B has the hosted zones. Account A Settings This is ExternalDNS account A role ( {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::BBBBBBBBBB:role/external-dns-cross-accounts-role"
},
"Action": [
"sts:TagSession",
"sts:AssumeRole"
]
}
]
} This is the annotation I added to my account A ExternalDNS ServiceAccount. metadata:
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::AAAAAAAAAA:role/external-dns-role This is the arg I added to my account A ExternalDNS Deployment. spec:
template:
spec:
containers:
- name: external-dns
args:
- '--aws-assume-role=arn:aws:iam::BBBBBBBBBB:role/external-dns-cross-accounts-role' Account B Settings This is account B role ( {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::AAAAAAAAAA:role/external-dns-role"
},
"Action": [
"sts:TagSession",
"sts:AssumeRole"
]
}
]
} This is the policy. {
"Statement": [
{
"Action": "route53:*",
"Effect": "Allow",
"Resource": "*"
}
],
"Version": "2012-10-17"
} Lastly, This is the error I'm having.
Can you guys help me with what I'm doing wrong? |
@ricardorqr , do you have an IAM trust policy in place, allowing the specified Kubernetes service account to assume the IAM role? https://aws.amazon.com/blogs/opensource/introducing-fine-grained-iam-roles-service-accounts/ |
This is one of my doubts. I understood by @linki example that I had to replace the old trust relationship role, which had This is the old trust relationship role installed by the default deployment. It was working, but this account doesn't have the hosted zones. Only the account B has. {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam:: AAAAAAAAAA:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/5FB9E51C0F08ELKJHLJH7B25462C7A16"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"oidc.eks.us-west-2.amazonaws.com/id/5FB9E51C0F08ELKJHLJH7B25462C7A16:sub": "system:serviceaccount:external-dns:external-dns",
"oidc.eks.us-west-2.amazonaws.com/id/5FB9E51C0F08ELKJHLJH7B25462C7A16:aud": "sts.amazonaws.com"
}
}
}
]
} And this is the policy. {
"Statement": [
{
"Action": "route53:ChangeResourceRecordSets",
"Effect": "Allow",
"Resource": "arn:aws:route53:::hostedzone/*"
},
{
"Action": [
"route53:ListTagsForResource",
"route53:ListResourceRecordSets",
"route53:ListHostedZones"
],
"Effect": "Allow",
"Resource": "*"
}
],
"Version": "2012-10-17"
} |
Hey @vainkop, {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::AAAAAAAAAA:oidc-provider/oidc.eks.us-east-2.amazonaws.com/id/5FB9E51C0F08ELKJHLJH7B25462C7A16"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"oidc.eks.us-east-2.amazonaws.com/id/5FB9E51C0F08ELKJHLJH7B25462C7A16:sub": "system:serviceaccount:external-dns:external-dns",
"oidc.eks.us-east-2.amazonaws.com/id/5FB9E51C0F08ELKJHLJH7B25462C7A16:aud": "sts.amazonaws.com"
}
}
},
{
"Sid": "Statement1",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::BBBBBBBBBB:role/external-dns-cross-accounts-role"
},
"Action": "sts:AssumeRole"
}
]
} I had a different error log:
|
The problem has been fixed. I just attached a second policy to the ExternalDNS account A role {
"Statement": [
{
"Action": [
"sts:AssumeRole"
],
"Effect": "Allow",
"Resource": [
"arn:aws:iam::BBBBBBBBBB:role/external-dns-cross-accounts-role"
],
"Sid": "Statement1"
}
],
"Version": "2012-10-17"
} |
Hello to everyone,
I hope this is the right place to ask my question. If not please point me to the correct place or documentation.
We are in the process of setting up an AWS EKS cluster that uses the OIDC provider for IAM access control to AWS resources. So far this works fine for the ALB ingresss controler. Now we want to also add externalDNS to create DNS records in Route53 for zones hosted in another AWS account.
We have a MGMT AWS account (ID: 222233334444) that is hosting the Route53 DNS zones and a test stage AWS account (ID: 999988887777) where we run the EKS cluster. Now we want to setup externalDNS for a cross account access to add/change the DNS entries hosted in the MGMT account. See below for the config files and error message we get.
Please let me know if I missed something or you need more information.
Michael
====== config details ======
When I try to setup externalDNS I get the following error:
IAM Role for the test account:
IAM Role for the MGMT account:
Kubernetes YAML configuration for externalDNS:
The text was updated successfully, but these errors were encountered: