Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for AWS STS AssumeRole is required in the aws-cli docker image #6475

Open
vinod827 opened this issue Oct 13, 2021 · 5 comments
Open
Assignees
Labels
assume-role docker Issue involves the AWS CLI Docker container image feature-request A feature should be added or improved. p3 This is a minor priority issue

Comments

@vinod827
Copy link

Is your feature request related to a problem? Please describe.
I have written my own docker image using AmazonLinux:2 as base image and then customized that to have aws-cli library. I was passing the .aws credentials as a volume mount to that container so that it can used and to assume role using the AWS STS service.

Can we have similar thing in this aws-cli docker image, where by passing the .aws credentials as volume mount, I can assumerole and can get temporary credentials set.

This is my solution snippet in my customized docker image:-

FROM amazonlinux:2 as dev
# ---------------------------------------------------------------------------- #
#                                Install AWS CLI                               #
# ---------------------------------------------------------------------------- #
# For SAM CLI
ARG SAM_CLI_VERSION=${SAM_CLI_VERSION:-1.1.0}
RUN set -eux; \
  curl -fsSL https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip -o awscliv2.zip; \
  unzip -qq awscliv2.zip; \
  ./aws/install -i /usr/local/lib/aws ; \
  # put it in .bashrc file
  # https://github.com/aws/aws-cli/issues/4950
  # complete -C '/usr/local/aws/bin/aws_completer' aws
  # aws cli cleanup
  rm -rf awscliv2.zip ./aws; \
  # Install SAM CLI in a dedicated Python virtualenv
  curl -fsSLk https://github.com/awslabs/aws-sam-cli/archive/v$SAM_CLI_VERSION.zip -o samcli.zip; \
  unzip -qq samcli.zip; \
  python3 -m venv /usr/local/lib/sam-cli; \
  /usr/local/lib/sam-cli/bin/pip3 --no-cache-dir install -r ./aws-sam-cli-$SAM_CLI_VERSION/requirements/reproducible-linux.txt; \
  /usr/local/lib/sam-cli/bin/pip3 --no-cache-dir install ./aws-sam-cli-$SAM_CLI_VERSION; \
  # cleanup
  rm -rf samcli.zip aws-sam-cli-${SAM_CLI_VERSION}; \
  echo ""

# add sam cli to PATH
ENV PATH=$PATH:/usr/local/lib/sam-cli/bin

COPY ./assume-role.sh .
RUN ["chmod", "+x", "assume-role.sh"]
ENTRYPOINT ["/assume-role.sh"]
CMD ["bash", "--"]

In my dockerfile, I'm passing an assume-role.sh file where I'm trying to generate the temporary credentials using AWS STS assumerole by using the .aws credentials mounted as a volume to it.

#!/usr/bin/env bash
#echo Your container args are: "${1} ${2} ${3}"
echo Your container args are: "${1}"
ROLE_ARN="${1}"
AWS_DEFAULT_REGION="${2:-us-east-1}"
SESSIONID=$(date +"%s")
DURATIONSECONDS="${3:-3600}"

# AWS STS AssumeRole
RESULT=(`aws sts assume-role --role-arn $ROLE_ARN \
        --role-session-name $SESSIONID \
  --duration-seconds $DURATIONSECONDS \
        --query '[Credentials.AccessKeyId,Credentials.SecretAccessKey,Credentials.SessionToken]' \
        --output text`)

# Setting up temporary creds
export AWS_ACCESS_KEY_ID=${RESULT[0]}
export AWS_SECRET_ACCESS_KEY=${RESULT[1]}
export AWS_SECURITY_TOKEN=${RESULT[2]}
export AWS_SESSION_TOKEN=${AWS_SECURITY_TOKEN}
echo 'AWS STS AssumeRole completed successfully'

# Making test AWS API calls
aws s3 ls
echo 'test calls completed'

So, the new feature request from my side is to have out of box capability of assuming a role by just passing AWS Role ARN while running the container where .aws credentials is mounted as a volume to the container in this aws-cli docker image as there are many use cases where this is a good fit.

Thank you

@vinod827 vinod827 added feature-request A feature should be added or improved. needs-triage This issue or PR still needs to be triaged. labels Oct 13, 2021
@kdaily kdaily self-assigned this Oct 14, 2021
@kdaily kdaily added investigating This issue is being investigated and/or work is in progress to resolve the issue. and removed needs-triage This issue or PR still needs to be triaged. labels Oct 14, 2021
@kdaily
Copy link
Member

kdaily commented Oct 14, 2021

Hi @vinod827,

Thanks for your post. The AWS CLI already supports this through named profiles. If you have a profile with a role_arn parameter set in it, you don't need to run any other assume role calls. Instead of passing in a role ARN, you could pass in a profile name to assume.

You can read more about this here:

https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-role.html

There is support for using a role ARN through an environment variable AWS_ROLE_ARN, but this is only for assuming a role through a web identity with OIDC.

There is an open feature request to add support for AWS_ROLE_ARN to the standard assume role, but it was not added already because this makes role chaining more complicated. Currently you can 'link' profiles together to assume a role multiple times. If this is of interest to you, please add your 👍🏻 reaction to the initial comment and provide your use cases here:

#5639

@kdaily kdaily added response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. and removed investigating This issue is being investigated and/or work is in progress to resolve the issue. labels Oct 14, 2021
@vinod827
Copy link
Author

