In typescript, how can I say "Don't create resourc...
# general
r
In typescript, how can I say "Don't create resource X until 15 seconds after the IAM Role it depends on finishes provisioning?"
b
Are you getting an error because the role isn't ready yet? How are you passing the role to resource X?
b
doing something in an
.apply
will wait until the IAM role is finished, so you can do something like this:
Copy code
iamRole.arn.apply(async (arn) => {
            console.log("waiting for IAM role to be ready")
            await new Promise(resolve => setTimeout(resolve, 120000));
            return arn;
}),
Josh's question is important though, you might not need this...
r
It's an implicit dependency, like:
Copy code
new aws.sns.TopicSubscription('firehose_sub', {
  topic: snsTopic.arn,
  protocol: 'firehose',
  endpoint: firehoseStream.arn,
  subscriptionRoleArn: snsRole.role.arn,
});
where
snsRole
is a module that creates an
aws.iam.Role
. I'll go with the promise route, thank you!
b
why is the role implicit? if you're passing an output from
snsRole.role.arn
to the Topic, it should be done in a dependent chain
b
Yea I'm surprised, I would expect that to just work without any funny business. That's not your experience, though?
r
It is done in a dependent chain, but sometimes IAM Roles aren't immediately usable after their creation. This is pretty common in Terraform: https://github.com/terraform-aws-modules/terraform-aws-autoscaling/blob/d4b7da041ef781604726953234b5bcd494cc5908/examples/complete/main.tf#L100-L103 When I delete and then recreate this module over and over, the IAM Role is not ready yet about 2/3rds of the time. And then a
pulumi up
right after creates it
My guess: Pulumi/or tries to ensure that the
subscriptionRoleArn
has the correct permissions on SNS when the
TopicSubscription
is created. The
TopicSubscription
is created after the IAM Role, but before the
managedPolicyArns
are all attached to the IAM Role. I could very well be wrong, but it's pretty consistent
b
So what if you pass something like
dependsOn: policyResource
to the TopicSubscription resource? That way it doesn't get created until the policies are provisioned.
r
The Role should already be dependent on the policy because the policy arn is in the Role
managedPolicyArns
b
Ok, I'm confused about the order of operations. Your last message gave me the impression that you were: 1. Creating a role 2. Adding a policy to it (maybe via policy attachment) 3. Passing the role to TopicSubscription And there was a race condition between 2 & 3, because since TopicSubscription is not explicitly dependent on the policy attachment in 2, it doesn't wait for it. I haven't seen
managedPolicyArns
in any code that you have shared.
r
repro package: https://gist.github.com/dmattia/7ac415f36ead6599aa7b39096f4037f8 Error on my first time trying to run it:
Re-running an
up
immediately after:
b
Ok so I was half correct. In your code, the order of operations is not as I interpreted - because you are creating the policy first. But
managedPolicyArns
functions in the way that I interpreted, meaning that when AWS receives values in that property it is actually creating additional resources in the form of PolicyAttachments for each of those ARNs, and since pulumi is not managing those policy attachments it does not know to wait for them. If you instead allow pulumi to manage that PolicyAttachment, than I suspect you would eliminate this race condition. Try something like this instead:
Copy code
const snsPolicy = new aws.iam.Policy(`sns_policy`, {
  name: 'raceConditionPolicySns',
  path: '/',
  policy: {
    Version: '2012-10-17',
    Statement: [
      {
        Effect: 'Allow',
        Action: [
          'firehose:DescribeDeliveryStream',
          'firehose:ListDeliveryStreams',
          'firehose:ListTagsForDeliveryStream',
          'firehose:PutRecord',
          'firehose:PutRecordBatch',
        ],
        Resource: [firehoseStream.arn],
      },
    ],
  },
});

const snsRole = new aws.iam.Role(`sns_role`, {
  name: 'raceConditionRoleSns',
  assumeRolePolicy: {
    Version: '2012-10-17',
    Statement: [
      {
        Effect: 'Allow',
        Action: 'sts:AssumeRole',
        Principal: {
          Service: '<http://sns.amazonaws.com|sns.amazonaws.com>',
        },
      },
    ],
  },
});

var policyAttachment = new aws.iam.RolePolicyAttachment('sns_role_policy_attachment', {
   policyArn: snsPolicy.arn,
   role: snsRole.name,
});

new aws.sns.TopicSubscription('firehose_sub', {
  topic: snsTopic.arn,
  protocol: 'firehose',
  endpoint: firehoseStream.arn,
  subscriptionRoleArn: snsRole.arn,
}, {
  dependsOn: policyAttachment,
});
r
I can do that, thank you!