aws / aws-cdk-rfcs

RFCs for the AWS CDK

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

CloudFormation Registry Support

eladb opened this issue · comments

Description

This proposal is to stop generating the CloudFormation Resources (also known as Cfn* classes / L1 Constructs) from the legacy CloudFormation Resource Specification document, and instead to leverage the improved schema that is provided as part of the CloudFormation Registry.

We recommend to use the import terminology and imports/ directory to align with cdk8s.

$ cdk import My::Resource::Example [--language python|dotnet|java|typescript]
imports/my/resource/example.ts

The CloudFormation resource spec is evolving and plans to support arbitrary JSON schema for resource properties. This will require that we will be able to generate code that models things like JSON unions (what else?).

Roles

Role User
Proposed by @eladb
Author(s) @rix0rrr, @eladb
API Bar Raiser @eladb

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.

Representing Unions

We have an idiom for JSON unions which is based on a class with static methods. The problem will be what name we should give the methods.

For example, say a property can accept either a string or boolean, then we can generate a union such as:

class MyOption {
  public static string(v: string) { return new MyOption(v); }
  public static boolean(v: boolean) { return new MyOption(b); }
  
  /** @internal */
  public get _value() { return this.value; }
  private constructor(private readonly value: any) { }
}

Then, usage will be:

{
  option: MyOption.string('foo'),
  // or
  option: MyOption.boolean(true)
}

However, this becomes hairier when the union accepts multiple complex types (and possibly even a mix between complex types and primitives, collections, etc). Then it becomes hard to name the static methods.

Say the schema is: foo: string | { string: number } (using typescript, but JSON schema can represent this of course).

Then what?

--

We can always say that we fall back to idiomatic untyped JSON representation for those L1s. It's probably not going to be the majority. Alternatively, we can also add first-class support for JSON schema in jsii and use idiomatic JSON schema generators.

Copy @awslabs/aws-cdk-team

@workeitel wrote:

Use Case

So far cfn2ts tool was only used for generating L1 TS files for the CloudFormation resource specification. The cfn2ts tool is hardcoded to use the cfnspec package which has all resources checked in: https://github.com/aws/aws-cdk/blob/master/tools/cfn2ts/lib/index.ts#L1

With the latest launch of CloudFormation resource registry: https://aws.amazon.com/blogs/aws/cloudformation-update-cli-third-party-resource-support-registry/ everybody can build own CloudFormation resources (not only custom resources as before). That includes multiple steps including defining a Resource Provider Schema ( != resource specification )

Proposed Solution

The perfect scenario would be if

  1. cfn2ts understands the resource provider schema and I can generate L1 constructs directly based on it
  2. OR CloudFormation supports generating resource specification out of the resource provider schema and I can use then cfn2ts to generate L1 constructs.

Because both solutions most likely require more time I would like to see a better way of triggering cfn2ts in the meanwhile.

What works today:

  1. I write manually/generate with a custom tool a resource specification out of my resource provider schema
  2. I checkout the cdk repo since cfn2ts is not published on npm.
  3. Manually patch this line to point to my own resource specification: https://github.com/aws/aws-cdk/blob/master/packages/%40aws-cdk/cfnspec/lib/index.ts#L9
  4. run cfn2ts to get my L1

Other

I suggest:

  1. something like cfn2ts --cfnspec-path ../myresource.json to override the path to the CloudFormation spec.
  2. Publishing cfn2ts as a own npm package for easier consumption.

In the interim, I resorted to a similar method described above, and (haphazardly) transform my registry schema into a resource specification "patch", that a build tool places into packages/@aws-cdk/cfnspec/spec-source/999_FooBar_patch.json. cfn2ts can then generate required constructs.

Just curious if this is still planned or maybe already implemented and i missed it.
I have the use case that for a 3rd party vendor that publishes their own resources for CloudFormation that I'd like to generate the L1 constructs from that.

Just curious if this is still planned or maybe already implemented and i missed it. I have the use case that for a 3rd party vendor that publishes their own resources for CloudFormation that I'd like to generate the L1 constructs from that.

https://github.com/cdklabs/cdk-import/

They are generated and published as separate libs.