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

Allow specifying baseArn to prepend to role names. #95

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

danp60
Copy link

@danp60 danp60 commented Nov 21, 2020

Description of changes:
This PR introduces the ability to specify a baseArn to prepend to role names when we detect that the arn passed to the eks.amazonaws.com/role-arn annotation is not fully qualified.

Our use case is that we have different clusters that run in different AWS accounts. This will allow us to use the same manifest to deploy to these different clusters and allow each pod to assume the correct IAM role local to their account.

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

If the role-arn specified in the eks.amazonaws.com/role-arn is not
fully qualified, prepend it with a default base Arn.
@danp60 danp60 requested a review from a team as a code owner November 21, 2020 02:47
@danp60
Copy link
Author

danp60 commented Nov 30, 2020

Any feedback or comments @aws/eks-contributors?

@danp60
Copy link
Author

danp60 commented Dec 5, 2020

@jqmichael @josselin-c @micahhausler Any chance someone could take a look at this?

@danopia
Copy link

danopia commented Dec 8, 2020

I'd love to see this merged; it's silly to require the role annotation to differ between AWS accounts. Splitting accounts by environment is pretty common practice, as is one cluster per account.

Fixes #56

@danp60
Copy link
Author

danp60 commented Apr 30, 2022

@nckturner @wongma7 does this look like a worthwhile contribution to you? Please let me know and I will cleanup this PR

@@ -60,6 +60,7 @@ func main() {
// annotation/volume configurations
annotationPrefix := flag.String("annotation-prefix", "eks.amazonaws.com", "The Service Account annotation to look for")
audience := flag.String("token-audience", "sts.amazonaws.com", "The default audience for tokens. Can be overridden by annotation")
baseArn := flag.String("base-arn", "", "The base arn to use if a non fully qualified role is detected")
Copy link
Contributor

Choose a reason for hiding this comment

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

I have few thoughts on this:
1- This mechanism allows usage only when the user has access to change the parameters. Non cluster admins would not be able to use this functionality. wdyt about making this extensible by adding an new annotations on service accounts?
2- rollout and rollback(if needed) of this might become tricky due to using the same rolearn annotation. wdyt about using entirely different parameters for annotation like eks.amazonaws.com/role and eks.amazonaws.com/role-prefix that clarifies the intent of the fields explicitly
3. Can we add a feature flag for this functionality (set to alpha first and disabled by default) so that only interested users can flip this on.

Choose a reason for hiding this comment

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

The prefix is always going to be specific to the cluster. It will be arn:aws:iam::, followed by the ID of the account the cluster is in, followed by :role/, followed by the name of the cluster, followed by some fixed separator (I use _).

So one possibility would be to make this not configurable, simply prepending unqualified values with the prefix described above.

Copy link
Author

Choose a reason for hiding this comment

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

Thanks for the comments. I did not forget about this PR, and I'll try and make some time to work on it soon.

Copy link
Author

Choose a reason for hiding this comment

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

1- This mechanism allows usage only when the user has access to change the parameters. Non cluster admins would not be able to use this functionality. wdyt about making this extensible by adding an new annotations on service accounts?

One of the main purposes of this feature is to hide the details of the environment (ie the AWS account ID) from the end user. If the end user had to add an annotation with the base ARN that included the account ID, then they could just write the fully qualified ARN and not use this feature at all, so I'm not sure if it would be that useful.

2- rollout and rollback(if needed) of this might become tricky due to using the same rolearn annotation. wdyt about using entirely different parameters for annotation like eks.amazonaws.com/role and eks.amazonaws.com/role-prefix that clarifies the intent of the fields explicitly

I can do this. If an end user sets both, the most reasonable (and backwards compatible) behavior to me seems to be to take the original annotation eks.amazonaws.com/role verbatim and not make any changes.

  1. Can we add a feature flag for this functionality (set to alpha first and disabled by default) so that only interested users can flip this on.

Do you think this is required if we do 2. and make the new annotation only a fallback if the original one doesn't exist?

The prefix is always going to be specific to the cluster. It will be arn:aws:iam::, followed by the ID of the account the cluster is in, followed by :role/, followed by the name of the cluster, followed by some fixed separator (I use _).

So one possibility would be to make this not configurable, simply prepending unqualified values with the prefix described above.
This seems reasonable to me too. I can add a flag for --aws-default-account-id similar to how we have flags for other AWS environment like region.

WDYT?

@seh
Copy link

seh commented Sep 2, 2022

Is anyone still working on this patch?

@chlunde
Copy link

chlunde commented Sep 3, 2022

@jyotimahapatra would this approach help anyone running on EKS? I would expect some template like {{clusterAccount}} might be supported in EKS, but configuring a CLI option would only work for self-hosted installations

@jyotimahapatra
Copy link
Contributor

would this approach help anyone running on EKS? I would expect some template like {{clusterAccount}} might be supported in EKS, but configuring a CLI option would only work for self-hosted installations

Correct. This is right now relevant for self hosted installations.

@johngmyers
Copy link

How this would work on EKS is a problem for EKS. It is not particularly relevant for the amazon-eks-pod-identity-webhook project.

@jyotimahapatra
Copy link
Contributor

How this would work on EKS is a problem for EKS. It is not particularly relevant for the amazon-eks-pod-identity-webhook project.

Correct. Once this is implemented, EKS can make it work by default.

@@ -133,6 +133,7 @@ Usage of amazon-eks-pod-identity-webhook:
--alsologtostderr log to standard error as well as files
--annotation-prefix string The Service Account annotation to look for (default "eks.amazonaws.com")
--aws-default-region string If set, AWS_DEFAULT_REGION and AWS_REGION will be set to this value in mutated containers
--base-arn string The base arn to use if a non fully qualified role is detected
Copy link

Choose a reason for hiding this comment

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

Suggested change
--base-arn string The base arn to use if a non fully qualified role is detected
--role-base-arn string The base ARN to use as a prefix for completing role ARNs that are not fully qualified

@@ -60,6 +60,7 @@ func main() {
// annotation/volume configurations
annotationPrefix := flag.String("annotation-prefix", "eks.amazonaws.com", "The Service Account annotation to look for")
audience := flag.String("token-audience", "sts.amazonaws.com", "The default audience for tokens. Can be overridden by annotation")
baseArn := flag.String("base-arn", "", "The base arn to use if a non fully qualified role is detected")
Copy link

Choose a reason for hiding this comment

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

Suggested change
baseArn := flag.String("base-arn", "", "The base arn to use if a non fully qualified role is detected")
roleBaseARN := flag.String("role-base-arn", "", "The base ARN to use as a prefix for completing role ARNs that are not fully qualified")

@@ -112,6 +113,7 @@ func main() {
handler.WithServiceAccountCache(saCache),
handler.WithRegion(*region),
handler.WithRegionalSTS(*regionalSTS),
handler.WithBaseArn(*baseArn),
Copy link

Choose a reason for hiding this comment

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

Suggested change
handler.WithBaseArn(*baseArn),
handler.WithRoleBaseARN(*roleBaseARN),

Comment on lines +107 to +108
// WithBaseArn sets the baseArn to use if we detect role name is not fully qualified
func WithBaseArn(baseArn string) ModifierOpt {
Copy link

Choose a reason for hiding this comment

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

Suggested change
// WithBaseArn sets the baseArn to use if we detect role name is not fully qualified
func WithBaseArn(baseArn string) ModifierOpt {
// WithRoleBaseARN sets the base ARN to use as a prefix for completing role ARNs that are not fully qualified
func WithRoleBaseARN(baseARN string) ModifierOpt {

@@ -102,6 +104,11 @@ func WithRegionalSTS(enabled bool) ModifierOpt {
return func(m *Modifier) { m.RegionalSTSEndpoint = enabled }
}

// WithBaseArn sets the baseArn to use if we detect role name is not fully qualified
func WithBaseArn(baseArn string) ModifierOpt {
return func(m *Modifier) { m.BaseArn = baseArn }
Copy link

Choose a reason for hiding this comment

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

Suggested change
return func(m *Modifier) { m.BaseArn = baseArn }
return func(m *Modifier) { m.RoleBaseARN = baseARN }

var changed bool
var initContainers = []corev1.Container{}
for i := range pod.Spec.InitContainers {
container := pod.Spec.InitContainers[i]
changed = m.addEnvToContainer(&container, tokenFilePath, roleName, updateSettings)
changed = m.addEnvToContainer(&container, tokenFilePath, fullRoleArn, updateSettings)
Copy link

Choose a reason for hiding this comment

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

Suggested change
changed = m.addEnvToContainer(&container, tokenFilePath, fullRoleArn, updateSettings)
changed = m.addEnvToContainer(&container, tokenFilePath, fullRoleARN, updateSettings)

initContainers = append(initContainers, container)
}
var containers = []corev1.Container{}
for i := range pod.Spec.Containers {
container := pod.Spec.Containers[i]
changed = m.addEnvToContainer(&container, tokenFilePath, roleName, updateSettings)
changed = m.addEnvToContainer(&container, tokenFilePath, fullRoleArn, updateSettings)
Copy link

Choose a reason for hiding this comment

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

Suggested change
changed = m.addEnvToContainer(&container, tokenFilePath, fullRoleArn, updateSettings)
changed = m.addEnvToContainer(&container, tokenFilePath, fullRoleARN, updateSettings)

@@ -48,6 +48,7 @@ var (
handlerExpirationAnnotation = "testing.eks.amazonaws.com/handler/expiration"
handlerRegionAnnotation = "testing.eks.amazonaws.com/handler/region"
handlerSTSAnnotation = "testing.eks.amazonaws.com/handler/injectSTS"
handlerBaseArnAnnotation = "testing.eks.amazonaws.com/handler/baseArn"
Copy link

Choose a reason for hiding this comment

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

Suggested change
handlerBaseArnAnnotation = "testing.eks.amazonaws.com/handler/baseArn"
handlerBaseARNAnnotation = "testing.eks.amazonaws.com/handler/baseARN"

Comment on lines +77 to +78
if baseArnAnnotation, ok := pod.Annotations[handlerBaseArnAnnotation]; ok {
modifiers = append(modifiers, WithBaseArn(baseArnAnnotation))
Copy link

Choose a reason for hiding this comment

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

Suggested change
if baseArnAnnotation, ok := pod.Annotations[handlerBaseArnAnnotation]; ok {
modifiers = append(modifiers, WithBaseArn(baseArnAnnotation))
if baseARNAnnotation, ok := pod.Annotations[handlerBaseARNAnnotation]; ok {
modifiers = append(modifiers, WithBaseARN(baseARNAnnotation))

metadata:
name: balajilovesoreos
annotations:
testing.eks.amazonaws.com/handler/baseArn: 'arn:aws:iam::111122223333:role/'
Copy link

Choose a reason for hiding this comment

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

Suggested change
testing.eks.amazonaws.com/handler/baseArn: 'arn:aws:iam::111122223333:role/'
testing.eks.amazonaws.com/handler/baseARN: 'arn:aws:iam::111122223333:role/'

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.

None yet

6 participants