Hello. I am trying to create an AWS provider for a...
# general
f
Hello. I am trying to create an AWS provider for a different AWS account than the one the Pulumi program is launched with. I do so like this:
Copy code
const provider = new aws.Provider(`${acctName}-provider`, {
    region: "us-west-2",
    assumeRole: {
        roleArn: pulumi.interpolate`arn:aws:iam::${args.id}:role/${args.roleName}`
    }
});
I later create a resource by passing the provider as the 3rd arg to the resource
{provider: provider}
. After running
pulumi up
, I receive the following message:
Copy code
aws:iam:Role (access):
    error: 1 error occurred:
    	* error configuring Terraform AWS Provider: IAM Role (arn:aws:iam::<<account id>>:role/<<role name>>) cannot be assumed.
    
    There are a number of possible causes of this - the most common are:
      * The credentials used in order to assume the role are invalid
      * The credentials do not have appropriate permission to assume the role
      * The role ARN is not valid
    
    Error: NoCredentialProviders: no valid providers in chain. Deprecated.
    	For verbose messaging see aws.Config.CredentialsChainVerboseErrors
How can I go about further debugging this?
I'd really like to see some sort of logs from the AWS sts API call. I've tried looking through the -v=9 logs and cannot find anything.
AH. I set AWS_PROFILE when running
pulumi up
and it worked! I've already set
aws:profile
in my config so it seems odd that I'd also need to set the env var...
l
Are you using the AWS backend? That uses only your env vars. The config is only for providers.
f
What does "AWS backend" mean in this context?
l
Where is your state file being stored? Have you defined the "backend" property in your Pulumi.yaml?
f
Pulumi is managing it.
So no, I have not specified anything special with the state file.
l
Ah. Then aws:profile should be the only thing you need.. at a guess, a new AWS provider isn't using the config that the default provider uses?
f
Plausible. My default provider will not have access to assume the role. Only the profile provider specified in my pulumi config aws:profile key would have access.
l
I've checked my code, and I note that I always explicitly pass a value for profile when I'm created a new AWS provider. So I haven't encountered this situation.
I recommend explicitly passing
new pulumi.Config("aws").require("profile")
to the profile of any AWS provider you create.
At least for providers using the default profile.
f
Just tried it out -- same error.
I pass the result of this:
Copy code
function getDefaultProfileProvider() {
    const profile = new pulumi.Config("aws").require("profile")
    console.log(profile)
    return new aws.Provider("aws-default-profile", {
        profile: profile
    })
}
to my role aws.Provider.
l
Does the profile specify a region? If not, can you add one there? And have you confirmed that the profile is allowed assume that role?
f
The profile does specify a region & it does have access. Running pulumi up with the env var set works. e.g.,
Copy code
AWS_PROFILE=profile-with-access pulumi up
l
So you're setting aws:profile in your Pulumi.x.yml file and it's not being picked up?
f
Correct
l
Maybe the format of the line is wrong? Can you paste it here?
f
It is only not being picked up for new new provider creation. Other top-level resources do pick it up.
Copy code
config:
  aws:region: us-west-2
  aws:profile: profile-with-access
To be clear: I create many other resources with the default aws provider. At some point, I construct a new provider (as seen in the OP). That call fails unless I run
pulumi up
with AWS_PROFILE set.
l
I've reread thread. It looks like currently you're passing profile only into the default provider. The non-working provider doesn't have a profile set.
Is that correct?
f
Yes. The non-working provider should use the default provider to assume the role specified in assumeRole. I did try as you suggested to explicitly pass a provider to the non-working provider (using the getDefaultProfileProvider fn) and that resulted in the same error.
l
I think the profile is required. I don't see how
getDefaultProfileProvider()
can help you pass the profile into the new provider?
Since the profile is a local variable within the function..
f
Could you clarify what "I think the profile is required" means?
l
You posted this code which I believe won't work:
Copy code
const provider = new aws.Provider(`${acctName}-provider`, {
    region: "us-west-2",
    assumeRole: {
        roleArn: pulumi.interpolate`arn:aws:iam::${args.id}:role/${args.roleName}`
    }
});
You would need this code instead:
Copy code
const provider = new aws.Provider(`${acctName}-provider`, {
    region: "us-west-2",
    profile: profile,
    assumeRole: {
        roleArn: pulumi.interpolate`arn:aws:iam::${args.id}:role/${args.roleName}`
    }
});
f
Hmm, that seems surprising. I interpreted the Provider args as the definition for the "target" aws account. The "source" being the provider passed to the Provider.
I will try it.
f
Yeah, the profile you set in config.yank is only used as config for the default provider, I don’t think pulumi knows to use it for custom providers
l
Consider the equivalent in the AWS credentials file. You cannot assume a role via
role_arn
unless you also provide
source_profile
(Or explicit
aws_access_key_id
and
aws_secret_access_key
)
f
Yep, that did it! Thank you for your patience @little-cartoon-10569.
👍 1
111 Views