I’ve recently been working on a project that uses AWS EKS managed Kubernetes Service.
For various reasons too complicated to go into here we’ve ended up with multiple clusters owned by different AWS Accounts so flipping back and forth between them has been a little trickier than normal.
Here are my notes on how to manage the AWS credentials and the kubectl
config to access each cluster.
AWS CLI
First task is to authorise the AWS CLI to act as the user in question. We do this by creating a user with the right permissions in the IAM console and then export the Access key ID and Secret access key values usually as a CSV file. We then take these values and add them to the ~/.aws/credentials
file.
[dev]
aws_access_key_id = AKXXXXXXXXXXXXXXXXXX
aws_secret_access_key = xyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxy
[test]
aws_access_key_id = AKYYYYYYYYYYYYYYYYYY
aws_secret_access_key = abababababababababababababababababababab
[prod]
aws_access_key_id = AKZZZZZZZZZZZZZZZZZZ
aws_secret_access_key = nmnmnmnmnmnmnmnmnmnmnmnmnmnmnmnmnmnmnmnm
We can pick which set of credential the AWS CLI uses by adding the --profile
option to the command line.
$ aws --profile dev sts get-caller-identity
{
"UserId": "AIXXXXXXXXXXXXXXXXXXX",
"Account": "111111111111",
"Arn": "arn:aws:iam::111111111111:user/dev"
}
Instead of using the --profile
option you can also set the AWS_PROFILE
environment variable. Details of all the ways to switch profiles are in the docs here.
$ export AWS_PROFILE=test
$ aws sts get-caller-identity
{
"UserId": "AIYYYYYYYYYYYYYYYYYYY",
"Account": "222222222222",
"Arn": "arn:aws:iam::222222222222:user/test"
}
Now we can flip easily between different AWS accounts we can export the EKS credential with
$ export AWS_PROFILE=prod
$ aws eks update-kubeconfig --name foo-bar --region us-east-1
Updated context arn:aws:eks:us-east-1:333333333333:cluster/foo-bar in /home/user/.kube/config
The user that created the cluster should also follow these instructions to make sure the new account is added to the cluster’s internal ACL.
Kubectl
If we run the previous command with each profile it will add the connection information for all 3 clusters to the ~/.kube/config
file. We can list them with the following command
$ kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
* arn:aws:eks:us-east-1:111111111111:cluster/foo-bar arn:aws:eks:us-east-1:111111111111:cluster/foo-bar arn:aws:eks:us-east-1:111111111111:cluster/foo-bar
arn:aws:eks:us-east-1:222222222222:cluster/foo-bar arn:aws:eks:us-east-1:222222222222:cluster/foo-bar arn:aws:eks:us-east-1:222222222222:cluster/foo-bar
arn:aws:eks:us-east-1:333333333333:cluster/foo-bar arn:aws:eks:us-east-1:333333333333:cluster/foo-bar arn:aws:eks:us-east-1:333333333333:cluster/foo-bar
The star is next to the currently active context, we can change the active context with this command
$ kubectl config set-context arn:aws:eks:us-east-1:222222222222:cluster/foo-bar
Switched to context "arn:aws:eks:us-east-1:222222222222:cluster/foo-bar".
Putting it all together
To automate all this I’ve put together a collection of script that look like this
export AWS_PROFILE=prod
aws eks update-kubeconfig --name foo-bar --region us-east-1
kubectl config set-context arn:aws:eks:us-east-1:222222222222:cluster/foo-bar
I then use the shell source ./setup-prod
command (or it’s shortcut . ./setup-prod
) , this is instead of adding the shebang to the top and running it as a normal script. This is because when environment variables are set in scripts they go out of scope. Leaving the AWS_PROFILE
variable in scope means that the AWS CLI will continue to use the correct account settings when it’s used later while working on this cluster.