Open beetahnator opened 4 years ago
What is the error message that you get here?
Note that you could put a delay inside an apply (setTimeout inside the apply) as a workaround
Sounds like the root issue is that the provider needs to retry the assume role lookup to deal with eventual consistency of IAM. That likely require an upstream AWS provider fix.
@lukehoban I added the error output above.
~Do you have an example for using setTimeout
inside apply
?~
I found this example, will try the setTimeout
method now.
UPDATE: This seems to work, could be further improved by checking if the role can be assumed inside the .apply
instead of using setTimeout
const roleProvider = new aws.Provider(
"test",
{
assumeRole: {
roleArn: role.arn.apply(async(arn) => {
if (!pulumi.runtime.isDryRun()) {
await new Promise(resolve => setTimeout(resolve, 30 * 1000));
}
return arn
})
}
},
{ dependsOn: rolePolicy}
);
@mazamats Thanks for updating the issue with a clear example. I was stuck on the same issue and your example really helped.
For the Python users out there, here's a similar example of how to do the above, but with sts.assume_role()
from boto3:
import asyncio
import boto3
import botocore.exceptions
import pulumi_aws as aws
import pulumi
async def wait_for_iam_eventual_consistency(args: list) -> str:
role_arn = args[0]
role_session_name = args[1]
duration = 3
attempts = 10
if not pulumi.runtime.is_dry_run():
pulumi.log.info(f"Waiting up to {attempts * duration} seconds for IAM eventual consistency for IAM Role: {role_arn}")
sts = boto3.client('sts')
for i in range(attempts):
try:
sts.assume_role(
RoleArn=role_arn,
RoleSessionName=role_session_name
)
except botocore.exceptions.ClientError:
await asyncio.sleep(duration)
else:
break
return role_arn
account_id = aws.get_caller_identity().account_id
iam_role = aws.iam.Role(
resource_name="vpc-admin",
description='IAM Role for VPC Administration',
path='/',
force_detach_policies=True,
assume_role_policy={
"Version": "2012-10-17",
"Statement": [{
"Sid": "AllowAccountAssumeRole",
"Action": "sts:AssumeRole",
"Principal": {
"AWS": f"arn:aws:iam::{account_id}:root"
},
"Effect": "Allow"
}]
}
)
iam_role_policy_attachment = aws.iam.RolePolicyAttachment(
resource_name="vpc-admin-policy-attachment",
role=iam_role.id,
policy_arn="arn:aws:iam::aws:policy/AmazonVPCFullAccess"
)
session_name = "VpcAdmin"
role_arn = pulumi.Output.all(iam_role.arn, session_name).apply(wait_for_iam_eventual_consistency)
iam_role_provider = aws.Provider(
resource_name='vpc-admin-provider',
assume_role={
"role_arn": role_arn,
"session_name": session_name
},
opts=pulumi.ResourceOptions(
depends_on=[
iam_role_policy_attachment
]
)
)
aws.ec2.Vpc(
resource_name="test-vpc",
cidr_block="10.100.0.0/16",
enable_dns_hostnames=True,
enable_dns_support=True,
tags={
"Name": "test-vpc",
"CreatedBy": "vpc-admin-provider"
},
opts=pulumi.ResourceOptions(
parent=iam_role_provider,
provider=iam_role_provider
)
)
This appears to be due to upstream https://github.com/hashicorp/terraform-provider-aws/issues/6566.
I have a usecase where I need to generate an IAM Role and then use it as a provider to generate more AWS resources.
When trying the example below, the first
pulumi up
always fails since Pulumi tries to assume the role immediately after creation.Error output when trying to apply