Skip to content
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

user-configurable IAM roles for ServiceAccounts #11016

Merged
merged 2 commits into from
May 2, 2021

Conversation

olemarkus
Copy link
Member

This PR allows users to configure IRSA for their own workloads. It is the kOps equivalent of https://eksctl.io/usage/iamserviceaccounts/#usage-with-config-files

/cc @justinsb @rifelpet

@k8s-ci-robot k8s-ci-robot added do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. area/api labels Mar 11, 2021
@olemarkus olemarkus force-pushed the irsa-custom branch 3 times, most recently from 3c22b11 to 04e0253 Compare March 12, 2021 10:30
@olemarkus
Copy link
Member Author

/retest

@olemarkus olemarkus changed the title WIP user-configurable IAM roles for ServiceAccounts user-configurable IAM roles for ServiceAccounts Mar 12, 2021
@k8s-ci-robot k8s-ci-robot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Mar 12, 2021
@k8s-ci-robot k8s-ci-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Mar 20, 2021
@olemarkus olemarkus added this to the v1.21 milestone Apr 1, 2021
@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 5, 2021
Copy link
Member

@rifelpet rifelpet left a comment

Choose a reason for hiding this comment

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

I don't see the OIDC provider being created in the integration test's terraform output. any idea why that is?

}
if sa.IAMPolicyARN != "" && sa.InlinePolicy != "" {
allErrs = append(allErrs, field.Forbidden(p, "cannot set both inlinePolicy and iamPolicyARN"))
}
Copy link
Member

Choose a reason for hiding this comment

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

nit, might be worth validating the policy arn:

parsedARN, err := arn.Parse(instanceProfileARN)
if err != nil || !strings.HasPrefix(parsedARN.Resource, "instance-profile/") {
allErrs = append(allErrs, field.Invalid(fldPath.Child("profile"), instanceProfileARN,
"Instance Group IAM Instance Profile must be a valid aws arn such as arn:aws:iam::123456789012:instance-profile/KopsExampleRole"))
}

pkg/model/iam.go Outdated Show resolved Hide resolved
pkg/model/iam.go Outdated Show resolved Hide resolved
@olemarkus
Copy link
Member Author

PublicJWKS feature flag isn't set on this particular test, so no OIDC config is created.

@rifelpet
Copy link
Member

rifelpet commented Apr 6, 2021

The iam roles' assume role policies reference arn:aws:iam::123456789012:oidc-provider/api.internal.minimal.example.com if that's not being created in kubernetes.tf nor specified anywhere in the cluster spec then where did it come from? Is this even a valid configuration?

@olemarkus
Copy link
Member Author

Not really. Those two flags would almost always be used together.

It depends a bit what we want here. My idea was to add an enable flag on this struct, and that would mean provision OIDC (i.e PublicJWKS). Having this enabled, would also use IRSA on all kops addons that supports it (i.e UseServiceAccountIAM).

Question is if we want to force that? Or do we want users to enable IRSA, but not for the kops addons? Do we want users to enable IRSA individually on all addons?

@rifelpet
Copy link
Member

rifelpet commented Apr 6, 2021

Hm for migration purposes I could see the benefit of being able to migrate individual addons to IRSA. It'd be safer to migrate one at a time rather than be forced to do them all at once. I do like the idea of an enable field here that would supplement PublicJWKS. Perhaps we update the integration test to use both feature flags, and (potentially in a followup PR) add api validation to ensure PublicJWKS is enabled if UseServiceAccountIAM is enabled? And if we want to relax that restriction down the road (eg. to allow specifying an existing OIDC provider ARN in the cluster spec) then we can do that.

@olemarkus olemarkus force-pushed the irsa-custom branch 3 times, most recently from c7f8abc to 93fbd3b Compare April 6, 2021 11:42
@olemarkus
Copy link
Member Author

/retest

@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 23, 2021
@rifelpet
Copy link
Member

Does Cluster API or any of the relevant Cluster API providers support similar functionality? If so we could consider modeling our design off of theirs to reduce friction when adopting Cluster API support.

@rifelpet
Copy link
Member

A summary of the discussion from office hours:

  • Move inlinePolicy and iamPolicyARNs to an aws substruct
  • Rename serviceAccountMappings to something indicating these are mappings to external permissions (cloud providers, etc.) serviceAccountExternalMappings was proposed.
  • We need to investigate if multiple fields are supported as a merge key for patch operations since an element in the serviceAccountMappings list would be keyed by name + namespace

As an aside, I think if we move iamPolicyARNs to an aws substruct we could probably drop the iam prefix from the field name, to be more consistent with inlinePolicy and because the presence of the aws field provides sufficient context that these policy ARNs are for AWS IAM policies.

@olemarkus
Copy link
Member Author

Amended according to our discussions today.

Note that right now, one can configure this without enabling AWS OIDC provider. Once that is configurable, we may want to add validation for that. Easy thing that can be done in a follow-up.

@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 29, 2021
@k8s-ci-robot k8s-ci-robot added the area/provider/aws Issues or PRs related to aws provider label Apr 30, 2021
@olemarkus
Copy link
Member Author

/test pull-kops-e2e-cni-amazonvpc

@johngmyers
Copy link
Member

Why use the word "mappings" for these? That word appears to be overly uninformative as to what is being provisioned. What is being provisioned is something more like "permissions" or "roles". They're the out-of-cluster analogue of Role and/or RoleBinding.

@johngmyers
Copy link
Member

Okay, at least that word isn't exposed through the API.

pkg/apis/kops/cluster.go Outdated Show resolved Hide resolved
pkg/apis/kops/cluster.go Outdated Show resolved Hide resolved
featureflag.ParseFlags("+PublicJWKS")
unsetFeatureFlags := func() {
featureflag.ParseFlags("-PublicJWKS")
}
Copy link
Member

Choose a reason for hiding this comment

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

Would be good to not require the feature flag. Not blocking.

@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 30, 2021
@k8s-ci-robot k8s-ci-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label May 1, 2021
@olemarkus olemarkus force-pushed the irsa-custom branch 2 times, most recently from 06851c5 to cf410b1 Compare May 1, 2021 12:19
Apply suggestions from code review

Co-authored-by: John Gardiner Myers <[email protected]>
Comment on lines 231 to 232
PolicyARNs []string `json:"policyARNs,omitempty"`
InlinePolicy string `json:"inlinePolicy,omitempty"`
Copy link
Member

Choose a reason for hiding this comment

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

Could use comments on these.

pkg/apis/kops/validation/validation.go Show resolved Hide resolved
pkg/apis/kops/validation/validation.go Outdated Show resolved Hide resolved
UseServiceAccountIAM = New("UseServiceAccountIAM", Bool(false))
// PublicJWKS enables public jwks access. This is generally not as secure as republishing.
// PublicJWKS enables public jwks access.
Copy link
Member

Choose a reason for hiding this comment

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

These changes are technically out of scope of this PR. Not blocking.

@@ -124,26 +125,64 @@ func (b *IAMModelBuilder) Build(c *fi.ModelBuilderContext) error {
}
}

iamSpec := b.Cluster.Spec.IAM
if iamSpec != nil {
for _, sa := range iamSpec.ServiceAccountExternalPermissions {
Copy link
Member

Choose a reason for hiding this comment

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

Do we have code to delete the relevant AWS objects when items are removed from this list?

Copy link
Member Author

Choose a reason for hiding this comment

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

No, as usual, kOps is quite bad at this. I am wondering if we need a more generic solution that. Maybe we can tag all RenderAWS-created resources with kops.k8s.io/task=taskname and then at the end of cloudup, remove all resources that match tasks that wasn't created.

I think we need to look at that separately.

if iamSpec != nil {
for _, sa := range iamSpec.ServiceAccountExternalPermissions {
var p *iam.Policy
aws := sa.AWS
Copy link
Member

Choose a reason for hiding this comment

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

We might consider handling aws == nil to save overlooking when someone adds a second external system.

Co-authored-by: John Gardiner Myers <[email protected]>
@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label May 2, 2021
@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: johngmyers

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

The pull request process is described 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

@k8s-ci-robot k8s-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label May 2, 2021
@k8s-ci-robot k8s-ci-robot merged commit b054fb3 into kubernetes:master May 2, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. area/api area/provider/aws Issues or PRs related to aws provider cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. kind/office-hours lgtm "Looks good to me", indicates that a PR is ready to be merged. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants