Kubernetes, CloudFormation and OIDC Magic Numbers
Using output-only CloudFormation Stacks to facilitate IAM Roles for Service Accounts in CloudFormation
Table Of Contents
Today I Explained
Magic numbers in programming refer to numeric (or other value) literals that are used within code without any explanation of its meaning, or providing any guidance on where to discover the value. An example of this comes with Kubernetes & IAM OIDC Identity Providers. These value ARNs look like the following:
arn:aws:iam::012345678901:oidc-provider/oidc.eks.us-east-2.amazonaws.com/id/7185F12D2B62B8DA97B0ECA713F66C86
If you are running a service within Kubernetes that you wish to have communicate with authenticated AWS APIs, you’ll need to make use of IAM Role for Service Accounts (IRSA). This works through an OIDC Provider which is able to permit authentication with an IAM Role. Within Kubernetes, a service account can then be mapped to that IAM Role, using the OIDC Provider to authenticate.
When it is understood, the usage of this OIDC Provider is understandable. Without the context behind it, these values appear as magic numbers, which present a uncertainty about which Kubernetes cluster they might be referencing, and how one would retrieve determine this.
Due to CloudFormation lacking the ability to lookup the OIDC Provider for a Kubernetes cluster by the name of the Kubernetes cluster, it can result in the value being passed as a parameter without the appropriate metadata context.
An alternative approach that can be considered is leveraging the capabilities of output-only CloudFormation stacks to provide details to the Kubernetes cluster for CloudFormation. Useful properties that can be provided are:
- OIDC Provider Arn
- Additional Security Groups
- Kubernetes Version
- Kubernetes Metadata
This can look something like the following within the output-only stack in which the stack is named after the Kubernetes cluster,
Resources:
OIDCArn:
Type: AWS::SSM::Parameter
Properties:
Name:
!Sub "${AWS::StackName}-eks-oidc-arn"
Type: String
Value: arn:aws:iam::012345678901:oidc-provider/oidc.eks.us-east-2.amazonaws.com/id/7185F12D2B62B8DA97B0ECA713F66C86
Outputs:
OIDCArn:
Value:
!Ref OIDCArn
Export:
Name:
'Fn::Sub': '${AWS::StackName}-eks-oidc-arn'
This can then be used within other CloudFormation stacks using ImportValue
and resolve:ssm
, and should any attempt be made to remove the output or delete the stack, it will fail with an error that Export ...-eks-oidc-arn cannot be deleted as it is in use by <stackname>
.
The CloudFormation for importing the value is:
Outputs:
ArnForIAMRole:
Value:
Fn::Sub:
- "{{resolve:ssm:/${Stack}}}"
- Stack:
Fn::ImportValue: 'eks-myclustername-eks-oidc-arn'