Hi @kdaily, thanks for addressing my concern and also sharing this useful information. I have gone through with the AWS doc link and I must admit that I was looking for such a feature only which is already given out of the box by AWS for assuming a role.
👍🏻
My use case was around Jenkins build agent running as a Docker container to deploy the application in a multi-account AWS architecture where I just have to pass the Role ARN (in this case --profile) besides volume mounting the .aws credential folder on the host to get the temporary credentials for Jenkins to deploy the app in different AWS accounts.

Thank you and really appreciated :)

@github-actions github-actions bot removed the response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. label Oct 16, 2021
@dPowNextdoor
Copy link

dPowNextdoor commented Dec 8, 2021

I agree with @vinod827. It's nearly impossible to do any sort of configuration when using the Docker image. There exists no $HOME/.aws/ directory to mount when running in non-user environments (e.g. CI pipelines), and running in user environments forces users to configure everything themselves before running any Docker command. This all happens even if environment variables are set.

Specifically, the Precedence of options section of the Environment variables to configure AWS CLI docs explicitly say:

If you specify an option by using one of the environment variables described in this topic, it overrides any value loaded from a profile in the configuration file.

Yet, the command below still fails with The config profile (myProfile) could not be found because a config file is required even though everything is already specified in env vars (which means the config/credentials files would be useless anyway).

docker run -it --rm \
    -e AWS_PROFILE=${AWS_PROFILE} \
    -e AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID} \
    -e ... \
    amazon/aws-cli iam get-user

This is made even worse because we can't run multiple commands with your Docker container (e.g. docker run ... amazon/aws-cli 'configure && iam get-user' with/out quotes).

It is extremely important to fix this! That probably means fixing the aws command itself to work as you said it would by checking for command flags first, then for environment variables only if flags don't exist, then for config/credentials file entries only if neither exists. However, if that fix will take a long time, then adding some patch in the amazon/aws-cli Dockerfile would be an acceptable temporary fix to get something out ASAP while we wait for the aws command to be fixed.

FWIW: As it stands now, we have to make a whole bunch of hacky workarounds to deal with this in both:

  • Pipelines
run: 
  echo "bunchOfConfigStrings" > $HOME/.aws/credentials
  docker run -v $HOME/.aws:/root/.aws ...
  • Local environments (simplified)
docker run -e ... --entrypoint bash amazon/aws-cli -c '
mkdir /root/.aws;
echo "[$AWS_PROFILE]" > /root/.aws/credentials;
(
    unset AWS_PROFILE;
    for envVar in $(compgen -v AWS); do
        echo "$envVar ${!envVar}" | awk "{ printf \"%s = %s\n\", tolower(\$1), \$2 }";
    done;
) >> /root/.aws/credentials;
aws iam get-user
'

@kdaily
Copy link
Member

kdaily commented Dec 9, 2021

Hi @dPowNextdoor,

Thanks for your comments. I'm not sure I follow though. A configuration and credential file are not required. The reason the command you supplied is failing is because you specified -e AWS_PROFILE=${AWS_PROFILE} but didn't mount something at /root/.aws. If you do not specify this and only configure the secret ID, secret key, and region, the command will work without any configuration or credential file.

You can use the command aws configure list to see where configuration values are coming from. Here's what I get if I don't specify a profile, don't mount any files, and do everything with environment variables:

> docker run -it --rm \
    -e AWS_ACCESS_KEY_ID="****************CNPE" \
    -e AWS_SECRET_ACCESS_KEY="****************4Sp2" \
    -e AWS_REGION="us-east-2" \
    amazon/aws-cli configure list

      Name                    Value             Type    Location
      ----                    -----             ----    --------
   profile                <not set>             None    None
access_key     ****************CNPE              env
secret_key     ****************4Sp2              env
    region                us-east-2              env    ['AWS_REGION', 'AWS_DEFAULT_REGION']

I can also mount my config file and override specific settings while getting the defaults, just as described in the documentation. For example, I can specify my access key and secret key, but get the region from the profile, which I set to us-west-2:

docker run --rm -it -v ~/.aws:/root/.aws \
    -e AWS_PROFILE='default' \
    -e AWS_ACCESS_KEY_ID="****************CNPE" \
    -e AWS_SECRET_ACCESS_KEY="****************4Sp2" \
    amazon/aws-cli configure list

      Name                    Value             Type    Location
      ----                    -----             ----    --------
   profile                  default              env    ['AWS_PROFILE', 'AWS_DEFAULT_PROFILE']
access_key     ****************CNPE              env
secret_key     ****************4Sp2              env
    region                us-west-2      config-file    ~/.aws/config

@kdaily
Copy link
Member

kdaily commented Dec 9, 2021

@dPowNextdoor,

As a followup, I think this is the frustration you're experiencing. The docs on precedence state:

Credentials from environment variables have precedence over credentials from the shared credentials and AWS CLI config file. Credentials specified in the shared credentials file have precedence over credentials in the AWS CLI config file. If AWS_PROFILE environment variable is set and the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables are set, then the credentials provided by AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY will override the credentials located in the profile provided by AWS_PROFILE.

Unfortunately, for backwards compatibility, we cannot change how these environment variables interact, as explained in that issue here: #3304 (comment)

@tim-finnigan tim-finnigan added assume-role docker Issue involves the AWS CLI Docker container image p3 This is a minor priority issue labels Nov 7, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
assume-role docker Issue involves the AWS CLI Docker container image feature-request A feature should be added or improved. p3 This is a minor priority issue
Projects
None yet
Development

No branches or pull requests

4 participants