Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Encode Properties for CloudFormation CustomResource #375

Closed
1 of 11 tasks
michanto opened this issue Aug 24, 2021 · 2 comments
Closed
1 of 11 tasks

Support Encode Properties for CloudFormation CustomResource #375

michanto opened this issue Aug 24, 2021 · 2 comments
Labels
bar-raiser/needed management/tracking status/stale The RFC did not get any significant enough progress or tracking and has become stale.

Comments

@michanto
Copy link
Contributor

michanto commented Aug 24, 2021

Description

When calling a CustomResource, CloudFormation turns all the JSON properties passed to the resource into strings. This makes it difficult to code a resource that processes non-string data, or to pass data to APIs that require non-string inputs.

The proposal is to add a flag to CustomResource, encodeProperties, that would encode all the properties in a custom resource other than the ServiceToken. If encodeProperties is false (the default), then the CustomResource creates a CfnResource as normal. If encodeProperties is true, the CustomResource instead creates a CfnEncodingResource:

/**
 * This resource will encode it's properties at the last possible moment - during
 * _toCloudFormation conversion of the CfnResource to CloudFormation, specifically
 * in renderProperties.  It is meant to be used for CustomResource, as it does not
 * encode the ServiceToken, and it expects one to be there.
 *
 * This is important because the properties of the resource might not be known until
 * all the Apsects have run, therefore we want to wait until they are all present
 * before encoding them.
 *
 * Why do we encode properties?  Because CloudFormation will turn numbers and booleans
 * into strings when it calls a custom resource Lambda, and that is not always desirable.
 * Encoding the properties prevents that conversion.
 */
export class CfnEncodingResource extends CfnResource {
    protected renderProperties(props: { [p: string]: any }): { [p: string]: any } {
        let serviceToken = props.ServiceToken
        delete props.ServiceToken
        let encodedProperties = {
            ServiceToken: serviceToken,
            EncodedProperties: Fn.base64(Stack.of(this).toJsonString(props))
        }
        return encodedProperties
    }
}

All lambda languages have native support for decoding Base64, so it is not necessary to add direct support for encoded resources to lambda libraries to make this work for end users. Sample code should suffice.

Example Typescript Decoding:

    if ("EncodedProperties" in event["ResourceProperties"]) {
        event["ResourceProperties"] = JSON.parse(Buffer
            .from(event["ResourceProperties"]["EncodedProperties"], "base64")
            .toString("utf8"))
        console.log(`Decoded Event: ${JSON.stringify(event)}`)
    }

Example Python Decoding:

encoded_properties = event["ResourceProperties"].get("EncodedProperties", None)
if encoded_resources:
   event["ResourceProperties"] = json.loads(base64.b64decode(encoded_properties).decode("utf-8")) 

This has become a common solution used by many custom resources. It should just be part of the CDK as an aid to CustomResource authors.

Roles

Role User
Proposed by @michanto
Author(s) @michanto
API Bar Raiser @alias
Stakeholders @alias, @alias, @alias

See RFC Process for details

Workflow

  • Tracking issue created (label: status/proposed)
  • API bar raiser assigned (ping us at #aws-cdk-rfcs if needed)
  • Kick off meeting
  • RFC pull request submitted (label: status/review)
  • Community reach out (via Slack and/or Twitter)
  • API signed-off (label api-approved applied to pull request)
  • Final comments period (label: status/final-comments-period)
  • Approved and merged (label: status/approved)
  • Execution plan submitted (label: status/planning)
  • Plan approved and merged (label: status/implementing)
  • Implementation complete (label: status/done)

Author is responsible to progress the RFC according to this checklist, and
apply the relevant labels to this issue so that the RFC table in README gets
updated.

@mrgrain
Copy link
Contributor

mrgrain commented Oct 27, 2023

Marking this RFCs as stale since there has been little recent activity and it is not currently close to getting accepted as-is. We appreciate the effort that has gone into this proposal. Marking an RFCs as stale is not a one-way door. If you have made substantial changes to the proposal, please open a new issue/RFC. You might also consider raising a PR to aws/aws-cdk directly or self-publishing to Construct Hub.

@mrgrain mrgrain closed this as not planned Won't fix, can't repro, duplicate, stale Oct 27, 2023
@mrgrain mrgrain added status/stale The RFC did not get any significant enough progress or tracking and has become stale. and removed status/proposed Newly proposed RFC labels Oct 27, 2023
@jfly
Copy link

jfly commented Mar 19, 2024

This proposal feels like a workaround for what's actually an underlying CloudFormation bug. Is there documentation or a bug report for the underlying "stringify all the leaf nodes in the json document" behavior?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bar-raiser/needed management/tracking status/stale The RFC did not get any significant enough progress or tracking and has become stale.
Projects
None yet
Development

No branches or pull requests

4 participants