aws-actions / configure-aws-credentials

Configure AWS credential environment variables for use in other GitHub Actions.
MIT License
2.43k stars 466 forks source link

Multiple profiles #112

Open tb102122 opened 4 years ago

tb102122 commented 4 years ago

Is it possible to also setup multiple profiles which can be used?

peterkline-es commented 4 years ago

This would be extremely valuable for self-hosted runners where we have a single named user but it doesn't different things in different accounts

ssannidhi-palo commented 3 years ago

Usecase: We are using terraform to setup our infrastructure in multiple aws accounts(one account for PROD, one account for non-prod envs). We maintain the state file of each env in S3 bucket of respective account. Prod env needs to access resources that are in a different aws account. Terraform provides a way to access remote state files present in s3 bucket of another aws account using "terraform_remote_state" with "profile".

data "terraform_remote_state" "env-GLOBAL" { backend = "s3"

config = { profile = "demo" bucket = "xxx" key = "global/terraform.tfstate" region = local.region } }

To run the terraform scripts through Github Actions for such a use case, it would be very helpful if aws-actions/configure-aws-credentials provides a way to configure multiple profiles.

Startouf commented 3 years ago

I believe this fits the issue, we have a project with a specific AWS profile name used with serverless (helps developers segregate their AWS credentials across multipleprojects), it would be nice to allow specifying the profile name when storing the Access key and secret access key

Currently we resort to the following

- name: Add profile credentials to ~/.aws/credentials
   env:
      AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
      AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
   run: |
      aws configure set aws_access_key_id $AWS_ACCESS_KEY_ID --profile my-app-name
      aws configure set aws_secret_access_key $AWS_SECRET_ACCESS_KEY --profile my-app-name
dennis-tra commented 3 years ago

This could be made more concise:

- name: Add profile credentials to ~/.aws/credentials 
   run: |
      aws configure set aws_access_key_id ${{ secrets.AWS_ACCESS_KEY_ID }} --profile my-app-name
      aws configure set aws_secret_access_key ${{ secrets.AWS_SECRET_ACCESS_KEY }} --profile my-app-name

For anyone else who comes across this issue and is concerned about printing the secrets to the console. GitHub is redacting the output (source):

Warning: GitHub automatically redacts secrets printed to the log, but you should avoid printing secrets to the log intentionally.

Well, here we're doing it kind of intentionally 🤷‍♂️

gastonsilva commented 2 years ago

Extending @dennis-tra answer, you should also add: aws configure set aws_session_token ${{ secrets.AWS_SESSION_TOKEN }} --profile my-app-name for this to work

peterwoodworth commented 1 year ago

I'm having trouble figuring out exactly how this would work with this action. When people want this action to support multiple profiles, how would you expect it to accomplish that? What is a sample input you could provide?

pecigonzalo commented 1 year ago

@peterwoodworth I think something like this would be ideal and simple:

    - name: Configure AWS credentials from Test account
      uses: aws-actions/configure-aws-credentials@v1
      with:
        role-to-assume: arn:aws:iam::111111111111:role/my-github-actions-role-test
        aws-region: us-east-1
        profile: foo

To be honest, I think overall supporting profile configs would be great.

We are currently emulating this with something like:

      - name: Configure AWS Profile
        run: |
          curl -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" "$ACTIONS_ID_TOKEN_REQUEST_URL&audience=sts.amazonaws.com" | jq -r '.value' > ~/.aws/web_identity_token_file
          aws configure set region eu-central-1 --profile foo
          aws configure set role_arn "arn:aws:iam::123123123:role/foo" --profile foo
          aws configure set web_identity_token_file "~/.aws/web_identity_token_file" --profile foo

but this is fairly rudimentary

pecigonzalo commented 1 year ago

I've created a draft of this (not fully integrated) in https://github.com/aws-actions/configure-aws-credentials/pull/557

It creates a exportCredentialsToConfig that can add/modify profiles in ~/.aws/config to configure different profiles.

If this is an approach you would be happy with, Im happy to finish the code and ready the PR.

pecigonzalo commented 1 year ago

@rafaelfuchs-mb are you asking about my solution or which one? If you are talking about what I linked in https://github.com/aws-actions/configure-aws-credentials/issues/112#issuecomment-1273757307, your workflow is not following my example, so it would not work.

rafaelfuchs-mb commented 1 year ago

You can ignore my comment... I was looking for a solution for multiple profiles with terraform, but it looks like something else is not working... I was able to get access to multiple profiles using aws cli, so my problem is actually in the terraform side. If that's ok, I can delete my previous comment.

pecigonzalo commented 1 year ago

@peterwoodworth let me know if the approach sounds good, so I can finalize the PR.

peterwoodworth commented 1 year ago

@pecigonzalo thanks for your patience, I'm hopping off for the day but I'll take a look tomorrow

GeertWille commented 1 year ago

@peterwoodworth @pecigonzalo any news regarding this issue and/or linked PR?

nsandary commented 1 year ago

I'm also interested in this functionality. We're building an action to synchronize RDS snapshots between multiple accounts, and it needs to access both accounts in the same workflow.

pecigonzalo commented 1 year ago

Im waiting on feedback from Peter

GeertWille commented 1 year ago

I created a PR to support this. Not sure or will be approved soon. In the meantime feel free to point to our branch and use it.

pecigonzalo commented 1 year ago

I mean, thanks for also taking a stab at it, glad to so a finalized solution. I would say tho that it's a bit rude to open a new PR @GeertWille given I had an open PR and was proposing a solution, and you even asked a question on my PR on how it works.

GeertWille commented 1 year ago

I mean, thanks for also taking a stab at it, glad to so a finalized solution. I would say tho that it's a bit rude to open a new PR @GeertWille given I had an open PR and was proposing a solution, and you even asked a question on my PR on how it works.

Euh woops, definitely didn't ment to step on toes here. I can close mine again. Just needed a working solution. If your PR works with only adding a config instead of config and credentials I think yours is better. Just didn't wanted to wait on feedback due to lack of activity here and I need to have this working.

pecigonzalo commented 1 year ago

All good @GeertWille, you have a working and final solution so lets go with that. Since no feedback was given, I did not develop further (not the first time I had a PR left hanging after spending a while on it).

Ill close mine, reference yours and see if we can get a merge. If I gather correctly, your PR writes the creds to the file even for OIDC, which is not necessary.

As you can see in https://github.com/aws-actions/configure-aws-credentials/issues/112#issuecomment-1273757307, you just have to configure ~/.aws/config to point to the web identity file.

eg. How I'm currently doing it.

    - name: Save WebIdentityTokenFile
      uses: actions/github-script@v6
      with:
        retries: 3
        script: |
          const fs = require("fs");

          webIdentityToken = await core.getIDToken("sts.amazonaws.com");
          webIdentityTokenFile = "/tmp/oidc-token";
          fs.writeFileSync(webIdentityTokenFile, webIdentityToken);

    - name: Configure AWS Profile
      shell: bash
      run: |
        aws configure set region "${{ inputs.region }}" --profile "${{ inputs.profile }}"
        aws configure set role_arn "${{ inputs.role-arn }}" --profile "${{ inputs.profile }}"
        aws configure set web_identity_token_file "/tmp/oidc-token" --profile "${{ inputs.profile }}"
        aws configure set duration_seconds "3600"
GeertWille commented 1 year ago

Still have an issue in my PR. Since the credentials are always exported it looks like precedence is given to the environment vars instead of the config files. So if you define 2 profiles. The last exported credentials are saved on the environment and used.

pecigonzalo commented 1 year ago

Yeah, I would not export env-vars when using profiles

woon-werd commented 1 year ago

this works for me:

use aws plugin to login:

    steps:
      - uses: actions/checkout@v3
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          role-to-assume: arn:aws:iam::${{ env.ACCOUNT }}:role/${{ env.roleName }}
          aws-region: ${{ env.REGION }}
          role-session-name: ${{ env.roleName }}

setup profile with credentials from plugin - the plugin above automatically set credentials to env.*


      - name: Setup Profile
        run: |
          aws configure set region ${{ env.REGION }} --profile ${{ env.profileName }}
          aws configure set aws_access_key_id ${{ env.AWS_ACCESS_KEY_ID }} --profile ${{ env.profileName }}
          aws configure set aws_secret_access_key ${{ env.AWS_SECRET_ACCESS_KEY }} --profile ${{ env.profileName }}
          aws configure set aws_session_token ${{ env.AWS_SESSION_TOKEN }} --profile ${{ env.profileName }}
