Skip to content

✨ Add EKS Pod Identities to AWSManagedControlPlane #4906

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

Open
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

stefanmcshane
Copy link
Contributor

@stefanmcshane stefanmcshane commented Apr 3, 2024

What type of PR is this?

/kind feature

What this PR does / why we need it:

Support using AWS EKS Pod Identity Associations for mapping pods to IAM roles without needing OIDC or IRSA

https://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html

Which issue(s) this PR fixes (optional, in fixes #<issue number>(, fixes #<issue_number>, ...) format, will close the issue(s) when PR gets merged):

N/A

Special notes for your reviewer:

Docs available here, for a brief overview on setup

Checklist:

  • squashed commits
  • includes documentation
  • includes emojis
  • adds unit tests
  • adds or updates e2e tests

Release note:

Support mapping kubernetes service account to IAM role using EKS Pod Identity Associations

@k8s-ci-robot k8s-ci-robot added release-note Denotes a PR that will be considered when it comes time to generate release notes. kind/feature Categorizes issue or PR as related to a new feature. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. needs-priority labels Apr 3, 2024
@k8s-ci-robot k8s-ci-robot requested review from AndiDog and cnmcavoy April 3, 2024 22:33
@k8s-ci-robot k8s-ci-robot added needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. labels Apr 3, 2024
@k8s-ci-robot
Copy link
Contributor

Hi @stefanmcshane. Thanks for your PR.

I'm waiting for a kubernetes-sigs member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@stefanmcshane stefanmcshane changed the title Add EKS Pod Identities to AWSManagedControlPlane ✨ Add EKS Pod Identities to AWSManagedControlPlane Apr 3, 2024
@Ankitasw Ankitasw added ok-to-test Indicates a non-member PR verified by an org member that is safe to test. and removed needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. labels Apr 5, 2024
@stefanmcshane
Copy link
Contributor Author

/retest

@stefanmcshane
Copy link
Contributor Author

/retest-required

Comment on lines 283 to 292
// ServiceAccountName is the name of the kubernetes Service Account within the namespace
// +kubebuilder:validation:Required
ServiceAccountName string `json:"serviceAccountName"`
// ServiceAccountNamespace is the kubernetes namespace, which the kubernetes Service Account resides in. Defaults to "default" namespace.
// +kubebuilder:validation:Required
// +kubebuilder:default=default
ServiceAccountNamespace string `json:"serviceAccountNamespace"`
// RoleARN is the ARN of an IAM role which the Service Account can assume.
// +kubebuilder:validation:Required
RoleARN string `json:"serviceAccountRoleARN,omitempty"`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They're all called serviceAccountXXX which is an antipattern in Kubernetes manifests. I'd recommend moving these to .serviceAccount.{name,namespace,roleARN}.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The goal here was to be overtly explicit as I have found that our customers get confused on that sometimes. Nothing that docs cannot fix however

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In thinking more about this, I remembered that the kubernetes Pod spec switched from serviceAccount to serviceAccountName a few years back.
I do err on the side of clarity for maintainability's sake when it comes to naming, but would definitely not go against whatever is considered standard. Do you have a reference for the naming convention to help me decide?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In thinking about this more, whilst the medium is a CRD, the keys are in reference to an AWS object. I would expect a PodIdentityAssociation.Name to refer to the name of an AWS object when using the AWS API

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pod.spec.serviceAccountName is a singular field that won't change. It doesn't allow referring to another namespace on purpose.

The 3 fields you're adding will always be filled and none can be optional or defaulted (even the namespace), so a common prefix is unusual for newly-designed CRDs. See for example Ingress.spec.defaultBackend.service.{name,port} or Gateway API's Gateway.[...].listeners[*].{name,protocol,port}. Core APIs such as Pod aren't great examples since they can't be evolved without lots of breaking changes, and also a pod spec mostly only refers to names and doesn't provide many comparable examples here.

Therefore, here's my suggestion (dedenting roleARN as compared to my initial comment, since it's not referring to a service account):

  podIdentityAssociations:
    - serviceAccount:
        name: myserviceaccount
        namespace: default
      roleARN: arn:aws:iam::012345678901:role/capi-test-role

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is definitely a back and forth on the semantics on this. I personally dont see this as being a blocking change, and moreso a semantic preference.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At least the JSON field name and struct name should be aligned, since currently they're not lowercase-equal which could be confusing:

Suggested change
// ServiceAccountName is the name of the kubernetes Service Account within the namespace
// +kubebuilder:validation:Required
ServiceAccountName string `json:"serviceAccountName"`
// ServiceAccountNamespace is the kubernetes namespace, which the kubernetes Service Account resides in. Defaults to "default" namespace.
// +kubebuilder:validation:Required
// +kubebuilder:default=default
ServiceAccountNamespace string `json:"serviceAccountNamespace"`
// RoleARN is the ARN of an IAM role which the Service Account can assume.
// +kubebuilder:validation:Required
RoleARN string `json:"serviceAccountRoleARN,omitempty"`
// ServiceAccountName is the name of the kubernetes Service Account within the namespace
// +kubebuilder:validation:Required
ServiceAccountName string `json:"serviceAccountName"`
// ServiceAccountNamespace is the kubernetes namespace, which the kubernetes Service Account resides in. Defaults to "default" namespace.
// +kubebuilder:validation:Required
// +kubebuilder:default=default
ServiceAccountNamespace string `json:"serviceAccountNamespace"`
// RoleARN is the ARN of an IAM role which the Service Account can assume.
// +kubebuilder:validation:Required
ServiceAccountRoleARN string `json:"serviceAccountRoleARN,omitempty"`

Or the other way around (json:"roleARN") – doesn't matter.

Then the documented examples in docs/book/src/topics/eks/pod-identity-associations.md must be converted to the final naming choice.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case, the roleARN is an AWS resource, not a service account, so the naming shouldnt be consistent. The suggested shouldn't be committed imo

Comment on lines 92 to 94
if output.Association == nil {
return ErrNilPodIdentityAssociation
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this really happen? Or is there a specific reason why we want to check this field here, since we're not even reading it? I'd rather remove this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there is a possibility for it in their SDK, I personally wouldnt rule it out. I'd personally rather catch the possibility of this error loudly with an error returned, than letting it silently continue. Ill follow your lead and remove it as the arn is not read/used at present

@stefanmcshane stefanmcshane mentioned this pull request Apr 9, 2024
5 tasks
@stefanmcshane
Copy link
Contributor Author

Split out the AWS updates to reduce the size of this PR
#4916

@k8s-ci-robot k8s-ci-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Apr 18, 2024
@stefanmcshane stefanmcshane force-pushed the main branch 2 times, most recently from 836fbba to 121d8b1 Compare April 19, 2024 15:08
@k8s-ci-robot k8s-ci-robot added size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. and removed size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. labels Apr 19, 2024
@k8s-ci-robot k8s-ci-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Apr 19, 2024
Comment on lines 283 to 292
// ServiceAccountName is the name of the kubernetes Service Account within the namespace
// +kubebuilder:validation:Required
ServiceAccountName string `json:"serviceAccountName"`
// ServiceAccountNamespace is the kubernetes namespace, which the kubernetes Service Account resides in. Defaults to "default" namespace.
// +kubebuilder:validation:Required
// +kubebuilder:default=default
ServiceAccountNamespace string `json:"serviceAccountNamespace"`
// RoleARN is the ARN of an IAM role which the Service Account can assume.
// +kubebuilder:validation:Required
RoleARN string `json:"serviceAccountRoleARN,omitempty"`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pod.spec.serviceAccountName is a singular field that won't change. It doesn't allow referring to another namespace on purpose.

The 3 fields you're adding will always be filled and none can be optional or defaulted (even the namespace), so a common prefix is unusual for newly-designed CRDs. See for example Ingress.spec.defaultBackend.service.{name,port} or Gateway API's Gateway.[...].listeners[*].{name,protocol,port}. Core APIs such as Pod aren't great examples since they can't be evolved without lots of breaking changes, and also a pod spec mostly only refers to names and doesn't provide many comparable examples here.

Therefore, here's my suggestion (dedenting roleARN as compared to my initial comment, since it's not referring to a service account):

  podIdentityAssociations:
    - serviceAccount:
        name: myserviceaccount
        namespace: default
      roleARN: arn:aws:iam::012345678901:role/capi-test-role

@@ -0,0 +1,102 @@
/*
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't have a style or coding guide, I think. I did a regular code review and while reading, I found this to be a bit too complex for what it's doing, especially since one needs to read multiple functions. The source example pkg/eks/addons/plan.go is doing a bit more because of addon "states", and didn't have access to the nice slices module at the time. I don't think the code is very bad here. But maybe we can modernize rather than copy the existing idea as-is. It can be mostly a single function.

Comment on lines 283 to 292
// ServiceAccountName is the name of the kubernetes Service Account within the namespace
// +kubebuilder:validation:Required
ServiceAccountName string `json:"serviceAccountName"`
// ServiceAccountNamespace is the kubernetes namespace, which the kubernetes Service Account resides in. Defaults to "default" namespace.
// +kubebuilder:validation:Required
// +kubebuilder:default=default
ServiceAccountNamespace string `json:"serviceAccountNamespace"`
// RoleARN is the ARN of an IAM role which the Service Account can assume.
// +kubebuilder:validation:Required
RoleARN string `json:"serviceAccountRoleARN,omitempty"`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At least the JSON field name and struct name should be aligned, since currently they're not lowercase-equal which could be confusing:

Suggested change
// ServiceAccountName is the name of the kubernetes Service Account within the namespace
// +kubebuilder:validation:Required
ServiceAccountName string `json:"serviceAccountName"`
// ServiceAccountNamespace is the kubernetes namespace, which the kubernetes Service Account resides in. Defaults to "default" namespace.
// +kubebuilder:validation:Required
// +kubebuilder:default=default
ServiceAccountNamespace string `json:"serviceAccountNamespace"`
// RoleARN is the ARN of an IAM role which the Service Account can assume.
// +kubebuilder:validation:Required
RoleARN string `json:"serviceAccountRoleARN,omitempty"`
// ServiceAccountName is the name of the kubernetes Service Account within the namespace
// +kubebuilder:validation:Required
ServiceAccountName string `json:"serviceAccountName"`
// ServiceAccountNamespace is the kubernetes namespace, which the kubernetes Service Account resides in. Defaults to "default" namespace.
// +kubebuilder:validation:Required
// +kubebuilder:default=default
ServiceAccountNamespace string `json:"serviceAccountNamespace"`
// RoleARN is the ARN of an IAM role which the Service Account can assume.
// +kubebuilder:validation:Required
ServiceAccountRoleARN string `json:"serviceAccountRoleARN,omitempty"`

Or the other way around (json:"roleARN") – doesn't matter.

Then the documented examples in docs/book/src/topics/eks/pod-identity-associations.md must be converted to the final naming choice.

}

// IsEqual determines if 2 EKSPodIdentityAssociation are equal.
func (e *EKSPodIdentityAssociation) IsEqual(other *EKSPodIdentityAssociation) bool {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this function maybe unused? I checked that make test still works without it.

@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign sbueringer for approval. For more information see the Kubernetes Code Review Process.

The full list of commands accepted by this bot can be found here.

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

Copy link
Contributor

@AndiDog AndiDog left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the small last changes to finish this up.

/lgtm

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Jun 4, 2024
@k8s-ci-robot k8s-ci-robot removed the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Jun 5, 2024
@k8s-ci-robot
Copy link
Contributor

New changes are detected. LGTM label has been removed.

@k8s-ci-robot k8s-ci-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jul 30, 2024
@k8s-ci-robot
Copy link
Contributor

PR needs rebase.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@k8s-ci-robot
Copy link
Contributor

@stefanmcshane: The following tests failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
pull-cluster-api-provider-aws-build-release-2-6 1cfd3e7 link true /test pull-cluster-api-provider-aws-build-release-2-6
pull-cluster-api-provider-aws-build-docker-release-2-6 1cfd3e7 link true /test pull-cluster-api-provider-aws-build-docker-release-2-6

Full PR test history. Your PR dashboard. Please help us cut down on flakes by linking to an open issue when you hit one in your PR.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

@richardcase
Copy link
Member

/retest

@AndiDog
Copy link
Contributor

AndiDog commented Nov 18, 2024

PR needs a rebase due to merge conflicts, please

@k8s-triage-robot
Copy link

The Kubernetes project currently lacks enough contributors to adequately respond to all PRs.

This bot triages PRs according to the following rules:

  • After 90d of inactivity, lifecycle/stale is applied
  • After 30d of inactivity since lifecycle/stale was applied, lifecycle/rotten is applied
  • After 30d of inactivity since lifecycle/rotten was applied, the PR is closed

You can:

  • Mark this PR as fresh with /remove-lifecycle stale
  • Close this PR with /close
  • Offer to help out with Issue Triage

Please send feedback to sig-contributor-experience at kubernetes/community.

/lifecycle stale

@k8s-ci-robot k8s-ci-robot added the lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. label Feb 16, 2025
@richardcase
Copy link
Member

/remove-lifecycle stale

@k8s-ci-robot k8s-ci-robot removed the lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. label Feb 17, 2025
@Danil-Grigorev
Copy link
Member

Hey @stefanmcshane - pinging in case you want to follow up on this PR? If not, would you mind if I try to rebase it to get it merged?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. kind/feature Categorizes issue or PR as related to a new feature. needs-priority needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. ok-to-test Indicates a non-member PR verified by an org member that is safe to test. release-note Denotes a PR that will be considered when it comes time to generate release notes. size/XL Denotes a PR that changes 500-999 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants