aws / copilot-cli

The AWS Copilot CLI is a tool for developers to build, release and operate production ready containerized applications on AWS App Runner or Amazon ECS on AWS Fargate.
https://aws.github.io/copilot-cli/
Apache License 2.0
3.54k stars 418 forks source link

Don't require AWS named profiles for credentials #5297

Open msusta opened 1 year ago

msusta commented 1 year ago

The documentation is recommending usage of named profiles stored in ~/.aws/. This is further supported by the copilot CLI outputing following warning when run with credentials supplied in ENV:

Note: Looks like you're creating an application using credentials set by environment variables.
Copilot will store your application metadata in this account.                                                                                                                                                     
We recommend using credentials from named profiles. To learn more:                                                                                                                                                
https://aws.github.io/copilot-cli/docs/credentials/

Sample warning above is for copilot app init. But when running copilot env init it just won't run with ENV and requires me to select named profile.

What is so wrong with ENV-provided credentials? Is this about security or usability? There can be many reasons to set the credentials as environment variables - aws-vault users, CI pipeline authenticating with OIDC and many more. Can't copilot just accept what AWS SDK allows by default?

Lou1415926 commented 1 year ago

Hey @msusta! Which version of Copilot were you using when you saw the error? Starting v1.30.0, Copilot no longer require that you have profiles - if there isn't any profile, then Copilot lets AWS SDK figures out the credentials used to create the environment. Related: https://github.com/aws/copilot-cli/issues/5066, https://github.com/aws/copilot-cli/pull/5202.

Did you want to create the environment into a separate account/region from where you created the app though? If so, would the ⬇️ flags to env init work for you?

      --aws-access-key-id string       Optional. An AWS access key.
      --aws-secret-access-key string   Optional. An AWS secret access key.
      --aws-session-token string       Optional. An AWS session token for temporary credentials.
msusta commented 1 year ago

@Lou1415926 As usual, I took one more look after posting and found there's a way.

The copilot env init did allow me to create the environment, however there was an interactive selection where I needed to select "Temporary Credentials".

Is there a way to not have the interactive selection? Global option or configuration perhaps?

Lou1415926 commented 1 year ago

Yeah you can skip the interactive selection by passing either ⬇️ set of flags to env init

--aws-access-key-id
--aws-secret-access-key
--aws-session-token

or

--profile (the name of the profile that you would have selected in an interactive session)

Would that be what you are looking for?

msusta commented 1 year ago

@Lou1415926 Yes, that's what I've been looking for.

So I have to add following options to copilot for it to work with what I have in my ENV already? That's quite hostile, but hopefully I can set some aliases so I don't have to write that all the time.

--aws-access-key-id $AWS_ACCESS_KEY --aws-secret-access-key $AWS_SECRET_ACCESS_KEY --aws-session-token $AWS_SESSION_TOKEN

I'm assuming that simply using what's in ENV is not something copilot wants to do - in that case can there be simpler option like --use-env ?

Lou1415926 commented 1 year ago

@msusta um sorry for the confusion. If you:

  1. Have AWS_ACCESS_KEY, AWS_SECRET_ACCESS_KEY and AWS_SESSION_TOKEN as environment variables.
  2. Do not have ~/.aws/config or ~/.aws/credentials

You should be able to just run copilot env init after v1.30.0, i.e. you won't need any of the credential flags mentioned above, nor would you encounter the interactive prompt for creds.

If you don't meet both of the conditions though, unfortunately you do need the flags. Thanks for bringing this up, this helped me discover an improvement opportunity here for Copilot. If users run copilot env init --profile default, maybe we should just let aws-sdk figure out the credentials following its default chain, instead of looking for the specific profile named "default". If this was supported, I think you would have just needed to meet the first ⬆️ condition to skip prompts without needing to provide the flags. This should accomplish the same thing that you were looking for by proposing --use-env.

msusta commented 1 year ago

@Lou1415926 I wasn't fulfilling the second requirement of not having the AWS SDK config files available.

The option you mentioned (profile=default) might be confusing. In general the AWS tools and SDKs would search for "default" profile in config and fail if that's unavailable. IIRC the ENV has priority over other credentials with SDKs, unless you explicitly call for them. So it's a question if you'd like to be more aligned with how most of the tools do it or have a specific configuration for copilot.

Lou1415926 commented 1 year ago

@msusta I agree with your concern on my proposal about --profile default! For future readers, here is how aws cli uses the --profile flag: it looks for a named profile called "default", instead of cascading down the default credential chain.

So it's a question if you'd like to be more aligned with how most of the tools do it or have a specific configuration for copilot.

Just to elaborate a bit on why Copilot's credential process is as it is today - we are aware that it is not completely aligned with a lot of the other tools.

Copilot supports cross-account/region applications: you deploy your application into account1/region1, and an environment into account2/region2.

When you run copilot env init, Copilot first needs to pull the application information from account1/region1, and asks users about what account2/region2 are. That is, there are two different sets of credentials involved when you run copilot env init, the application credential, and the environment credential.

This is different from any other commands in Copilot, as well as, I 'd say most commands in any other CLI tools: those commands involve only one credential. Now, there can be a lot of design choices around copilot env init's credential processes, but I think this (the fact that it needs two sets of creds) is the fundamental reason why it eventually ends up with a UX that feels foreign to a lot of users that are already familiar with the sdk or aws cli.

Back to the original issue - given your set up, I would recommend you to use the credential flags for now, for env init.

Sorry for the confusion!