Is there a way to use AWS SSO credentials with Pul...
# aws
c
Is there a way to use AWS SSO credentials with Pulumi? I authenticate with
aws sso login --profile
then I can reuse those credentials by passing the same profile to AWS CLI commands. Unless I did some mistake, we cannot use those profiles with Pulumi. Did someone achieve it?
m
Here's a
credential_process
script I've written that might help you?
Copy code
#!/usr/bin/env bash

# Generate a profile with temporary credentials for the role
# Add to your AWS profile:
# credential_process = /usr/local/bin/aws_sso.sh my-profile arn:aws:iam::1234567890:role/CoolRole-us-east-1 write
# In application use the profile name: <profile_name>-temp
function aws_sso () {
    local AWS_PROFILE=$1
    local AWS_PROFILE_SSO="${AWS_PROFILE}-sso"
    local ROLE_ARN=$2
    local SSO_ROLE_NAME=$(aws configure get profile.${AWS_PROFILE_SSO}.sso_role_name)
    local SSO_ROLE_SESSION_NAME=$(aws configure get profile.${AWS_PROFILE_SSO}.role_session_name)

    if [[ -n ${SSO_ROLE_NAME} ]]; then
        local AWS_ROLE_USER_ID=$(aws --profile ${AWS_PROFILE_SSO} sts get-caller-identity |jq -r '.UserId' || exit 0)
        if [[ -z ${AWS_ROLE_USER_ID} ]]; then
            $(aws sso login --profile=${AWS_PROFILE}-sso &>/dev/null)
        fi

        local AWS_CREDENTIALS=$(aws --profile ${AWS_PROFILE_SSO} sts assume-role --role-arn ${ROLE_ARN} --role-session-name ${SSO_ROLE_SESSION_NAME})

        local AWS_ACCESS_KEY_ID=$(echo ${AWS_CREDENTIALS} | jq -r '.Credentials.AccessKeyId')
        local AWS_SECRET_ACCESS_KEY=$(echo ${AWS_CREDENTIALS} | jq -r '.Credentials.SecretAccessKey')
        local AWS_SESSION_TOKEN=$(echo ${AWS_CREDENTIALS} | jq -r '.Credentials.SessionToken')
        local AWS_EXPIRATION=$(echo ${AWS_CREDENTIALS} | jq -r '.Credentials.Expiration')

        local RESPONSE_TEMPLATE='{"Version": 1,
          "AccessKeyId": "%s",
          "SecretAccessKey": "%s",
          "SessionToken": "%s",
          "Expiration": "%s"
        }'

        if [[ ${3} == "write" ]]; then
            aws configure set profile.${AWS_PROFILE}-temp.aws_access_key_id ${AWS_ACCESS_KEY_ID}
            aws configure set profile.${AWS_PROFILE}-temp.aws_secret_access_key ${AWS_SECRET_ACCESS_KEY}
            aws configure set profile.${AWS_PROFILE}-temp.aws_session_token ${AWS_SESSION_TOKEN}
        fi

        echo $(printf "${RESPONSE_TEMPLATE}" "${AWS_ACCESS_KEY_ID}" "${AWS_SECRET_ACCESS_KEY}" "${AWS_SESSION_TOKEN}" "${AWS_EXPIRATION}")
    else
        echo "Profile not found, or missing sso_role_name"
    fi
}

aws_sso $1 $2 $3
c
Thanks, I'll try it out!
According to https://github.com/pulumi/pulumi/issues/5072 it is supposed to work. That's weird!
b
@clever-painter-96148 we use
aws sso login
for Pulumi and it works fine, what issue are you seeing?
@millions-furniture-75402 I wrote a little Go binary to help with that process 🙂 https://github.com/jaxxstorm/aws-sso-creds
👍 1
c
@billowy-army-68599 I described what I've done here: https://pulumi-community.slack.com/archives/CRH5ENVDX/p1635948880103000?thread_ts=1635946074.101600&amp;cid=CRH5ENVDX Did you achieve it without your tool? I'll check it out, thanks!!
b
@clever-painter-96148 double check your env vars to make sure you don't have any latent env vars hanging aroind?
env | grep -i AWS
c
nope, my env is clean
b
huh, strange. it should just work
c
b
I'm sure it won't make a difference, bt can you can try exporting the
AWS_PROFILE
var?
c
Haha, I already tried. Same result.
When running pulumi with -v9, I see:
Copy code
I1103 17:42:21.679702  151402 eventsink.go:59] Attempting to use session-derived credentials
I1103 17:42:21.679724  151402 eventsink.go:62] eventSink::Debug(<{%reset%}>Attempting to use session-derived credentials<{%reset%}>)
I1103 17:42:21.680392  151402 provider_plugin.go:511] Provider[aws, 0xc000f08960].Configure() failed: err=unable to discover AWS AccessKeyID and/or SecretAccessKey - see <https://pulumi.io/install/aws.html> for details on configuration
But there is no reason that explain why...
If I understand this correctly: https://github.com/pulumi/pulumi-aws/blob/master/provider/resources.go#L253 1. It creates a Config object based on the function arguments and fill it with values from the environment 2. It passes it to hashicorp/aws-sdk-go-base's GetCredentials which uses StaticProvider, EnvProvider and SharedCredentialsProvider (none of these seem to be able to use AWS SSO credentials) According to https://aws.amazon.com/blogs/developer/aws-sso-support-in-the-aws-sdk-for-go/ we should use NewSessionWithOptions. hashicorp/aws-sdk-go-base uses it in GetCredentialsFromSession. But pulumi only uses GetCredentials. Where is the current implementation supposed to get credentials from AWS SSO? Disclaimer: My understanding could be very wrong as I don't know anything about golang... 😅
b
@clever-painter-96148 I've never had success using the SSO profile directly. Either use
Copy code
eval `aws-sso-creds export --profile <profile>`
or
Copy code
aws-sso-creds set --profile <sso-profile> <temp_profile>
AWS_PROFILE=<temp_profile>
c
Guess I'll use @billowy-army-68599's aws-sso-creds for now 🙂
f
I use profiles w/o export via
AWS_PROFILE
I have this setup in
/.aws/config
:
Copy code
[profile pulumi-ci]
sso_start_url = <https://xxxxxxx.awsapps.com/start>
sso_region = us-west-2
sso_account_id = 12345678901
sso_role_name = FooRole
region = us-west-2
my workflow is to run
aws sso login
and then i’ll do a
AWS_PROFILE=my-profile pulumi up
I also have
AWS_SDK_LOAD_CONFIG=true
set in my env vars since I believe you need that in order for the SDK to pick up
~/.aws/config
c
My profile in ~/.aws/config:
Copy code
[profile foo]
sso_start_url=<https://foo.awsapps.com/start>
sso_region=eu-west-1
sso_account_id=42
sso_role_name=AWSAdministratorAccess
Then I run
aws sso login --profile foo
and finally
AWS_PROFILE=foo pulumi up
. I also tried to set
AWS_SDK_LOAD_CONFIG=true
, but it did not change the result:
Copy code
error: unable to discover AWS AccessKeyID and/or SecretAccessKey - see <https://pulumi.io/install/aws.html> for details on configuration
In the meantime, I tried aws-sso-creds, and it's already an improvement, thanks @billowy-army-68599 😄
b
glad to help!
c
Any idea how I could dig the native aws sso integration issue further? I'd love to have this, so I could set aws:profile in Pulumi.stackName.yaml and ensure I will never again run
pulumi up
on the wrong stack on the wrong account 🥲
r
I know the AWS go SDK just started supporting SSO in February: https://aws.amazon.com/blogs/developer/aws-sso-support-in-the-aws-sdk-for-go/, so the first thing I'd is to check the sdk versions used in whatever language provider you are using and make sure that the aws sdk supported sso in that version
c
pulumi-aws 4.25.0 uses hashicorp/aws-sdk-go-base v1.0.0 (https://github.com/pulumi/pulumi-aws/blob/v4.25.0/provider/go.mod) hashicorp/aws-sdk-go-base 1.0.0 uses aws-sdk-go v1.31.9 (https://github.com/hashicorp/aws-sdk-go-base/blob/main/go.mod#L4) aws-sdk-go 1.13.9 has been released on 2020-06-02 (https://github.com/aws/aws-sdk-go/blob/v1.31.9/CHANGELOG.md) It looks like that SSO support has been added in v1.25.30: https://github.com/aws/aws-sdk-go/blob/main/CHANGELOG.md#release-v12530-2019-11-07 Then they fixed an issue that affected it in version 1.37.2 : https://github.com/aws/aws-sdk-go/blob/main/CHANGELOG.md#release-v1372-2021-02-02 On the same day (2020-02-02), they announced support for sso in the go sdk: (https://aws.amazon.com/blogs/developer/aws-sso-support-in-the-aws-sdk-for-go/) So it looks like the AWS SDK used in Pulumi should be able to work with AWS SSO.
b
credential_process
in conjunction with aws-vault works really well 🙂
f
I’d love to have this, so I could set aws:profile in Pulumi.stackName.yaml and ensure I will never again run 
pulumi up
 on the wrong stack on the wrong account
Irrespective of getting this to work, one thing I’ve seen as a pattern is along the lines of:
Copy code
aws.getCallerIdentity().then(identity => {
    if (identity.accountId != expectedAccountId)
    throw new Error("uh-oh");
});
as a way to add a guard directly to your program
Looking at what you’ve described so far, I’d expect that to work, so I’m not sure what I’m doing differently or what’s different on your end.
I guess the only difference I can observe is I login purely with
aws sso login
without specifying
--profile
(though, I just tried w/ that and it worked fine)
c
Irrespective of getting this to work, one thing I’ve seen as a pattern is along the lines of:
Simple, efficient, I like this idea a lot! All my pulumi projects have multiple stacks (usually 1 per environment). I'll write a PoC using an account ID stored in the stack's config. Thanks!
I guess the only difference I can observe is I login purely with 
aws sso login
 without specifying 
--profile
Guess that means "use the default profile"?
Looking at what you’ve described so far, I’d expect that to work, so I’m not sure what I’m doing differently or what’s different on your end.
Yep. Unfortunately, I have no idea how I could troubleshoot this further. I'm open to suggestions. 🙂
f
One other thought: is this an old stack that used a previous version of the plugin?
c
Nope:
Copy code
$ pulumi stack export | grep providers:aws:: | sort -u
                "provider": "urn:pulumi:dev::yarn-monorepo-pulumi-lambda::pulumi:providers:aws::default_4_25_0::801f221c-0186-470c-bd95-87d67531d813",
                "urn": "urn:pulumi:dev::yarn-monorepo-pulumi-lambda::pulumi:providers:aws::default_4_25_0",