I'm trying to create a user with an access key along the following lines:
import iam = require('@aws-cdk/aws-iam')
const myUserName = 'my-user-name'
const user = new iam.User(this, 'myUser', {
userName: userName
})
const accessKey = new iam.CfnAccessKey(this, 'myAccessKey', {
userName: myUserName
})
new cdk.Output(this, 'accessKeyId', { value: accessKey.accessKeyId });
new cdk.Output(this, 'secretAccessKey', { value: accessKey.accessKeySecretAccessKey });
This works OK when I run it in two stages so that the user gets created in the first deployment and the access key gets created in the second deployment. However, if it's run in a single stage it looks like the creation of the access key does not wait for the user to be created and thus an error occurs.
Is there a way to express the dependency of the access key resource on the user resource?
Hey @floehopper,
can you try:
const accessKey = new CfnAccessKey(this, 'myAccessKey', {
userName: user.userName,
});
?
Thanks,
Adam
Yes, that works perfectly. Thank you!
$ cdk deploy
CdkIamUserStack: deploying...
CdkIamUserStack: creating CloudFormation changeset...
0/4 | 20:22:59 | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata
0/4 | 20:22:59 | CREATE_IN_PROGRESS | AWS::IAM::User | myUser (myUserF51C09EE)
0/4 | 20:23:00 | CREATE_IN_PROGRESS | AWS::IAM::User | myUser (myUserF51C09EE) Resource creation Initiated
0/4 | 20:23:02 | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata Resource creation Initiated
1/4 | 20:23:02 | CREATE_COMPLETE | AWS::CDK::Metadata | CDKMetadata
2/4 | 20:23:35 | CREATE_COMPLETE | AWS::IAM::User | myUser (myUserF51C09EE)
2/4 | 20:23:38 | CREATE_IN_PROGRESS | AWS::IAM::AccessKey | myAccessKey
2/4 | 20:23:38 | CREATE_IN_PROGRESS | AWS::IAM::AccessKey | myAccessKey Resource creation Initiated
3/4 | 20:23:38 | CREATE_COMPLETE | AWS::IAM::AccessKey | myAccessKey
4/4 | 20:23:40 | CREATE_COMPLETE | AWS::CloudFormation::Stack | CdkIamUserStack
Actually a quick follow-up question: if I switch the code for an existing stack from my version to your version, will deploying change the access key credentials? i.e. what does the "replace" mean in the following diff output?
$ cdk --profile my-app diff
Resources
[~] AWS::IAM::AccessKey myAccessKey myAccessKey replace
鈹斺攢 [~] UserName (requires replacement)
鈹溾攢 [-] my-user-name
鈹斺攢 [+] {"Ref":"myUser69C47CE3"}
Yes, 'replace' here means the resource will be deleted and then created again if you do cdk deploy
.
Thanks 馃憤
The syntax mentioned above (cdk.Output
) is out of date. To achieve the same thing now you would use:
new cdk.CfnOutput(this, 'accessKeyId', { value: accessKey.ref });
new cdk.CfnOutput(this, 'secretAccessKey', { value: accessKey.attrSecretAccessKey });
@skinny85 Thanks, that works great!
Would you mind explaining _why_ it works?
Is this a general codified way to indicate dependencies between CDK constructs?
@memark Can you explain which comment are you referencing? What are you asking?
@skinny85, sorry. I mean this
can you try:
const accessKey = new CfnAccessKey(this, 'myAccessKey', {
userName: user.userName,
});
i.e. referencing the previously declared construct instead of just using the userName
string variable as the OP had done.
How and why does this alter the CF template and/or the way it's deployed?
Yes, this is the standard way to reference things in the CDK.
The resulting template will use a { Ref: "UserLogicalId" }
CloudFormation expression, and not simply insert the string value of userName
there.
Most helpful comment
The syntax mentioned above (
cdk.Output
) is out of date. To achieve the same thing now you would use: