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

Add EKS access entry and policy association resources #1273

Merged
merged 10 commits into from
Aug 8, 2024

Conversation

mbbush
Copy link
Collaborator

@mbbush mbbush commented Apr 21, 2024

Description of your changes

Add support for api-based auth in EKS, using eks access entries and access policy associations.

Fixes #1098

I have:

  • Read and followed Crossplane's contribution process.
  • Run make reviewable to ensure this PR is ready for review.
  • Added backport release-x.y labels to auto-backport this PR if necessary.

How has this code been tested

Uptest run (the only difference between this and the latest commit is a spelling fix in a code comment)

I'm planning to update the uptest example manifest to include an update test as well. not going to fight with uptest about the current hard-to-use update syntax, and instead will just wait for chainsaw to offer a better way.

@johnathan-sq
Copy link

Are there any updates on this PR? Keen to see this in main

@fernandezcuesta
Copy link

I guess the underlying version constraint is gone with 1.5?

@haarchri
Copy link
Member

Yes

@mbbush mbbush force-pushed the eks-access branch 2 times, most recently from 8fc48f7 to 1e85602 Compare May 30, 2024 21:11
@mbbush
Copy link
Collaborator Author

mbbush commented May 30, 2024

/test-examples="examples/eks/v1beta1/accessentry.yaml"

1 similar comment
@mbbush
Copy link
Collaborator Author

mbbush commented May 31, 2024

/test-examples="examples/eks/v1beta1/accessentry.yaml"

config/externalname.go Outdated Show resolved Hide resolved
// This function sets the keys as IdentifierFields, which means that they are always required, even for observe-only
// resources. Because the id is constructed exclusively from the keys, omitting them (even if the external name
// annotation is set) leaves the provider unable to find the terraform id to use to observe the resource.
func FormattedIdentifierFromProviderWithIdentifierFields(separator string, keys ...string) config.ExternalName {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

These function names are getting excessively verbose, but I couldn't think of another option that preserved the "dsl-like" semantics of (most of) the external name config file, didn't introduce a schema change, and could handle the ...string variable arguments.

If anyone has a better idea I'd love to hear it.

Copy link
Collaborator

@turkenf turkenf Jun 25, 2024

Choose a reason for hiding this comment

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

When I examined the import sections in the two resources you added, the parameters used in id can be taken from spec.forProvider. In other words, since these are not resources whose identifiers are assigned by the remote client, I think it is better to use TemplatedStringAsIdentifier here if it works.

This function also sets the keys as IdentifierFields, so extra configuration is unnecessary.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

That's exactly what I tried as my first external name configuration; see 24a791a. The problem with TemplatedStringAsIdentifier is that because it has DisableNameInitializer: false it initializes the external name to the metadata.name, before updating it to use the value from the template. When I was testing, this caused something to not work; I don't remember what it was.

Your comment about the identifier not really coming from the provider is a good one; that means this is not a good name for this function. Really the essence of what I need is to disable the name initializer. I think the best solution is to add WithDisabledNameInitializer to the ExternalNameFrom helper functions @ulucinar added in crossplane/upjet@47cb5c5

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The trouble is that I couldn't find any actual examples of usages of the ExternalNameFrom helpers, so I'll probably have to fumble around a bit in order to figure out the syntax.

Copy link
Collaborator

Choose a reason for hiding this comment

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

If the problem is just DisableNameInitializer: false, we may use this function?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

TemplatedStringAsIdentifierWithNoName is only used by two resources, both of which have a provider-generated component to their terraform id which is separated out and stored in the external name. I recall running into some problems with them in the past related to initial creation, which prompted the TODO I put in that function's docs, and I'm re-running their uptest examples to refresh my memory. I'll check back once those tests finish to see what they did.

Do you have a reason for preferring the "Templated" syntax in the external name config over specifying the parameters and the separator? It seems like that just creates more work to reverse-engineer the template string to do things like find identifier fields and look for {{ .external_name }}.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think that whatever problem I was observing on initial creation for TemplatedStringAsIdentifierWithNoName was only a problem with the cli-forking architecture, as I saw no issues with those resources. I'll remove the TODO comment from that external name config.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Do you have a reason for preferring the "Templated" syntax in the external name config over specifying the parameters and the separator?

I don't have any special reason or desire to use the templated syntax. I don't find it appropriate to add a new function for consistency reasons if we can configure the resource without any problems with the existing external name functions/configurations.

I think that whatever problem I was observing on initial creation for TemplatedStringAsIdentifierWithNoName was only a problem with the cli-forking architecture, as I saw no issues with those resources. I'll remove the TODO comment from that external name config.

From your comment, am I to understand that you will try to continue with TemplatedStringAsIdentifierWithNoName?

Comment on lines +116 to +109
// Use the terraform id instead of the external name because the external name is set before the cluster
// has been created.
Extractor: common.PathTerraformIDExtractor,
Copy link
Collaborator Author

@mbbush mbbush May 31, 2024

Choose a reason for hiding this comment

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

When I was testing this resource (see the console logs from https://github.com/crossplane-contrib/provider-upjet-aws/actions/runs/9309885236 with the state of the MRs before the cluster creation finishes), I was surprised to see that with the default external name extractor, the reference to the eks cluster was being resolved even before the MR posted a Ready condition. I thought that the Ready check was part of all the cross-resource references, but when I went looking for the code that implemented it I couldn't find anything.

I'm not sure if this is something special about the eks cluster resource, something that would be true of all resources with an external name config that has the name-based initializer enabled, something I'm just misremembering, or a sign of a larger problem.

It seems like it would be especially problematic for those resources which use an external name which is not the same as the metadata.name, but which have an external name config that has the initializer enabled, because then references would resolve first to the metadata.name (in the external name field) and then once the real external name was set, switch to the right value.

@mbbush mbbush marked this pull request as ready for review May 31, 2024 05:51
@turkenf
Copy link
Collaborator

turkenf commented Jun 24, 2024

/test-examples="examples/eks/v1beta1/accessentry.yaml"

// my_cluster:my_eks_addon
// "aws_eks_addon": config.TemplatedStringAsIdentifier("addon_name", "{{ .parameters.cluster_name }}:{{ .external_name }}"),
"aws_eks_addon": FormattedIdentifierFromProvider(":", "cluster_name", "addon_name"),
// import EKS access entry using the cluster_name and principal_arn separated by a colon (:).
"aws_eks_access_entry": FormattedIdentifierFromProviderWithIdentifierFields(":", "cluster_name", "principal_arn"),
Copy link
Collaborator

Choose a reason for hiding this comment

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

As I mentioned here, could you please try the following:

Suggested change
"aws_eks_access_entry": FormattedIdentifierFromProviderWithIdentifierFields(":", "cluster_name", "principal_arn"),
"aws_eks_access_entry": config.TemplatedStringAsIdentifier("", "{{ .parameters.cluster_name }}:{{ .parameters.principal_arn }}"),

// import EKS access entry using the cluster_name and principal_arn separated by a colon (:).
"aws_eks_access_entry": FormattedIdentifierFromProviderWithIdentifierFields(":", "cluster_name", "principal_arn"),
// import EKS access entry using the cluster_name principal_arn and policy_arn separated by a (#) which the tf provider docs incorrectly describe as a colon.
"aws_eks_access_policy_association": FormattedIdentifierFromProviderWithIdentifierFields("#", "cluster_name", "principal_arn", "policy_arn"),
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
"aws_eks_access_policy_association": FormattedIdentifierFromProviderWithIdentifierFields("#", "cluster_name", "principal_arn", "policy_arn"),
"aws_eks_access_policy_association": config.TemplatedStringAsIdentifier("", "{{ .parameters.cluster_name }}#{{ .parameters.principal_arn }}#{{ .parameters.policy_arn }}"),

@r-nasiri
Copy link

any updates on this? this is a very useful feature specially if you have multiple node groups or need to grant access to multiple IAM roles. updating config map is not fun :)

@fhochleitner
Copy link

plus one from my side this feature/provider would realy make our lives a lot easier

@turkenf
Copy link
Collaborator

turkenf commented Jul 25, 2024

Hey @mbbush, are you still interested in taking this PR forward?

@mbbush
Copy link
Collaborator Author

mbbush commented Jul 28, 2024

/test-examples="examples/eks/v1beta1/accessentry.yaml"

2 similar comments
@mbbush
Copy link
Collaborator Author

mbbush commented Jul 28, 2024

/test-examples="examples/eks/v1beta1/accessentry.yaml"

@mbbush
Copy link
Collaborator Author

mbbush commented Jul 29, 2024

/test-examples="examples/eks/v1beta1/accessentry.yaml"

@mbbush
Copy link
Collaborator Author

mbbush commented Jul 29, 2024

/test-examples="examples/eks/v1beta1/accessentry.yaml"

@mbbush
Copy link
Collaborator Author

mbbush commented Jul 29, 2024

@turkenf I've rebased this, updated the schema to use embedded objects, and reran the tests. I renamed the ...FromProvider external name configs which only actually used values from the parameters to be named ...FromParameters, and gave the shorter name to the one that does include identifier fields, as that's what I would expect to be more correct for new resources. We can update the existing resource configurations as needed.

As I mentioned above, the main difference between the current external name config and the TemplatedString one is that this disables the name initializer, which I see as a good thing, since it would only ever set the external name to an incorrect value.

@turkenf
Copy link
Collaborator

turkenf commented Jul 29, 2024

As I mentioned above, the main difference between the current external name config and the TemplatedString one is that this disables the name initializer, which I see as a good thing, since it would only ever set the external name to an incorrect value.

I left a comment above.

@turkenf I've rebased this, updated the schema to use embedded objects, and reran the tests. I renamed the ...FromProvider external name configs which only actually used values from the parameters to be named ...FromParameters, and gave the shorter name to the one that does include identifier fields, as that's what I would expect to be more correct for new resources. We can update the existing resource configurations as needed.

I really appreciate your effort @mbbush, but I think the externalname change should be handled in another PR, even if we are just changing the name.

@mbbush
Copy link
Collaborator Author

mbbush commented Jul 29, 2024

/test-examples="examples/cloudformation/v1beta1/stack.yaml"

@mbbush
Copy link
Collaborator Author

mbbush commented Jul 29, 2024

/test-examples="examples/appsync/v1beta1/apikey.yaml"

@turkenf
Copy link
Collaborator

turkenf commented Aug 1, 2024

Hey @mbbush, kindly reminder: #1273 (comment)

@turkenf
Copy link
Collaborator

turkenf commented Aug 6, 2024

/test-examples="examples/eks/v1beta1/accessentry.yaml"

@mbbush
Copy link
Collaborator Author

mbbush commented Aug 7, 2024

@turkenf My plan for handling this was actually to remove TemplatedStringAsIdentifierWithNoName, as the two resources that use it work just as well (or better) using TemplatedStringAsProviderDefinedIdentifier, which has the added benefits of a name that makes sense with what it does, and not setting the external name to an invalid value (the template with an empty string in the .external_name part) during creation, as TemplatedStringAsIdentifierWithNoName does for templates that contain {{ .external_name }}.

I guess it's true that those changes can be done later in a non-breaking way, even if we release this code as it is after your 8a301f3 commit. I just find that I'm having less time lately for such improvements, and that when I do, those sorts of "general improvement" PRs often linger unreviewed for a long time.

Maybe the best thing to do at this point is to just merge this and release it so we can finally support this feature that I started implementing 3 months ago.

mbbush and others added 10 commits August 8, 2024 14:39
Signed-off-by: Matt Bush <[email protected]>
So that the refs don't resolve until after the cluster exists

Signed-off-by: Matt Bush <[email protected]>
So that crossplane doesn't initialize the external name with
the incorrect value before updating it to the correct value.

Signed-off-by: Matt Bush <[email protected]>
Signed-off-by: Matt Bush <[email protected]>
Signed-off-by: Matt Bush <[email protected]>
…nd AccessEntry resources

Signed-off-by: Fatih Türken <[email protected]>
@turkenf
Copy link
Collaborator

turkenf commented Aug 8, 2024

/test-examples="examples/eks/v1beta1/accessentry.yaml"

https://github.com/crossplane-contrib/provider-upjet-aws/actions/runs/10301382270

Copy link
Collaborator

@mergenci mergenci left a comment

Choose a reason for hiding this comment

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

Thanks @mbbush and @turkenf. LGTM.

@turkenf turkenf merged commit 5a775c6 into crossplane-contrib:main Aug 8, 2024
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Request for aws_eks_access_entry resource
8 participants