IRSA Role
Before running the script, check if an IAM role and policy already exist with the names listed below. If these names exist, delete the policy and role before running the commands.
- Role: rafay-ecr-irsa-role
- Policy: rafay-ecr-irsa-policy
Create the createIRSA-AMPIngest.sh file (see below), then run the commands. Replace <eks-cluster-name>
with the name of the EKS cluster. Replace <region>
with the region the cluster belongs to.
chmod +x ./createIRSA-AMPIngest.sh
bash ./createIRSA-AMPIngest.sh -c <eks-cluster-name> -r <region>
IRSA Script¶
The script createIRSA-AMPIngest.sh
.
#!/bin/bash -e
while getopts c:r: flag
do
case "${flag}" in
c) CLUSTER_NAME=${OPTARG};;
r) REGION=${OPTARG};;
esac
done
SERVICE_ACCOUNT_NAMESPACE=rafay-registry
AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query "Account" --output text)
OIDC_PROVIDER=$(aws eks describe-cluster --name $CLUSTER_NAME --region $REGION --query "cluster.identity.oidc.issuer" --output text | sed -e "s/^https:\/\///")
SERVICE_ACCOUNT_ECR_ROLE=rafay-ecr-irsa-role
SERVICE_ACCOUNT_ECR_POLICY=rafay-ecr-irsa-policy
#
# Set up a trust policy designed for a specific combination of K8s service account and namespace to sign in from a Kubernetes cluster which hosts the OIDC Idp.
#
cat <<EOF > TrustPolicy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::${AWS_ACCOUNT_ID}:oidc-provider/${OIDC_PROVIDER}"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"${OIDC_PROVIDER}:aud": "sts.amazonaws.com",
"${OIDC_PROVIDER}:sub": ["system:serviceaccount:${SERVICE_ACCOUNT_NAMESPACE}:nexus-registry","system:serviceaccount:${SERVICE_ACCOUNT_NAMESPACE}:sa-health-check"]
}
}
}
]
}
EOF
#
# Set up the permission policy that grants ingest (remote write) permissions for all AMP workspaces
#
cat <<EOF > PermissionPolicyIngest.json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ListImagesInRepository",
"Effect": "Allow",
"Action": [
"ecr:ListImages",
"ecr:BatchGetImage",
"ecr:GetDownloadUrlForLayer"
],
"Resource": "arn:aws:ecr:${REGION}:${AWS_ACCOUNT_ID}:repository/rafay/*"
},
{
"Sid": "GetAuthorizationToken",
"Effect": "Allow",
"Action": [
"ecr:GetAuthorizationToken"
],
"Resource": "*"
}
]
}
EOF
function getRoleArn() {
OUTPUT=$(aws iam get-role --role-name $1 --query 'Role.Arn' --output text 2>&1)
# Check for an expected exception
if [[ $? -eq 0 ]]; then
echo $OUTPUT
elif [[ -n $(grep "NoSuchEntity" <<< $OUTPUT) ]]; then
echo ""
else
>&2 echo $OUTPUT
return 1
fi
}
#
# Create the IAM Role for ingest with the above trust policy
#
SERVICE_ACCOUNT_ECR_ROLE_ARN=$(getRoleArn $SERVICE_ACCOUNT_ECR_ROLE)
if [ "$SERVICE_ACCOUNT_ECR_ROLE_ARN" = "" ];
then
#
# Create the IAM role for service account
#
SERVICE_ACCOUNT_ECR_ROLE_ARN=$(aws iam create-role \
--role-name $SERVICE_ACCOUNT_ECR_ROLE \
--assume-role-policy-document file://TrustPolicy.json \
--query "Role.Arn" --output text)
#
# Create an IAM permission policy
#
SERVICE_ACCOUNT_ECR_ARN=$(aws iam create-policy --policy-name $SERVICE_ACCOUNT_ECR_POLICY \
--policy-document file://PermissionPolicyIngest.json \
--query 'Policy.Arn' --output text)
#
# Attach the required IAM policies to the IAM role created above
#
aws iam attach-role-policy \
--role-name $SERVICE_ACCOUNT_ECR_ROLE \
--policy-arn $SERVICE_ACCOUNT_ECR_ARN
else
echo "$SERVICE_ACCOUNT_ECR_ROLE_ARN IAM role for ingest already exists"
fi
echo $SERVICE_ACCOUNT_ECR_ROLE_ARN
#
# EKS cluster hosts an OIDC provider with a public discovery endpoint.
# Associate this IdP with AWS IAM so that the latter can validate and accept the OIDC tokens issued by Kubernetes to service accounts.
# Doing this with eksctl is the easier and best approach.
#
eksctl utils associate-iam-oidc-provider --cluster $CLUSTER_NAME --approve