stephendarling commented 1 year ago

this works for me:

use aws plugin to login:

    steps:
      - uses: actions/checkout@v3
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          role-to-assume: arn:aws:iam::${{ env.ACCOUNT }}:role/${{ env.roleName }}
          aws-region: ${{ env.REGION }}
          role-session-name: ${{ env.roleName }}

setup profile with credentials from plugin - the plugin above automatically set credentials to env.*

      - name: Setup Profile
        run: |
          aws configure set region ${{ env.REGION }} --profile ${{ env.profileName }}
          aws configure set aws_access_key_id ${{ env.AWS_ACCESS_KEY_ID }} --profile ${{ env.profileName }}
          aws configure set aws_secret_access_key ${{ env.AWS_SECRET_ACCESS_KEY }} --profile ${{ env.profileName }}
          aws configure set aws_session_token ${{ env.AWS_SESSION_TOKEN }} --profile ${{ env.profileName }}

@woon-werd, not sure if it's the same on aws-actions/configure-aws-credentials@v1 (I'm using aws-actions/configure-aws-credentials@v1-node16) but the environment variable exported for region is AWS_REGION, not REGION. Works otherwise, thanks for this!

mcblair commented 1 year ago

I'm standing on the shoulders of giants with this, but here is something that I whipped up to meet my use case: https://github.com/marketplace/actions/configure-aws-profile

woon-werd commented 1 year ago

this works for me: use aws plugin to login:

    steps:
      - uses: actions/checkout@v3
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          role-to-assume: arn:aws:iam::${{ env.ACCOUNT }}:role/${{ env.roleName }}
          aws-region: ${{ env.REGION }}
          role-session-name: ${{ env.roleName }}

setup profile with credentials from plugin - the plugin above automatically set credentials to env.*

      - name: Setup Profile
        run: |
          aws configure set region ${{ env.REGION }} --profile ${{ env.profileName }}
          aws configure set aws_access_key_id ${{ env.AWS_ACCESS_KEY_ID }} --profile ${{ env.profileName }}
          aws configure set aws_secret_access_key ${{ env.AWS_SECRET_ACCESS_KEY }} --profile ${{ env.profileName }}
          aws configure set aws_session_token ${{ env.AWS_SESSION_TOKEN }} --profile ${{ env.profileName }}

@woon-werd, not sure if it's the same on aws-actions/configure-aws-credentials@v1 (I'm using aws-actions/configure-aws-credentials@v1-node16) but the environment variable exported for region is AWS_REGION, not REGION. Works otherwise, thanks for this!

ah yes. I hardcoded a few on them on my github actions. these are the useful things exported from the plugin: env.AWS_ACCESS_KEY_ID env.AWS_SECRET_ACCESS_KEY env.AWS_SESSION_TOKEN

Just spotted them on the log line whenever the plugin finish its works.

kidpollo commented 1 year ago

I'm standing on the shoulders of giants with this, but here is something that I whipped up to meet my use case: https://github.com/marketplace/actions/configure-aws-profile

This solution WORKS. Thanks @mcblair I do still feel this should be part of this repo

jonworek commented 1 year ago

My use case was to create the profile which is being expected with the elastic beanstalk CLI which I'm using to deploy.

In the latest v2 version of the plugin, this is ultimately what I got to work:

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v2
        with: 
          role-to-assume: arn:aws:iam::1233456788:role/GitHubActionsRole
          aws-region: us-east-2

      - name: Add profile credentials to ~/.aws/credentials 
        run: |
          aws configure set aws_access_key_id ${{ env.AWS_ACCESS_KEY_ID }} --profile eb-cli
          aws configure set aws_secret_access_key ${{ env.AWS_SECRET_ACCESS_KEY }} --profile eb-cli
          aws configure set aws_session_token ${{ env.AWS_SESSION_TOKEN }} --profile eb-cli

Thanks to all of the folks that commented above that steered me in this direction.

Hronom commented 1 year ago

