AwsCustomResource: When extracting a json field from response, json response seem to be url encoded
- Dominant language
- TypeScript
- Stars
- 12.9k
- Forks
- 4.6k
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 83
Description
### Describe the bug
I have a simple stack, that uses AwsCustomResource to query an IAM role and fetches AssumeRolePolicyDocument field from the response and proceeds to store that in SSM parameter variable
```
export class GetCurrentAssumePoliciesStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
const roleName = 'role-that-has-trust-policy'
const getRoleCustomResource = new AwsCustomResource(this, "CustomResourcePolicy", {
resourceType: "Custom::GetIamRoleCustomResourcePolicy",
onCreate: {
service: "IAM",
action: "getRole",
parameters: {
RoleName: roleName,
},
physicalResourceId: PhysicalResourceId.of(roleName),
},
onUpdate: {
service: "IAM",
action: "getRole",
parameters: {
RoleName: roleName,
},
physicalResourceId: PhysicalResourceId.of(roleName),
},
policy: AwsCustomResourcePolicy.fromStatements([
new PolicyStatement({
actions: ["iam:*"],
resources: ["*"],
}),
]),
});
new StringParameter(this, "Parameter", {
parameterName: "/path/to/parameter",
description: "Description for your parameter",
stringValue: getRoleCustomResource.getResponseField("Role.AssumeRolePolicyDocument"),
});
}
}
```
When the stack is deployed, i noticed that the value in SSM Param store for the key /path/to/parameter seems to be URL encoded. Here is how it looks like
`%7B%22Version%22%3A%222012-10-17%22%2C%22Statement%22%3A%5B%7B%22Effect%22%3A%22Allow%22%2C%22Principal%22%3A%7B%22AWS%22%3A%22arn%3Aaws%3Aiam%3A%3A123456789%3Aroot%22%7D%2C%22Action%22%3A%22sts%3AAssumeRole%22%7D%5D%7D`
This is an issue for me because in a different stack, i need to be able to read this json from SSM param store and use it
### Expected Behavior
When the stack is deployed, i expect the following value to be present in the SSM Param store for the key /path/to/parameter
```json
{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"AWS":"arn:aws:iam::123456789:root"},"Action":"sts:AssumeRole"}]}
```
### Current Behavior
When the stack is deployed, i noticed that the value in SSM Param store for the key /path/to/parameter seems to be URL encoded. Here is how it looks like
`%7B%22Version%22%3A%222012-10-17%22%2C%22Statement%22%3A%5B%7B%22Effect%22%3A%22Allow%22%2C%22Principal%22%3A%7B%22AWS%22%3A%22arn%3Aaws%3Aiam%3A%3A123456789%3Aroot%22%7D%2C%22Action%22%3A%22sts%3AAssumeRole%22%7D%5D%7D`
### Reproduction Steps
you can deploy the stack, as you would normally after having updated the role for which you are querying the information for
### Possible Solution
_No response_
### Additional Information/Context
I tried decoding the value from the response before storing SSM Parameter store like this
```
new StringParameter(this, "Parameter", {
parameterName: "/path/to/parameter",
description: "Description for your parameter",
stringValue: decodeURIComponent(getRoleCustomResource.getResponseField("Role.AssumeRolePolicyDocument")),
});
```
But this did not work for me
### CDK CLI Version
2.55.0
### Framework Version
2.55.0
### Node.js Version
v18.11.0
### OS
Mac
### Language
Typescript
### Language Version
_No response_
### Other information
_No response_
Contributor guide
Research direction
Start by reproducing the deployment with AwsCustomResource.getResponseField("Role.AssumeRolePolicyDocument") and StringParameter, then inspect how the IAM getRole response is passed into the parameter. Compare the stored value with the expected JSON and trace where URL encoding is introduced; done means the response field is stored in SSM in the expected form without breaking other response fields.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- aws, typescript
- Domain
- cloud, infrastructure
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100