Reputation: 304
I am facing a strange behavior in an AWS IAM's application to automatically create users and roles.
My sequence of operation is:
CreateUser
;CreateAccessKey
for this created user;GetUser
for this created user to get the account id. I need to do this because I only have the root key and secret;CreateRole
, with a AssumeRolePolicyDocument
where the Principal is this created user.When I execute step 4, I receive a MalformedPolicyDocument
(Invalid principal in policy: "AWS":"arn:aws:iam::123412341234:user/newuser"
).
But, if before the step 4 I put a 15 seconds delay, it runs without any problem.
Is there any workflow that I don't need to stick with a fixed delay, like read some IAM webservice to check if the user is ready to be used?
Upvotes: 2
Views: 556
Reputation: 64751
As outlined in my answer to Deterministically creating and tagging EC2 instances, the AWS APIs need to be generally treated as eventually consistent only.
Specifically, I mention that it is reasonable to assume that each and every single API action is operated entirely independently by AWS, i.e. is a micro service on its own. This explains, why even within a service like Amazon EC2 or in your case AWS Identity and Access Management (IAM), a call to one API action that results in a resource state change isn't necessarily visible to (all) other API actions within that service right away - that's precisely what you are experiencing, i.e. even though the created user is already visible for one of the other IAM APIs GetUser
, it isn't yet visible for a different IAM API action CreateRole
.
The correct workflow to work around this inherent characteristics is to repeat the desired API call with an Exponential backoff strategy until it succeeds (or the configured timeout is reached), which is good practice anyway in asynchronous communication scenarios. Several AWS SDKs offer integrated support for retry with exponential support meanwhile, which is usually applied transparently, but can be tailored to specific scenarios if need be, e.g. to extend whatever default timeout for very high latency scenarios etc.
Upvotes: 3