Please, someone complete the work for this repo, from user side such API will be very needed and usable for terraform etc.

      - name: Configure AWS Credentials for profile-a
        uses: aws-actions/configure-aws-credentials@v2
        with:
          role-to-assume: ${{ inputs.profile_a_aws_arn }}
          aws-region: ${{ inputs.region }}
          profile: profile-a

      - name: Configure AWS Credentials for profile-b
        uses: aws-actions/configure-aws-credentials@v2
        with:
          role-to-assume: ${{ inputs.profile_b_aws_arn }}
          aws-region: ${{ inputs.region }}
          profile: profile-b

      - name: Configure AWS Credentials for profile-c
        uses: aws-actions/configure-aws-credentials@v2
        with:
          role-to-assume: ${{ inputs.profile_c_aws_arn }}
          aws-region: ${{ inputs.region }}
          profile: profile-c

3 years of discussions and still nothing for seems like basic functionality... Use this as example https://github.com/marketplace/actions/configure-aws-profile

ffMathy commented 1 year ago

I need this too.

When we deploy to production, we'd like to also configure the staging environment credentials under the "staging" profile, so that our tests can then explicitly use that profile.

That way, it becomes easier to not accidentally run tests towards production.

benjefferies commented 11 months ago

I'm standing on the shoulders of giants with this, but here is something that I whipped up to meet my use case: https://github.com/marketplace/actions/configure-aws-profile

Amazing stuff @mcblair. Needed to be done. Hopefully, someone can review the good work @GeertWille did https://github.com/aws-actions/configure-aws-credentials/pull/633

ruckc commented 10 months ago

We have a deployment that sprawls across multiple AWS accounts... it would be nice to be able to merge all of the tasks into a action.

asychev commented 7 months ago

Really, more than 3 years 🤯 ... maybe @tim-finnigan can help moving this forward?

kokuyouwind commented 7 months ago

Currently, I use a configuration file with credential_source = Environment as follows. I personally recommend this method because it simplifies the workflow files by only requiring a fixed aws config to be placed in .aws/config.

.github/workflows/aws_config/config:

[profile a]
credential_source = Environment
role_arn = arn:aws:iam::xxxxx28:role/SwitchRoleA

[profile b]
credential_source = Environment
role_arn = arn:aws:iam::xxxxx02:role/SwitchRoleB

.github/workflows/workflow.yml:

    steps:
      - uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: ${{ env.AWS_ROLE_ARN }}
      - name: Configure AWS Profiles
        run: |
          mkdir ~/.aws
          cp .github/workflows/aws_config/config ~/.aws/config
      - run: aws --profile=a sts get-caller-identity
      - run: aws --profile=b sts get-caller-identity
Moulick commented 7 months ago

Building on the work of @mcblair, I have published an action that handles all of this very cleanly, it continues to use the official aws-actions/configure-aws-credentials under the hood + a couple of steps to see if all the profiles are correctly logged in correctly https://github.com/marketplace/actions/configure-multiple-aws-roles.

Also documented is the case on how to use with some composite docker steps that you might have later in the chain. Dependabot is enabled so any updates to the official action will be updated here asap.

We are already using this internally at my current org to manage multiple AWS Accounts in a single Job, specially important whenever there is coordinated cross-account steps.

abseht commented 3 months ago

A very much needed feature 🙏🏼 💡 A use case for a least-privilege, multi-role, multi-account... Terraform access: ⬇️ Say we have a repository. It consists of multiple parent modules with simple configuration as below. Only the profile value is different and each relies on a dedicated role to manage AWS resources of a specific parent module:

terraform {
  required_version = ">= 1.3"

  backend "s3" {
    bucket                    = "terraform-state"
    key                          = "main.tfstate"
    region                    = "us-east-1"
    dynamodb_table = "terraform-state-lock"
    profile                    = "state-dev"
  }

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5"
    }
  }
}

provider "aws" {
  region = "us-east-1"
  profile = "dev"
...
}

Suggested look of the action:

steps:
  - uses: aws-actions/configure-aws-credentials@v4
    with:
      profiles:
        - name: "state-dev"
          role-to-assume: "your arn"
          aws-region: "us-west-1"
        - name: "dev"
          role-to-assume: "your other arn"
          aws-region: "us-east-1"
    ...other parameters...

As a result, with only one step, you have an environment which can seamlessly run commands for multiple Terraform parent modules. 🙏🏼 Thank you for your considerations!