You possibly can automate the OIDC and IAM roles creation if you provision EKS cluster by Terraform or CloudFormatio however what if you wish to automate the creation of OIDC and IAM roles when creating the EKS cluster by Rancher!
What if you wish to use a crossplane to create AWS assets from a brand new EKS cluster, how does crossplane get entry to the cluster, now we face a chicken-egg downside.
On this article, I’m going to indicate you the best way to Automate the method as soon as the EKS cluster is created.
We want OIDC and IAM roles to make use of service accounts in Kubernetes to get entry to AWS assets like S3, SQS,SNS ..and many others
AWS is really helpful to make use of service accounts fairly than utilizing
static ACCESS KEY and SECRET KEY inside your pods.
Within the structure diagram when a brand new EKS cluster is created then it would ship an occasion to the occasion bridge after which we added a rule to invoke lambda solely when the occasion title is CreateNodegroup or DeleteCluster.
You’ll ask why the occasion title just isn’t CreateCluster as a result of we’re concerned about values after the cluster is created, the creation of the cluster takes round 8 minutes.
Steps:
1- Go to lambda service -> Create operate -> Add “eks-iam” within the Perform title -> Creator from scratch -> select Runtime Python 3.8 -> Create a brand new position with fundamental Lambda permissions -> Create operate
2- Create IAM a coverage eks-iam-policy and add the under coverage
{
"Model": "2012-10-17",
"Assertion": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"iam:UntagRole",
"iam:TagRole",
"iam:CreateRole",
"iam:DeleteRole",
"iam:AttachRolePolicy",
"iam:CreateOpenIDConnectProvider",
"iam:DetachRolePolicy",
"iam:ListAttachedRolePolicies",
"eks:DescribeCluster",
"iam:UntagOpenIDConnectProvider",
"eks:ListClusters",
"iam:DeleteOpenIDConnectProvider",
"iam:TagOpenIDConnectProvider"
],
"Useful resource": "*"
}
]
}
3- Connect the coverage to the lambda Execution position, go to lambda eks-iam operate -> Configuration -> Permissions -> Execution position -> click on on Position title eks-iam-role-XXXX -> connect coverage eks-iam-policy
4- Add the under code to eks-iam lambda operate
import json
import boto3
# through which namespace that utilized by the service account
namespace="default"
# iam insurance policies
insurance policies = ['arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess']
iam = boto3.consumer('iam')
def create_role(roleName,coverage):
response = iam.create_role(
RoleName=roleName,
AssumeRolePolicyDocument=json.dumps(coverage),
Description='Lambda invoked by Rancher occasion to Create this Position',
MaxSessionDuration=3600,
Tags=[
{
'Key': 'Created-By',
'Value': 'Lambda'
},
]
)
return response
def lambda_handler(occasion, context):
if occasion['detail']['eventName'] == "CreateNodegroup":
clusterName = occasion['detail']['responseElements']['nodegroup']['clusterName']
eks = boto3.consumer('eks')
eksResponse = eks.describe_cluster(title=clusterName)
oidc = eksResponse['cluster']['identity']['oidc']['issuer']
# create oidc supplier
oidcResponse = iam.create_open_id_connect_provider(Url=oidc,
ClientIDList=['sts.amazonaws.com',],
ThumbprintList=['9e99a48a9960b14926bb7f3b02e22da2b0ab7280',],
Tags=[{ 'Key': 'Created-By', 'Value': 'Lambda' }, ])
arn = oidcResponse['OpenIDConnectProviderArn']
coverage = { "Model": "2012-10-17","Assertion": [ {"Sid": "", "Effect": "Allow", "Principal": { "Federated": arn}, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { arn.split('oidc-provider/')[1] +":sub": "system:serviceaccount:" + namespace + ":" + clusterName }}}]}
# create iam position
createResponse = create_role (clusterName, coverage)
print(createResponse)
# connect insurance policies to the position
for i in vary(len(insurance policies)):
iam.attach_role_policy(
RoleName=clusterName,
PolicyArn= insurance policies[i]
)
return oidcResponse
elif occasion['detail']['eventName'] == "DeleteCluster":
clusterName = occasion['detail']['responseElements']['cluster']['name']
oidc = occasion['detail']['responseElements']['cluster']['identity']['oidc']['issuer']
accountId = occasion['detail']['userIdentity']['accountId']
arn = "arn:aws:iam::" + accountId + ":oidc-provider/" + oidc.cut up('https://')[1]
# take away oidc supplier
oidcResponse = iam.delete_open_id_connect_provider(
OpenIDConnectProviderArn=arn
)
# get all insurance policies connected to the position
policyResponse = iam.list_attached_role_policies(
RoleName=clusterName
)
# detach all insurance policies from the position
for i in vary(len(policyResponse['AttachedPolicies'])):
iam.detach_role_policy(
RoleName=clusterName, PolicyArn=policyResponse['AttachedPolicies'][i]['PolicyArn']
)
# take away the iam position
roleResponse = iam.delete_role(
RoleName=clusterName
)
return oidcResponse
5- Go to EventBridge -> Guidelines -> Create Rule -> Rule with an occasion sample -> Within the Occasion sample, select Customized patterns (JSON editor) and add the next:
{
"supply": ["aws.eks"],
"detail-type": ["AWS API Call via CloudTrail"],
"element": {
"eventSource": ["eks.amazonaws.com"],
"eventName": ["CreateNodegroup", "DeleteCluster"]
}
}
Select goal -> AWS service -> Choose a goal -> Lambda operate -> Perform -> eks-iam
6- Create a service account in your EKS cluster, now we will know the arn of our IAM position since you solely change the EKS-CLUSTER-NAME.
Trace: I assumed you’ve got a novel title for EKS clusters
---
apiVersion: v1
form: ServiceAccount
metadata:
title: list-s3
namespace: default
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::AWS-ACCOUNT-NUMBER:position/EKS-CLUSTER-NAME
7- Create a deployment and outline the service account title like the instance under
---
apiVersion: apps/v1
form: Deployment
metadata:
title: aws-cli
namespace: default
spec:
selector:
matchLabels:
app: aws-cli
replicas: 1
template:
metadata:
labels:
app: aws-cli
spec:
serviceAccountName: list-s3
containers:
- title: aws-cli
picture: amazon/aws-cli
command: [ "/bin/bash", "-c", "--" ]
args: [ "while true; do sleep 30; done;" ]
now you may entry your pod and take a look at it by:
aws s3 ls
In the long run, you may have a default coverage that’s connected for every EKS cluster after which use instruments like crossplane to create a selected IAM insurance policies and roles.