amplify-cli
amplify-cli copied to clipboard
[Feature Request] Amplify CLI support AWS SSO
Describe the bug
$ amplify env pull
⠦ Fetching updates to backend environment: dev from the cloud.(node:10308) UnhandledPromiseRejectionWarning: Error: connect EHOSTUNREACH 169.254.169.254:80
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1141:16)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:10308) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:10308) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
⠋ Fetching updates to backend environment: dev from the cloud.
Amplify CLI Version 4.21.1
To Reproduce
- aws sso login --profile dev
- amplify pull or amplify env pull
Expected behavior Update my local development environment
Desktop
- OS: Linux Mint 19.3
- Node Version. v14.3.0
I have a problem adding a new env with the Amplify CLI that uses a SSO profile. Getting
init failed
Error: connect ETIMEDOUT 169.254.169.254:80
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1141:16) {
message: 'Missing credentials in config, if using AWS_CONFIG_FILE, set AWS_SDK_LOAD_CONFIG=1',
errno: 'ETIMEDOUT',
code: 'CredentialsError',
syscall: 'connect',
address: '169.254.169.254',
port: 80,
time: 2020-06-08T05:08:14.592Z,
originalError: {
message: 'Could not load credentials from any providers',
errno: 'ETIMEDOUT',
code: 'CredentialsError',
syscall: 'connect',
address: '169.254.169.254',
port: 80,
time: 2020-06-08T05:08:14.592Z,
originalError: {
message: 'EC2 Metadata roleName request returned error',
errno: 'ETIMEDOUT',
code: 'ETIMEDOUT',
syscall: 'connect',
address: '169.254.169.254',
port: 80,
time: 2020-06-08T05:08:14.592Z,
originalError: [Object]
}
}
}
I tried another way but I also had problems.
You must delete the "amplify" directory of your project
$ aws sso login --profile amplify
Attempting to automatically open the SSO authorization page in your default browser. If the browser does not open or you wish to use a different device to authorize this request, open the following URL:
https://device.sso.us-east-1.amazonaws.com/
Then enter the code:
XXXX-XXXX Successully logged into Start URL: https://amplify.awsapps.com/start
$ amplify pull
For more information on AWS Profiles, see: https://docs.aws.amazon.com/cli/latest/userguide/cli-multiple-profiles.html
? Do you want to use an AWS profile? Yes ? Please choose the profile you want to use amplify
Error: connect EHOSTUNREACH 169.254.169.254:80
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1141:16) {
message: 'Missing credentials in config, if using AWS_CONFIG_FILE, set AWS_SDK_LOAD_CONFIG=1',
errno: -113,
code: 'CredentialsError',
syscall: 'connect',
address: '169.254.169.254',
port: 80,
time: 2020-06-13T22:09:10.614Z,
originalError: {
message: 'Could not load credentials from any providers',
errno: -113,
code: 'CredentialsError',
syscall: 'connect',
address: '169.254.169.254',
port: 80,
time: 2020-06-13T22:09:10.614Z,
originalError: {
message: 'EC2 Metadata roleName request returned error',
errno: -113,
code: 'EHOSTUNREACH',
syscall: 'connect',
address: '169.254.169.254',
port: 80,
time: 2020-06-13T22:09:10.614Z,
originalError: [Object]
}
}
}
Hi folks,
we also face a similar problem with slightly different error messages. I've tried to describe it here also for the 'amplify init' command:
You may be able to use aws-sso-credential-process with AWS_SDK_LOAD_CONFIG=1 set to enable AWS SSO credentials to be used.
If that doesn't work, there is a workaround, developed for the CDK (which has the same problem): https://github.com/aws/aws-cdk/issues/5455#issuecomment-713643500
The aws2-wrap method referenced by @benkehoe is working absolutely fine for CDK. However, the amplify issue isn't getting resolved by it. Is there some other way that anyone has been able to get the amplify to work with sso credentials since the time this issue was first created?
Hey, folks, let me know if this helps, since I was facing a very similar problem and (I think) I "fixed" it: Setup
- Multiple AWS Accounts in AWS Organization with AWS Single Sign-On enabled for those accounts;
- Amplify with Angular (10) SPA - using basically (import) auth and (add) hosting; Issue: multiple profiles not working or amplify ends up publishing in the wrong (default) account.
$> amplify publish -c
× There was an error pulling the backend environment dev.
An error occurred during the push operation: The provided token has expired.
Fixing:
- Run $> aws configure sso (for each AWS Account/profile) ==> this will update (only) the ~/.aws/config (Linux & Mac) or %USERPROFILE%.aws\config (Windows) file;
- Copy the information from the SSO User Portal URL (repeat this step when the token expires) - command line or programmatic access (Option 2: Add a profile to your AWS credentials file) ==> user portal is something like 'https://xyz.awsapps.com/start#/'
- Edit the ~/.aws/credentials (Linux & Mac) or %USERPROFILE%.aws/credentials (Windows) and paste the information from #2. Save;
- Run the command again: success.
@nishitjain13 Did you try the credential_process method using aws-sso-util instead of aws2-wrap? I have updated the documentation for it here.
Additionally, aws-export-credentials supports AWS SSO and allows you to inject environment variables with your credentials.
In case like this one or other similar cases where AWS SSO result in incompatibilities with your library and you don't want to play with workarounds or complicated fixes, maybe you can also give a try to our open-source project: https://github.com/Noovolari/leapp. It deals with AWS SSO authentication and accounts/roles retrieval then it creates short-lived temporary credentials in .aws/credentials to maximize compatibility with third party tools / sdks.
Did you try the
credential_processmethod usingaws-sso-utilinstead ofaws2-wrap? I have updated the documentation for ithere.
@benkehoe
Thank you. I solved the problem in my environment (aws-amplify/cli 4.41.2).
I needed AWS_SDK_LOAD_CONFIG=1
I followed the above instructions with AWS_SDK_LOAD_CONFIG=1 using credential_process method with aws-sso-util. However it appears that the AWS CLI completely ignores the credential process as per this issue here: https://github.com/aws-amplify/amplify-cli/issues/6882
Ok I figured out the issue. For this credential_process to work, all of the following conditions must be met:
- Set
AWS_SDK_LOAD_CONFIG=1 - Set
AWS_Profile={your profile} - Run
amplify initand select the same{your profile}when prompted
Also an (empty) ~/.aws/credentials file needed. https://github.com/aws-amplify/amplify-cli/issues/6882#issuecomment-950348362
Bug is still relevant today (amplify version 9.2.1).
When trying to run amplify init, using AWS profile as the authentication method and choosing the profile set up by AWS SSO, I get the error:
Failed to get profile: Cannot read property 'accessKeyId' of undefined
This is frustrating as using AWS SSO is considered best-practice instead of creating individual long-lived IAM users with permanent credentials.
Neither touch ~/.aws/credentials nor AWS_SDK_LOAD_CONFIG=1 amplify init solve the issue.
I'm seeing the same issue as @ari-becker.
$ amplify version
10.0.0
$ AWS_SDK_LOAD_CONFIG=1
$ AWS_PROFILE=mapp01
$ amplify init
Note: It is recommended to run this command from the root of your app directory
? Enter a name for the project s3uploaderui
The following configuration will be applied:
Project information
| Name: s3uploaderui
| Environment: dev
| Default editor: Visual Studio Code
| App type: javascript
| Javascript framework: react
| Source Directory Path: src
| Distribution Directory Path: build
| Build Command: npm run-script build
| Start Command: npm run-script start
? Initialize the project with the above configuration? Yes
Using default provider awscloudformation
? Select the authentication method you want to use: AWS profile
For more information on AWS Profiles, see:
https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html
? Please choose the profile you want to use mapp01
Failed to get profile: Cannot read property 'accessKeyId' of undefined
Is there a best practice on how to use amplify with SSO?
I'm a little confused now. The AWS JavaScript SDK v2 added support for AWS SSO in v2.1093.0 and from what I can tell Amplify CLI requires v2.1113.0, so it seems like AWS SSO support should be present in the latest version of Amplify CLI.
Running cli v10.3.0 I receive the same as the users above:
Failed to get profile: Cannot read property 'accessKeyId' of undefined
Is there an expected fix date for this?
I've been stuck on this issue for 2 hours...how can something like this be broken and not fixed yet.
This is indeed broken as of now .
? Please choose the profile you want to use SB102
Failed to get profile: Cannot read property 'accessKeyId' of undefined
devops-amplify-app git:main ❯ amplify --version ⏎
10.5.1
This was supposed to be a basic requirement as AWS already provides this SSO creds long back .
Adding a role_arn to the profile configuration should solve the undefined 'accessKeyId' problem. Here is what I did in order to get it working on my computer:
I configured a profile in ~/.aws/config like this:
[profile myprofile]
region=<REGION>
role_arn=arn:aws:iam::<ACCOUNT_ID>:role/<ROLE_NAME>
sso_start_url=https://<SUBDOMAIN>.awsapps.com/start
sso_region=<REGION>
sso_account_id=<ACCOUNT_ID>
sso_role_name=<ROLE_NAME>
I created the following script to login and export the credentials to the environment variables:
#!/bin/sh
profile_name="$1"
aws sso login --profile "${profile_name}"
credentials=$(aws-sso-util credential-process --profile "${profile_name}")
export AWS_ACCESS_KEY_ID="$(echo "${credentials}" | jq -r '.AccessKeyId')"
export AWS_SECRET_ACCESS_KEY="$(echo "${credentials}" | jq -r '.SecretAccessKey')"
export AWS_SESSION_TOKEN="$(echo "${credentials}" | jq -r '.SessionToken')"
This script must be sourced in order to keep the AWS envs (Make absolutely sure you're sourcing the script and not regularly executing it!). For example:
. ./configure-credentials-env.sh myprofile
First I executed the script. Then, after the login was successful, I executed amplify init. It then allowed me to choose "AWS profile" and within it "myprofile".
When your credentials run out, just source the script again to get new ones. The amplify cli (under these configurations) should recognize them.
Also, if you want to make sure the AWS profile configuration was done correctly, look inside the created amplify/.config/local-aws-info.json file. It should look something like this:
{
"dev": {
"configLevel": "project",
"useProfile": true,
"profileName": "myprofile"
}
}
Hope this helps.
I've found @benkehoe 's excellent aws-sso-util has solved this for me, on amplify v10.5.1.
-
Install aws-sso-util
-
Set up a profile (which goes in .aws/config) called 'myprofile' (substitute your own values) :
aws-sso-util configure profile --sso-start-url 'https://myapp.awsapps.com/start#/' --account-id 987654321 --sso-region ap-southeast-2 --role-name AWSPowerUserAccess --region ap-southeast-2 myprofileNow whenever you need to login, you can just run:
aws-sso-util login --allI have set up an alias in my .zshrc for this:
alias awslogin="aws-sso-util login --all"and another one to launch the AWS web console:
alias awsconsolebp="aws-sso-util console launch --account-id 987654321 --role-name AWSPowerUserAccess"
The resulting profile in ~/.aws/config looks like this; note the credential_process property :
[profile myprofile]
sso_start_url = https://myapp.awsapps.com/start#/
sso_region = ap-southeast-2
sso_account_id = 987654321
sso_role_name = AWSPowerUserAccess
region = ap-southeast-2
credential_process = aws-sso-util credential-process --profile myprofile
I think the credential_process is the special sauce which makes this work for us.
A workaround I just got working was to make another profile with the credential_process set to call the sso login command, i.e.
[profile admin]
sso_start_url = https://xxxxxxxx.awsapps.com/start#/
sso_region = us-east-1
sso_account_id = xxxxxxxxxx
sso_role_name = AWSAdministratorAccess
region = us-east-1
output = json
[profile admin-amplify]
credential_process = aws sso login --profile admin
Note: you'll need to replace the values for the
profilenames,sso_start_url,sso_account_idfor this to work for your situation
Then when using the amplify CLI set the profile to the amplify one, in this case: admin-amplify
17:25:20 ~/ feature/lambda $ amplify init
Note: It is recommended to run this command from the root of your app directory
? Enter a name for the project xyz
The following configuration will be applied:
Project information
| Name: xyz
| Environment: dev
| Default editor: Visual Studio Code
| App type: javascript
| Javascript framework: react
| Source Directory Path: src
| Distribution Directory Path: build
| Build Command: npm run-script build
| Start Command: npm run-script start
? Initialize the project with the above configuration? Yes
Using default provider awscloudformation
? Select the authentication method you want to use: AWS profile
For more information on AWS Profiles, see:
https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html
? Please choose the profile you want to use sso-session sami-sso
Failed to get profile: Cannot read property 'accessKeyId' of undefined
When is this issue expected to get resolves, I am using SSO-Login and SSO-profile?
@cunneen made a great comment.
but I used this npm package instead https://www.npmjs.com/package/aws-sso-cli
just replace aws-sso-util with aws-sso-cli and it will work like a charm.
still having issues after setup.
config file:
[profile account-sso-dev]
sso_start_url = https://*********.awsapps.com/start
sso_region = ca-central-1
sso_account_id = ************
sso_role_name = ******Dev
region = ca-central-1
output = json
credentials file:
[account-sso-dev]
aws_access_key_id=*****************
aws_secret_access_key=***********************
aws_session_token=***********************
I've used aws sso login --profile <profile name> and re-logged in only to receive error:
✖ There was an error pulling the backend environment dev. 🛑 The provided token is malformed or otherwise invalid.
I've also used aws-vault exec <profile name> and same thing.
@adcanis it looks like you're missing a line from your config file:
credential_process = aws sso login --profile account-sso-dev
@cuneen thats fantastic! worked like a charm.
@adcanis it looks like you're missing a line from your
configfile:credential_process = aws sso login --profile account-sso-dev
This is the oddest solution, to me, considering credential_process is supposed to require that the process outputs to stdout a json blob in a very specific format. And aws sso login definitely does not do that. Some weirdness must be happening under the covers, an implementation detail that works for the moment, and not an actual solution to the problem...
This is my workaround. My amplify-cli is v11.1.1.
Almost all the same as https://github.com/aws-amplify/amplify-cli/issues/4488#issuecomment-1379987317 , but this way just depends on only aws-cli, jq, and POSIX shell commands.
example
~/.aws/config
# SSO session config, See: https://docs.aws.amazon.com/cli/latest/userguide/sso-configure-profile-token.html#sso-configure-profile-token-manual
[sso-session my-sso]
sso_start_url = ...
sso_region = ...
sso_registration_scopes = sso:account:access
# SSO profile for amplify-cli, See: https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sourcing-external.html
# Please replace {{AWS_ACCOUNT_ID}} and {{SSO_ROLE_NAME}} to your own
[profile my-amplify]
credential_process = aws sso get-role-credentials --account-id {{AWS_ACCOUNT_ID}} --role-name {{SSO_ROLE_NAME}} --access-token $(ls -t ~/.aws/sso/cache/*.json | xargs -I{} jq -r '.accessToken' {} | grep -v 'null' | head -n 1) --output json --query 'roleCredentials.{Version:`1`,AccessKeyId:accessKeyId,SecretAccessKey:secretAccessKey,SessionToken:sessionToken,Expiration:expiration}'
usage:
$ aws sso login --sso-session my-sso
$ amplify init
...
? Select the authentication method you want to use: AWS profile
...
? Please choose the profile you want to use my-amplify
...
How about adding a step to use aws-sdk-js#SsoCredentials in amplify-cli#getProfiledAwsConfig() ?
For example, aws-cdk that is a CLI tool depending on aws-sdk-js like amplify-cli, also use it like https://github.com/aws/aws-cdk/blob/v2.77.0/packages/aws-cdk/lib/api/aws-auth/awscli-compatible.ts#L81 .
Thanks @benkehoe, the aws-sso-util has saved my life here.