Integralist
Integralist

Reputation: 6185

Env variables not persisting in parent shell

I have the following bash script that attempts to automate the assuming of an AWS role (I've obviously removed the various private settings):

#! /bin/bash
#
# Dependencies:
#   brew install jq
#
# Execute:
#   source aws-cli-assumerole.sh

unset AWS_SESSION_TOKEN
export AWS_ACCESS_KEY_ID=<user_access_key>
export AWS_SECRET_ACCESS_KEY=<user_secret_key>

temp_role=$(aws sts assume-role \
                    --role-arn "arn:aws:iam::<aws_account_number>:role/<role_name>" \
                    --role-session-name "<some_session_name>")

export AWS_ACCESS_KEY_ID=$(echo $temp_role | jq .Credentials.AccessKeyId)
export AWS_SECRET_ACCESS_KEY=$(echo $temp_role | jq .Credentials.SecretAccessKey)
export AWS_SESSION_TOKEN=$(echo $temp_role | jq .Credentials.SessionToken)

env | grep -i AWS_

I have to execute this script using source because otherwise if I use standard bash or sh the exported environment variables are not available within the parent shell executing this script.

The problem is, even when using source it doesn't work; and by that I mean: the environment variables AND their correct/updated values are showing in the parent shell (if I execute env | grep AWS_ I can see the correct values).

If I then try to use the AWS CLI tools (e.g. aws s3 ls - to list all s3 buckets within the specific account I've assumed the role for) it'll report back that the access key is invalid.

BUT, if I manually copy and paste the environment variable values and re-export them in the parent shell (effectively overwriting them with the exact same values that are already set), then the AWS CLI command will work - but I do not know why. What's different?

Upvotes: 4

Views: 1058

Answers (2)

Mac
Mac

Reputation: 11

Another way to assume an AWS role:

Write a profile, which automatically assumes the role.

aws configure --profile new-profile set arn:aws:iam::<aws_account_number>:role/<role_name> 

To give credentials to the new profile, you must use one of the following lines:

  1. aws configure --profile new-profile set source_profile default
  2. aws configure --profile new-profile set credential_sourceEc2InstanceMetadata
  3. aws configure --profile new-profile set credential_source EcsContainer

Line 1 was correct on my personal pc, because I used the default profile. Line 3 was correct when I tested the code with AWS CodeBuild. The new profile used the credentials of the codepipeline-role.

Afterwards, you may use the new profile, example: aws --profile new-profile s3 ls s3://bucket-in-target-account

Documentation: https://docs.aws.amazon.com/cli/latest/topic/config-vars.html#using-aws-iam-roles

Upvotes: 0

Shane
Shane

Reputation: 477

jq .Blah will return the output quoted.

So for example export AWS_ACCESS_KEY_ID=$(echo $temp_role | jq .Credentials.AccessKeyId) Will result "KEY" instead what you need is just KEY which is why your xargs works in your comment.

If you use the -r flag for raw with jq you will get the result you want export AWS_ACCESS_KEY_ID=$(echo $temp_role | jq -r .Credentials.AccessKeyId)

Upvotes: 1

Related Questions