Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass AWS credentials (IAM role credentials) to code running in docker container

When running code on an EC2 instance, the SDK you use to access AWS resources, automagically talks to a locally linked web server on 169.254.169.254 and gets that instances AWS credentials(access_key, secret) that are needed to talk to other AWS services.

Also there are other options, like setting the credentials in ENV variables or passing them as command line args ...

What is the best practice here? I really prefer to let the container access the 169.254.169.254 (by routing the requests) or even better run a proxy container that mimics the behavior of the real server at 169.254.169.254.

Is there already a solution out there?

like image 717
Ali Avatar asked Sep 18 '14 11:09

Ali


People also ask

How do I pass AWS credentials to Docker container?

RUN pip install awscli RUN --mount=type=secret,id=aws,target=/root/. aws/credentials aws s3 cp s3://... ... And you build it with a command in 18.09 or newer like: DOCKER_BUILDKIT=1 docker build -t your_image --secret id=aws,src=$HOME/.

How do I pass my AWS credentials?

command line options: specify region, output format, or profile. Environment variables: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and AWS_SESSION_TOKEN. The AWS credentials file – located at ~/. aws/credentials on Linux, macOS, or Unix, or at C:\Users\USERNAME .

How do I pass an environment variable in Docker run?

With a Command Line Argument The command used to launch Docker containers, docker run , accepts ENV variables as arguments. Simply run it with the -e flag, shorthand for --env , and pass in the key=value pair: sudo docker run -e POSTGRES_USER='postgres' -e POSTGRES_PASSWORD='password' ...

What is -- RM in Docker run?

The --rm causes Docker to automatically remove the container when it exits. The image being used to create the container is generally specified as <name>:<tag> such as ruby:latest . If the specified image is not available locally, Docker will attempt to retrieve it from Docker Hub (or any connected Docker registry).


2 Answers

The EC2 metadata service will usually be available from within docker (unless you use a more custom networking setup - see this answer on a similar question).

If your docker network setup prevents it from being accessed, you might use the ENV directive in your Dockerfile or pass them directly during run, but keep in mind that credentials from IAM roles are automatically rotated by AWS.

like image 198
dcro Avatar answered Oct 22 '22 12:10

dcro


Amazon does have some mechanisms for allowing containers to access IAM roles via the SDK and either routing/forwarding requests through the ECS agent container or the host. There is way too much to copy and paste, but using --net host is the LEAST recommended option because without additionally filters that allows your container full access to anything it's host has permission to do.

https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-iam-roles.html

declare -a ENVVARS
declare AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN
get_aws_creds_local () {
   # Use this to get secrets on a non AWS host assuming you've set credentials via some mechanism in the past, and then don't pass in a profile to gitlab-runner because it doesn't see the ~/.aws/credentials file where it would look up profiles
   awsProfile=${AWS_PROFILE:-default}
   AWS_ACCESS_KEY_ID=$(aws --profile $awsProfile configure get aws_access_key_id)
   AWS_SECRET_ACCESS_KEY=$(aws --profile $awsProfile configure get aws_secret_access_key)
   AWS_SESSION_TOKEN=$(aws --profile $awsProfile configure get aws_session_token)
   
}

get_aws_creds_iam () {
  TEMP_ROLE=$(aws sts assume-role --role-arn "arn:aws:iam::123456789012:role/example-role" --role-session-name AWSCLI-Session)
  AWS_ACCESS_KEY_ID=$(echo $TEMP_ROLE | jq -r . Credentials.RoleAccessKeyID)
  AWS_SECRET_ACCESS_KEY=$(echo $TEMP_ROLE | jq -r . Credentials.RoleSecretKey)
  AWS_SESSION_TOKEN=$(echo $TEMP_ROLE | jq -r . Credentials.RoleSessionToken)
}

get_aws_creds_local

get_aws_creds_iam

ENVVARS=("AWS_ACCESS_KEY_ID=$ACCESS_KEY_ID" "AWS_SECRET_ACCESS_KEY=$ACCESS_SECRET_ACCESS_KEY" "AWS_SESSION_TOKEN=$AWS_SESSION_TOKEN")

# passing creds into GitLab runner
 gitlab-runner exec docker stepName $(printf " --env %s" "${ENVVARS[@]}")

# using creds with a docker container
docker run -it --rm $(printf " --env %s" "${ENVVARS[@]}") amazon/aws-cli sts get-caller-identity
like image 29
dragon788 Avatar answered Oct 22 '22 11:10

dragon788