diff --git a/packages/@aws-cdk/assets/lib/asset.ts b/packages/@aws-cdk/assets/lib/asset.ts index 92e010de59983..f8e53a0a0a36a 100644 --- a/packages/@aws-cdk/assets/lib/asset.ts +++ b/packages/@aws-cdk/assets/lib/asset.ts @@ -97,7 +97,7 @@ export class Asset extends cdk.Construct { this.s3BucketName = bucketParam.value; this.s3Prefix = new cdk.FnSelect(0, new cdk.FnSplit(cxapi.ASSET_PREFIX_SEPARATOR, keyParam.value)); const s3Filename = new cdk.FnSelect(1, new cdk.FnSplit(cxapi.ASSET_PREFIX_SEPARATOR, keyParam.value)); - this.s3ObjectKey = new cdk.FnConcat(this.s3Prefix, s3Filename); + this.s3ObjectKey = new s3.ObjectKey(new cdk.FnConcat(this.s3Prefix, s3Filename)); this.bucket = s3.BucketRef.import(parent, 'AssetBucket', { bucketName: this.s3BucketName diff --git a/packages/@aws-cdk/assets/test/integ.assets.refs.lit.expected.json b/packages/@aws-cdk/assets/test/integ.assets.refs.lit.expected.json index 6f239e31e2a97..9539e0a25879a 100644 --- a/packages/@aws-cdk/assets/test/integ.assets.refs.lit.expected.json +++ b/packages/@aws-cdk/assets/test/integ.assets.refs.lit.expected.json @@ -76,29 +76,36 @@ }, "/", { - "Fn::Select": [ - 0, - { - "Fn::Split": [ - "||", - { - "Ref": "SampleAssetS3VersionKey3E106D34" - } - ] - } - ] - }, - { - "Fn::Select": [ - 1, - { - "Fn::Split": [ - "||", - { - "Ref": "SampleAssetS3VersionKey3E106D34" - } - ] - } + "Fn::Join": [ + "", + [ + { + "Fn::Select": [ + 0, + { + "Fn::Split": [ + "||", + { + "Ref": "SampleAssetS3VersionKey3E106D34" + } + ] + } + ] + }, + { + "Fn::Select": [ + 1, + { + "Fn::Split": [ + "||", + { + "Ref": "SampleAssetS3VersionKey3E106D34" + } + ] + } + ] + } + ] ] } ] diff --git a/packages/@aws-cdk/aws-autoscaling/test/test.auto-scaling-group.ts b/packages/@aws-cdk/aws-autoscaling/test/test.auto-scaling-group.ts index 5deccbfbe8d5b..321d8d6235787 100644 --- a/packages/@aws-cdk/aws-autoscaling/test/test.auto-scaling-group.ts +++ b/packages/@aws-cdk/aws-autoscaling/test/test.auto-scaling-group.ts @@ -336,9 +336,9 @@ export = { function mockVpc(stack: cdk.Stack) { return ec2.VpcNetwork.import(stack, 'MyVpc', { - vpcId: new ec2.VpcNetworkId('my-vpc'), + vpcId: new ec2.VPCId('my-vpc'), availabilityZones: [ 'az1' ], - publicSubnetIds: [ new ec2.VpcSubnetId('pub1') ], - privateSubnetIds: [ new ec2.VpcSubnetId('pri1') ], + publicSubnetIds: [ new ec2.SubnetId('pub1') ], + privateSubnetIds: [ new ec2.SubnetId('pri1') ], }); } diff --git a/packages/@aws-cdk/aws-certificatemanager/lib/certificate-ref.ts b/packages/@aws-cdk/aws-certificatemanager/lib/certificate-ref.ts index d208a2f74ba5c..76d8d9b687e77 100644 --- a/packages/@aws-cdk/aws-certificatemanager/lib/certificate-ref.ts +++ b/packages/@aws-cdk/aws-certificatemanager/lib/certificate-ref.ts @@ -1,10 +1,5 @@ -import { Arn, Construct, Output } from "@aws-cdk/cdk"; - -/** - * Represents the ARN of a certificate - */ -export class CertificateArn extends Arn { -} +import { Construct, Output } from "@aws-cdk/cdk"; +import { CertificateArn } from './certificatemanager.generated'; /** * Interface for certificate-like objects diff --git a/packages/@aws-cdk/aws-certificatemanager/lib/certificate.ts b/packages/@aws-cdk/aws-certificatemanager/lib/certificate.ts index 8265b749be8ab..99d75a7cc07f2 100644 --- a/packages/@aws-cdk/aws-certificatemanager/lib/certificate.ts +++ b/packages/@aws-cdk/aws-certificatemanager/lib/certificate.ts @@ -1,6 +1,6 @@ import { Construct } from '@aws-cdk/cdk'; -import { CertificateArn, CertificateRef } from './certificate-ref'; -import { cloudformation } from './certificatemanager.generated'; +import { CertificateRef } from './certificate-ref'; +import { CertificateArn, cloudformation } from './certificatemanager.generated'; import { apexDomain } from './util'; /** diff --git a/packages/@aws-cdk/aws-cloudformation/example/cdk.json b/packages/@aws-cdk/aws-cloudformation/examples/cdk.json similarity index 100% rename from packages/@aws-cdk/aws-cloudformation/example/cdk.json rename to packages/@aws-cdk/aws-cloudformation/examples/cdk.json diff --git a/packages/@aws-cdk/aws-cloudformation/example/index.ts b/packages/@aws-cdk/aws-cloudformation/examples/index.ts similarity index 100% rename from packages/@aws-cdk/aws-cloudformation/example/index.ts rename to packages/@aws-cdk/aws-cloudformation/examples/index.ts diff --git a/packages/@aws-cdk/aws-cloudformation/example/provider.py b/packages/@aws-cdk/aws-cloudformation/examples/provider.py similarity index 100% rename from packages/@aws-cdk/aws-cloudformation/example/provider.py rename to packages/@aws-cdk/aws-cloudformation/examples/provider.py diff --git a/packages/@aws-cdk/aws-codebuild/lib/project.ts b/packages/@aws-cdk/aws-codebuild/lib/project.ts index 48120f478fa55..7ff73c7276df1 100644 --- a/packages/@aws-cdk/aws-codebuild/lib/project.ts +++ b/packages/@aws-cdk/aws-codebuild/lib/project.ts @@ -5,7 +5,7 @@ import kms = require('@aws-cdk/aws-kms'); import s3 = require('@aws-cdk/aws-s3'); import cdk = require('@aws-cdk/cdk'); import { BuildArtifacts, CodePipelineBuildArtifacts, NoBuildArtifacts } from './artifacts'; -import { cloudformation, ProjectArn } from './codebuild.generated'; +import { cloudformation, ProjectArn, ProjectName } from './codebuild.generated'; import { BuildSource } from './source'; const CODEPIPELINE_TYPE = 'CODEPIPELINE'; @@ -704,6 +704,4 @@ export enum BuildEnvironmentVariableType { * An environment variable stored in Systems Manager Parameter Store. */ ParameterStore = 'PARAMETER_STORE' -} - -export class ProjectName extends cdk.Token { } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-codepipeline/lib/pipeline.ts b/packages/@aws-cdk/aws-codepipeline/lib/pipeline.ts index 0044707ef3f15..ffe8b6f01c214 100644 --- a/packages/@aws-cdk/aws-codepipeline/lib/pipeline.ts +++ b/packages/@aws-cdk/aws-codepipeline/lib/pipeline.ts @@ -4,7 +4,7 @@ import iam = require('@aws-cdk/aws-iam'); import s3 = require('@aws-cdk/aws-s3'); import cdk = require('@aws-cdk/cdk'); import util = require('@aws-cdk/util'); -import { cloudformation, PipelineVersion } from './codepipeline.generated'; +import { cloudformation, PipelineName, PipelineVersion } from './codepipeline.generated'; import { Stage } from './stage'; /** @@ -12,11 +12,6 @@ import { Stage } from './stage'; */ export class PipelineArn extends cdk.Arn { } -/** - * The name of the pipeline. - */ -export class PipelineName extends cdk.Token { } - export interface PipelineProps { /** * The S3 bucket used by this Pipeline to store artifacts. diff --git a/packages/@aws-cdk/aws-dynamodb/lib/index.ts b/packages/@aws-cdk/aws-dynamodb/lib/index.ts index 6aa8541733f21..45e70d3bb0f0a 100644 --- a/packages/@aws-cdk/aws-dynamodb/lib/index.ts +++ b/packages/@aws-cdk/aws-dynamodb/lib/index.ts @@ -1,123 +1,2 @@ -import { Construct, Token } from '@aws-cdk/cdk'; -import { cloudformation } from './dynamodb.generated'; - -// AWS::DynamoDB CloudFormation Resources: export * from './dynamodb.generated'; - -const HASH_KEY_TYPE = 'HASH'; -const RANGE_KEY_TYPE = 'RANGE'; - -export interface TableProps { - /** - * The read capacity for the table. Careful if you add Global Secondary Indexes, as - * those will share the table's provisioned throughput. - * @default 5 - */ - readCapacity?: number; - /** - * The write capacity for the table. Careful if you add Global Secondary Indexes, as - * those will share the table's provisioned throughput. - * @default 5 - */ - writeCapacity?: number; - - /** - * Enforces a particular physical table name. - * @default - */ - tableName?: string; -} - -/** - * Provides a DynamoDB table. - */ -export class Table extends Construct { - private readonly table: cloudformation.TableResource; - - private readonly keySchema = new Array(); - private readonly attributeDefinitions = new Array(); - - constructor(parent: Construct, name: string, props: TableProps = {}) { - super(parent, name); - - const readCapacityUnits = props.readCapacity || 5; - const writeCapacityUnits = props.writeCapacity || 5; - - this.table = new cloudformation.TableResource(this, 'Resource', { - tableName: props.tableName, - keySchema: this.keySchema, - attributeDefinitions: this.attributeDefinitions, - provisionedThroughput: { readCapacityUnits, writeCapacityUnits } - }); - - if (props.tableName) { this.addMetadata('aws:cdk:hasPhysicalName', props.tableName); } - } - - public get tableArn() { - return this.table.tableArn; - } - - public get tableName() { - return this.table.ref as TableName; - } - - public get tableStreamArn() { - return this.table.tableStreamArn; - } - - public addPartitionKey(name: string, type: KeyAttributeType): this { - this.addKey(name, type, HASH_KEY_TYPE); - return this; - } - - public addSortKey(name: string, type: KeyAttributeType): this { - this.addKey(name, type, RANGE_KEY_TYPE); - return this; - } - - public validate(): string[] { - const errors = new Array(); - if (!this.findKey(HASH_KEY_TYPE)) { - errors.push('a partition key must be specified'); - } - return errors; - } - - private findKey(keyType: string) { - return this.keySchema.find(prop => prop.keyType === keyType); - } - - private addKey(name: string, type: KeyAttributeType, keyType: string) { - const existingProp = this.findKey(keyType); - if (existingProp) { - throw new Error(`Unable to set ${name} as a ${keyType} key, because ${existingProp.attributeName} is a ${keyType} key`); - } - this.registerAttribute(name, type); - this.keySchema.push({ - attributeName: name, - keyType - }); - return this; - } - - private registerAttribute(name: string, type: KeyAttributeType) { - const existingDef = this.attributeDefinitions.find(def => def.attributeName === name); - if (existingDef && existingDef.attributeType !== type) { - throw new Error(`Unable to specify ${name} as ${type} because it was already defined as ${existingDef.attributeType}`); - } - if (!existingDef) { - this.attributeDefinitions.push({ - attributeName: name, - attributeType: type - }); - } - } -} - -export class TableName extends Token {} - -export enum KeyAttributeType { - Binary = 'B', - Number = 'N', - String = 'S', -} +export * from './table'; diff --git a/packages/@aws-cdk/aws-dynamodb/lib/table.ts b/packages/@aws-cdk/aws-dynamodb/lib/table.ts new file mode 100644 index 0000000000000..d6a3ff419a6f4 --- /dev/null +++ b/packages/@aws-cdk/aws-dynamodb/lib/table.ts @@ -0,0 +1,114 @@ +import { Construct } from '@aws-cdk/cdk'; +import { cloudformation, TableArn, TableName, TableStreamArn } from './dynamodb.generated'; + +const HASH_KEY_TYPE = 'HASH'; +const RANGE_KEY_TYPE = 'RANGE'; + +export interface TableProps { + /** + * The read capacity for the table. Careful if you add Global Secondary Indexes, as + * those will share the table's provisioned throughput. + * @default 5 + */ + readCapacity?: number; + /** + * The write capacity for the table. Careful if you add Global Secondary Indexes, as + * those will share the table's provisioned throughput. + * @default 5 + */ + writeCapacity?: number; + + /** + * Enforces a particular physical table name. + * @default + */ + tableName?: string; +} + +/** + * Provides a DynamoDB table. + */ +export class Table extends Construct { + public readonly tableArn: TableArn; + public readonly tableName: TableName; + public readonly tableStreamArn: TableStreamArn; + + private readonly table: cloudformation.TableResource; + + private readonly keySchema = new Array(); + private readonly attributeDefinitions = new Array(); + + constructor(parent: Construct, name: string, props: TableProps = {}) { + super(parent, name); + + const readCapacityUnits = props.readCapacity || 5; + const writeCapacityUnits = props.writeCapacity || 5; + + this.table = new cloudformation.TableResource(this, 'Resource', { + tableName: props.tableName, + keySchema: this.keySchema, + attributeDefinitions: this.attributeDefinitions, + provisionedThroughput: { readCapacityUnits, writeCapacityUnits } + }); + + if (props.tableName) { this.addMetadata('aws:cdk:hasPhysicalName', props.tableName); } + + this.tableArn = this.table.tableArn; + this.tableName = this.table.ref; + this.tableStreamArn = this.table.tableStreamArn; + } + + public addPartitionKey(name: string, type: KeyAttributeType): this { + this.addKey(name, type, HASH_KEY_TYPE); + return this; + } + + public addSortKey(name: string, type: KeyAttributeType): this { + this.addKey(name, type, RANGE_KEY_TYPE); + return this; + } + + public validate(): string[] { + const errors = new Array(); + if (!this.findKey(HASH_KEY_TYPE)) { + errors.push('a partition key must be specified'); + } + return errors; + } + + private findKey(keyType: string) { + return this.keySchema.find(prop => prop.keyType === keyType); + } + + private addKey(name: string, type: KeyAttributeType, keyType: string) { + const existingProp = this.findKey(keyType); + if (existingProp) { + throw new Error(`Unable to set ${name} as a ${keyType} key, because ${existingProp.attributeName} is a ${keyType} key`); + } + this.registerAttribute(name, type); + this.keySchema.push({ + attributeName: name, + keyType + }); + return this; + } + + private registerAttribute(name: string, type: KeyAttributeType) { + const existingDef = this.attributeDefinitions.find(def => def.attributeName === name); + if (existingDef && existingDef.attributeType !== type) { + throw new Error(`Unable to specify ${name} as ${type} because it was already defined as ${existingDef.attributeType}`); + } + if (!existingDef) { + this.attributeDefinitions.push({ + attributeName: name, + attributeType: type + }); + } + } +} + +export enum KeyAttributeType { + Binary = 'B', + Number = 'N', + String = 'S', +} diff --git a/packages/@aws-cdk/aws-ec2/lib/security-group.ts b/packages/@aws-cdk/aws-ec2/lib/security-group.ts index b506df17aae46..0204439d1d74b 100644 --- a/packages/@aws-cdk/aws-ec2/lib/security-group.ts +++ b/packages/@aws-cdk/aws-ec2/lib/security-group.ts @@ -1,6 +1,6 @@ import { Construct, Output, Token } from '@aws-cdk/cdk'; import { Connections, IConnectable } from './connections'; -import { cloudformation, SecurityGroupId, SecurityGroupVpcId } from './ec2.generated'; +import { cloudformation, SecurityGroupId, SecurityGroupName, SecurityGroupVpcId } from './ec2.generated'; import { IPortRange, ISecurityGroupRule } from './security-group-rule'; import { slugify } from './util'; import { VpcNetworkRef } from './vpc-ref'; @@ -198,8 +198,6 @@ export class SecurityGroup extends SecurityGroupRef { } } -export class SecurityGroupName extends Token { } - export interface ConnectionRule { /** * The IP protocol name (tcp, udp, icmp) or number (see Protocol Numbers). diff --git a/packages/@aws-cdk/aws-ec2/lib/vpc-ref.ts b/packages/@aws-cdk/aws-ec2/lib/vpc-ref.ts index 7a7500fe4b538..7ad02e46ca69f 100644 --- a/packages/@aws-cdk/aws-ec2/lib/vpc-ref.ts +++ b/packages/@aws-cdk/aws-ec2/lib/vpc-ref.ts @@ -1,4 +1,5 @@ -import { Construct, IDependable, Output, StringListOutput, Token } from "@aws-cdk/cdk"; +import { Construct, IDependable, Output, StringListOutput } from "@aws-cdk/cdk"; +import { SubnetId, VPCId } from "./ec2.generated"; /** * Customize how instances are placed inside a VPC @@ -31,7 +32,7 @@ export abstract class VpcNetworkRef extends Construct implements IDependable { /** * Identifier for this VPC */ - public abstract readonly vpcId: VpcNetworkId; + public abstract readonly vpcId: VPCId; /** * List of public subnets in this VPC @@ -76,7 +77,7 @@ class ImportedVpcNetwork extends VpcNetworkRef { /** * Identifier for this VPC */ - public readonly vpcId: VpcNetworkId; + public readonly vpcId: VPCId; /** * List of public subnets in this VPC @@ -120,7 +121,7 @@ export interface VpcNetworkRefProps { /** * VPC's identifier */ - vpcId: VpcNetworkId; + vpcId: VPCId; /** * List of a availability zones, one for every subnet. @@ -135,20 +136,14 @@ export interface VpcNetworkRefProps { * * Must match the availability zones and private subnet ids in length and order. */ - publicSubnetIds: VpcSubnetId[]; + publicSubnetIds: SubnetId[]; /** * List of private subnet IDs, one for every subnet * * Must match the availability zones and public subnet ids in length and order. */ - privateSubnetIds: VpcSubnetId[]; -} - -/** - * Identifier for a VPC - */ -export class VpcNetworkId extends Token { + privateSubnetIds: SubnetId[]; } /** @@ -167,7 +162,7 @@ export abstract class VpcSubnetRef extends Construct implements IDependable { /** * The subnetId for this particular subnet */ - public abstract readonly subnetId: VpcSubnetId; + public abstract readonly subnetId: SubnetId; /** * Parts of this VPC subnet @@ -187,7 +182,7 @@ class ImportedVpcSubnet extends VpcSubnetRef { /** * The subnetId for this particular subnet */ - public readonly subnetId: VpcSubnetId; + public readonly subnetId: SubnetId; constructor(parent: Construct, name: string, props: VpcSubnetRefProps) { super(parent, name); @@ -206,13 +201,7 @@ export interface VpcSubnetRefProps { /** * The subnetId for this particular subnet */ - subnetId: VpcSubnetId; -} - -/** - * Id of a VPC Subnet - */ -export class VpcSubnetId extends Token { + subnetId: SubnetId; } /** diff --git a/packages/@aws-cdk/aws-ec2/lib/vpc.ts b/packages/@aws-cdk/aws-ec2/lib/vpc.ts index 17c2c33a368a1..2bca6d6a97251 100644 --- a/packages/@aws-cdk/aws-ec2/lib/vpc.ts +++ b/packages/@aws-cdk/aws-ec2/lib/vpc.ts @@ -1,8 +1,8 @@ import cdk = require('@aws-cdk/cdk'); import { Obj } from '@aws-cdk/util'; -import { cloudformation } from './ec2.generated'; +import { cloudformation, SubnetId, VPCId } from './ec2.generated'; import { NetworkBuilder } from './network-util'; -import { VpcNetworkId, VpcNetworkRef, VpcSubnetId, VpcSubnetRef } from './vpc-ref'; +import { VpcNetworkRef, VpcSubnetRef } from './vpc-ref'; /** * VpcNetworkProps allows you to specify configuration options for a VPC */ @@ -231,7 +231,7 @@ export class VpcNetwork extends VpcNetworkRef { /** * Identifier for this VPC */ - public readonly vpcId: VpcNetworkId; + public readonly vpcId: VPCId; /** * List of public subnets in this VPC @@ -466,7 +466,7 @@ export class VpcSubnet extends VpcSubnetRef { /** * The subnetId for this particular subnet */ - public readonly subnetId: VpcSubnetId; + public readonly subnetId: SubnetId; /** * The routeTableId attached to this subnet. diff --git a/packages/@aws-cdk/aws-iam/lib/group.ts b/packages/@aws-cdk/aws-iam/lib/group.ts index b9b37f5f997cf..d8afa34375b4f 100644 --- a/packages/@aws-cdk/aws-iam/lib/group.ts +++ b/packages/@aws-cdk/aws-iam/lib/group.ts @@ -1,5 +1,5 @@ -import { ArnPrincipal, Construct, PolicyPrincipal, PolicyStatement, Token } from '@aws-cdk/cdk'; -import { cloudformation, GroupArn } from './iam.generated'; +import { ArnPrincipal, Construct, PolicyPrincipal, PolicyStatement } from '@aws-cdk/cdk'; +import { cloudformation, GroupArn, GroupName } from './iam.generated'; import { IIdentityResource, IPrincipal, Policy } from './policy'; import { User } from './user'; import { AttachedPolicies, undefinedIfEmpty } from './util'; @@ -104,8 +104,4 @@ export class Group extends Construct implements IIdentityResource, IPrincipal { this.defaultPolicy.addStatement(statement); } -} - -export class GroupName extends Token { - -} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-iam/lib/role.ts b/packages/@aws-cdk/aws-iam/lib/role.ts index 260f99f02bb60..0eb2b88055e06 100644 --- a/packages/@aws-cdk/aws-iam/lib/role.ts +++ b/packages/@aws-cdk/aws-iam/lib/role.ts @@ -1,5 +1,5 @@ -import { ArnPrincipal, Construct, IDependable, PolicyDocument, PolicyPrincipal, PolicyStatement, Token } from '@aws-cdk/cdk'; -import { cloudformation, RoleArn } from './iam.generated'; +import { ArnPrincipal, Construct, IDependable, PolicyDocument, PolicyPrincipal, PolicyStatement } from '@aws-cdk/cdk'; +import { cloudformation, RoleArn, RoleName } from './iam.generated'; import { IIdentityResource, IPrincipal, Policy } from './policy'; import { AttachedPolicies, undefinedIfEmpty } from './util'; @@ -154,10 +154,6 @@ export class Role extends Construct implements IIdentityResource, IPrincipal, ID } } -export class RoleName extends Token { - -} - function createAssumeRolePolicy(principal: PolicyPrincipal) { return new PolicyDocument() .addStatement(new PolicyStatement() diff --git a/packages/@aws-cdk/aws-iam/lib/user.ts b/packages/@aws-cdk/aws-iam/lib/user.ts index 933b321858ab9..a8040b96caf42 100644 --- a/packages/@aws-cdk/aws-iam/lib/user.ts +++ b/packages/@aws-cdk/aws-iam/lib/user.ts @@ -1,6 +1,6 @@ -import { ArnPrincipal, Construct, PolicyPrincipal, PolicyStatement, Token } from '@aws-cdk/cdk'; +import { ArnPrincipal, Construct, PolicyPrincipal, PolicyStatement } from '@aws-cdk/cdk'; import { Group } from './group'; -import { cloudformation, UserArn } from './iam.generated'; +import { cloudformation, UserArn, UserName } from './iam.generated'; import { IIdentityResource, IPrincipal, Policy } from './policy'; import { AttachedPolicies, undefinedIfEmpty } from './util'; @@ -152,8 +152,4 @@ export class User extends Construct implements IIdentityResource, IPrincipal { return undefined; // no console access } -} - -export class UserName extends Token { - -} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-kinesis/lib/stream.ts b/packages/@aws-cdk/aws-kinesis/lib/stream.ts index 0ca4dbe1c6c7b..c0027a76f36ed 100644 --- a/packages/@aws-cdk/aws-kinesis/lib/stream.ts +++ b/packages/@aws-cdk/aws-kinesis/lib/stream.ts @@ -382,7 +382,7 @@ class ImportedStreamRef extends StreamRef { this.streamArn = props.streamArn; // Get the name from the ARN - this.streamName = cdk.Arn.parseToken(props.streamArn).resourceName; + this.streamName = new StreamName(cdk.Arn.parseToken(props.streamArn).resourceName); if (props.encryptionKey) { this.encryptionKey = kms.EncryptionKeyRef.import(parent, 'Key', props.encryptionKey); diff --git a/packages/@aws-cdk/aws-kms/lib/alias.ts b/packages/@aws-cdk/aws-kms/lib/alias.ts index 248747a9f7912..fac0514430288 100644 --- a/packages/@aws-cdk/aws-kms/lib/alias.ts +++ b/packages/@aws-cdk/aws-kms/lib/alias.ts @@ -1,6 +1,6 @@ -import { Construct, Token } from '@aws-cdk/cdk'; +import { Construct } from '@aws-cdk/cdk'; import { EncryptionKeyRef } from './key'; -import { cloudformation } from './kms.generated'; +import { AliasName, cloudformation } from './kms.generated'; const REQUIRED_ALIAS_PREFIX = 'alias/'; const DISALLOWED_PREFIX = REQUIRED_ALIAS_PREFIX + 'AWS'; @@ -59,5 +59,3 @@ export class EncryptionKeyAlias extends Construct { this.aliasName = resource.ref; } } - -export class AliasName extends Token { } diff --git a/packages/@aws-cdk/aws-lambda/lib/alias.ts b/packages/@aws-cdk/aws-lambda/lib/alias.ts index 11b07bcb65fc5..034f3e4ad4489 100644 --- a/packages/@aws-cdk/aws-lambda/lib/alias.ts +++ b/packages/@aws-cdk/aws-lambda/lib/alias.ts @@ -1,8 +1,8 @@ import iam = require('@aws-cdk/aws-iam'); import cdk = require('@aws-cdk/cdk'); -import { FunctionName, FunctionRef } from './lambda-ref'; +import { FunctionRef } from './lambda-ref'; import { FunctionVersion } from './lambda-version'; -import { cloudformation, FunctionArn } from './lambda.generated'; +import { cloudformation, FunctionArn, FunctionName } from './lambda.generated'; import { Permission } from './permission'; /** diff --git a/packages/@aws-cdk/aws-lambda/lib/lambda-ref.ts b/packages/@aws-cdk/aws-lambda/lib/lambda-ref.ts index 505562b050785..126f3f74b623e 100644 --- a/packages/@aws-cdk/aws-lambda/lib/lambda-ref.ts +++ b/packages/@aws-cdk/aws-lambda/lib/lambda-ref.ts @@ -4,7 +4,7 @@ import iam = require('@aws-cdk/aws-iam'); import logs = require('@aws-cdk/aws-logs'); import s3n = require('@aws-cdk/aws-s3-notifications'); import cdk = require('@aws-cdk/cdk'); -import { cloudformation, FunctionArn } from './lambda.generated'; +import { cloudformation, FunctionArn, FunctionName } from './lambda.generated'; import { Permission } from './permission'; /** @@ -341,5 +341,4 @@ class LambdaRefImport extends FunctionRef { return new cdk.FnSelect(6, new cdk.FnSplit(':', arn)); } -} -export class FunctionName extends cdk.Token { } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-lambda/lib/lambda.ts b/packages/@aws-cdk/aws-lambda/lib/lambda.ts index 620ffe1ceff55..adf5bf5434a1b 100644 --- a/packages/@aws-cdk/aws-lambda/lib/lambda.ts +++ b/packages/@aws-cdk/aws-lambda/lib/lambda.ts @@ -1,9 +1,9 @@ import iam = require('@aws-cdk/aws-iam'); import cdk = require('@aws-cdk/cdk'); import { Code } from './code'; -import { FunctionName, FunctionRef } from './lambda-ref'; +import { FunctionRef } from './lambda-ref'; import { FunctionVersion } from './lambda-version'; -import { cloudformation, FunctionArn } from './lambda.generated'; +import { cloudformation, FunctionArn, FunctionName } from './lambda.generated'; import { Runtime } from './runtime'; export interface FunctionProps { diff --git a/packages/@aws-cdk/aws-lambda/lib/singleton-lambda.ts b/packages/@aws-cdk/aws-lambda/lib/singleton-lambda.ts index 226f69b733ddf..f0c518f33d69f 100644 --- a/packages/@aws-cdk/aws-lambda/lib/singleton-lambda.ts +++ b/packages/@aws-cdk/aws-lambda/lib/singleton-lambda.ts @@ -1,8 +1,8 @@ import iam = require('@aws-cdk/aws-iam'); import cdk = require('@aws-cdk/cdk'); import { Function, FunctionProps } from './lambda'; -import { FunctionName, FunctionRef } from './lambda-ref'; -import { FunctionArn } from './lambda.generated'; +import { FunctionRef } from './lambda-ref'; +import { FunctionArn, FunctionName } from './lambda.generated'; import { Permission } from './permission'; /** diff --git a/packages/@aws-cdk/aws-logs/lib/cross-account-destination.ts b/packages/@aws-cdk/aws-logs/lib/cross-account-destination.ts index 0e982c9e61cc3..d5a4bb0d5ca8e 100644 --- a/packages/@aws-cdk/aws-logs/lib/cross-account-destination.ts +++ b/packages/@aws-cdk/aws-logs/lib/cross-account-destination.ts @@ -1,7 +1,7 @@ import iam = require('@aws-cdk/aws-iam'); import cdk = require('@aws-cdk/cdk'); import { LogGroup } from './log-group'; -import { cloudformation, DestinationArn } from './logs.generated'; +import { cloudformation, DestinationArn, DestinationName } from './logs.generated'; import { ILogSubscriptionDestination, LogSubscriptionDestination } from './subscription-filter'; export interface CrossAccountDestinationProps { @@ -97,10 +97,4 @@ export class CrossAccountDestination extends cdk.Construct implements ILogSubscr private stringifiedPolicyDocument() { return this.policyDocument.isEmpty ? '' : cdk.CloudFormationJSON.stringify(cdk.resolve(this.policyDocument)); } -} - -/** - * Name of a CloudWatch Destination - */ -export class DestinationName extends cdk.Token { -} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-logs/lib/log-group.ts b/packages/@aws-cdk/aws-logs/lib/log-group.ts index e8e0ce1a31f2a..f7810b6d5d9fe 100644 --- a/packages/@aws-cdk/aws-logs/lib/log-group.ts +++ b/packages/@aws-cdk/aws-logs/lib/log-group.ts @@ -1,6 +1,6 @@ import cdk = require('@aws-cdk/cdk'); import { LogStream } from './log-stream'; -import { cloudformation, LogGroupArn } from './logs.generated'; +import { cloudformation, LogGroupArn, LogGroupName } from './logs.generated'; import { MetricFilter } from './metric-filter'; import { IFilterPattern } from './pattern'; import { ILogSubscriptionDestination, SubscriptionFilter } from './subscription-filter'; @@ -119,12 +119,6 @@ export class LogGroup extends cdk.Construct { } } -/** - * Name of a log group - */ -export class LogGroupName extends cdk.Token { -} - /** * Properties for a new LogStream created from a LogGroup */ diff --git a/packages/@aws-cdk/aws-logs/lib/log-stream.ts b/packages/@aws-cdk/aws-logs/lib/log-stream.ts index 057a84736e3ab..e9937fadcb2b3 100644 --- a/packages/@aws-cdk/aws-logs/lib/log-stream.ts +++ b/packages/@aws-cdk/aws-logs/lib/log-stream.ts @@ -1,6 +1,6 @@ import cdk = require('@aws-cdk/cdk'); import { LogGroup } from './log-group'; -import { cloudformation } from './logs.generated'; +import { cloudformation, LogStreamName } from './logs.generated'; /** * Properties for a new LogStream @@ -57,10 +57,4 @@ export class LogStream extends cdk.Construct { this.logStreamName = resource.ref; } -} - -/** - * The name of a log stream - */ -export class LogStreamName extends cdk.Token { -} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-neptune/lib/index.ts b/packages/@aws-cdk/aws-neptune/lib/index.ts index 5639643cbd056..22cf821079fa3 100644 --- a/packages/@aws-cdk/aws-neptune/lib/index.ts +++ b/packages/@aws-cdk/aws-neptune/lib/index.ts @@ -86,12 +86,12 @@ export class NeptuneDatabase extends cdk.Construct implements ec2.IConnectable { /** * Identifier of the cluster */ - public readonly clusterIdentifier: rds.ClusterIdentifier; + public readonly clusterIdentifier: rds.DBClusterName; /** * Identifiers of the replicas */ - public readonly instanceIdentifiers: rds.InstanceIdentifier[] = []; + public readonly instanceIdentifiers: rds.DBInstanceId[] = []; /** * The endpoint to use for read/write operations diff --git a/packages/@aws-cdk/aws-rds/lib/cluster-ref.ts b/packages/@aws-cdk/aws-rds/lib/cluster-ref.ts index 3ad5fe24036cb..c2affde36ffae 100644 --- a/packages/@aws-cdk/aws-rds/lib/cluster-ref.ts +++ b/packages/@aws-cdk/aws-rds/lib/cluster-ref.ts @@ -1,6 +1,6 @@ import ec2 = require('@aws-cdk/aws-ec2'); import cdk = require('@aws-cdk/cdk'); -import { DBClusterEndpointAddress } from './rds.generated'; +import { DBClusterEndpointAddress, DBClusterEndpointPort, DBClusterName, DBInstanceId } from './rds.generated'; /** * Create a clustered database with a given number of instances. @@ -21,12 +21,12 @@ export abstract class DatabaseClusterRef extends cdk.Construct implements ec2.IC /** * Identifier of the cluster */ - public abstract readonly clusterIdentifier: ClusterIdentifier; + public abstract readonly clusterIdentifier: DBClusterName; /** * Identifiers of the replicas */ - public abstract readonly instanceIdentifiers: InstanceIdentifier[] = []; + public abstract readonly instanceIdentifiers: DBInstanceId[] = []; /** * The endpoint to use for read/write operations @@ -72,7 +72,7 @@ export interface DatabaseClusterRefProps { /** * The database port */ - port: Port; + port: DBClusterEndpointPort; /** * The security group for this database cluster @@ -82,12 +82,12 @@ export interface DatabaseClusterRefProps { /** * Identifier for the cluster */ - clusterIdentifier: ClusterIdentifier; + clusterIdentifier: DBClusterName; /** * Identifier for the instances */ - instanceIdentifiers: InstanceIdentifier[]; + instanceIdentifiers: DBInstanceId[]; /** * Cluster endpoint address @@ -122,12 +122,12 @@ class ImportedDatabaseCluster extends DatabaseClusterRef { /** * Identifier of the cluster */ - public readonly clusterIdentifier: ClusterIdentifier; + public readonly clusterIdentifier: DBClusterName; /** * Identifiers of the replicas */ - public readonly instanceIdentifiers: InstanceIdentifier[] = []; + public readonly instanceIdentifiers: DBInstanceId[] = []; /** * The endpoint to use for read/write operations @@ -165,21 +165,6 @@ class ImportedDatabaseCluster extends DatabaseClusterRef { } } -/** - * Identifier of a cluster - */ -export class ClusterIdentifier extends cdk.Token { } - -/** - * Identifier of an instance - */ -export class InstanceIdentifier extends cdk.Token { } - -/** - * Port part of an address - */ -export class Port extends cdk.Token { } - /** * A complete socket address (hostname + ":" + port) */ @@ -199,16 +184,16 @@ export class Endpoint { /** * The port of the endpoint */ - public readonly port: Port; + public readonly port: DBClusterEndpointPort; /** * The combination of "HOSTNAME:PORT" for this endpoint */ public readonly socketAddress: SocketAddress; - constructor(address: DBClusterEndpointAddress, port: Port) { + constructor(address: DBClusterEndpointAddress, port: DBClusterEndpointPort) { this.hostname = address; this.port = port; - this.socketAddress = new cdk.FnJoin(":", [address, port]); + this.socketAddress = new SocketAddress(new cdk.FnJoin(":", [address, port])); } } diff --git a/packages/@aws-cdk/aws-rds/lib/cluster.ts b/packages/@aws-cdk/aws-rds/lib/cluster.ts index c85c3238df141..33ae72ce4ce91 100644 --- a/packages/@aws-cdk/aws-rds/lib/cluster.ts +++ b/packages/@aws-cdk/aws-rds/lib/cluster.ts @@ -1,9 +1,9 @@ import ec2 = require('@aws-cdk/aws-ec2'); import kms = require('@aws-cdk/aws-kms'); import cdk = require('@aws-cdk/cdk'); -import { ClusterIdentifier, DatabaseClusterRef, Endpoint, InstanceIdentifier } from './cluster-ref'; +import { DatabaseClusterRef, Endpoint } from './cluster-ref'; import { BackupProps, DatabaseClusterEngine, InstanceProps, Login, Parameters } from './props'; -import { cloudformation } from './rds.generated'; +import { cloudformation, DBClusterName, DBInstanceId } from './rds.generated'; /** * Properties for a new database cluster @@ -95,12 +95,12 @@ export class DatabaseCluster extends DatabaseClusterRef { /** * Identifier of the cluster */ - public readonly clusterIdentifier: ClusterIdentifier; + public readonly clusterIdentifier: DBClusterName; /** * Identifiers of the replicas */ - public readonly instanceIdentifiers: InstanceIdentifier[] = []; + public readonly instanceIdentifiers: DBInstanceId[] = []; /** * The endpoint to use for read/write operations diff --git a/packages/@aws-cdk/aws-route53/lib/hosted-zone-ref.ts b/packages/@aws-cdk/aws-route53/lib/hosted-zone-ref.ts index b642621dd60c4..185c33acadeb7 100644 --- a/packages/@aws-cdk/aws-route53/lib/hosted-zone-ref.ts +++ b/packages/@aws-cdk/aws-route53/lib/hosted-zone-ref.ts @@ -1,4 +1,5 @@ -import { Construct, Output, Token } from "@aws-cdk/cdk"; +import { Construct, Output } from "@aws-cdk/cdk"; +import { HostedZoneId } from './route53.generated'; /** * Imported or created hosted zone @@ -29,12 +30,6 @@ export abstract class HostedZoneRef extends Construct { } } -/** - * Hosted zone identifier - */ -export class HostedZoneId extends Token { -} - /** * Reference to a hosted zone */ diff --git a/packages/@aws-cdk/aws-route53/lib/hosted-zone.ts b/packages/@aws-cdk/aws-route53/lib/hosted-zone.ts index 7d342666b0e35..093f6a9a92c99 100644 --- a/packages/@aws-cdk/aws-route53/lib/hosted-zone.ts +++ b/packages/@aws-cdk/aws-route53/lib/hosted-zone.ts @@ -1,8 +1,8 @@ import ec2 = require('@aws-cdk/aws-ec2'); import logs = require('@aws-cdk/aws-logs'); import cdk = require('@aws-cdk/cdk'); -import { HostedZoneId, HostedZoneRef } from './hosted-zone-ref'; -import { cloudformation, HostedZoneNameServers } from './route53.generated'; +import { HostedZoneRef } from './hosted-zone-ref'; +import { cloudformation, HostedZoneId, HostedZoneNameServers } from './route53.generated'; import { validateZoneName } from './util'; /** diff --git a/packages/@aws-cdk/aws-s3/lib/bucket.ts b/packages/@aws-cdk/aws-s3/lib/bucket.ts index 4f7a62e481c16..748789f1d6467 100644 --- a/packages/@aws-cdk/aws-s3/lib/bucket.ts +++ b/packages/@aws-cdk/aws-s3/lib/bucket.ts @@ -6,7 +6,7 @@ import { BucketPolicy } from './bucket-policy'; import { BucketNotifications } from './notifications-resource'; import perms = require('./perms'); import { LifecycleRule } from './rule'; -import { BucketArn, BucketDomainName, BucketDualStackDomainName, cloudformation } from './s3.generated'; +import { BucketArn, BucketDomainName, BucketDualStackDomainName, BucketName, cloudformation } from './s3.generated'; import { parseBucketArn, parseBucketName, validateBucketName } from './util'; /** @@ -144,7 +144,7 @@ export abstract class BucketRef extends cdk.Construct { components.push(key); } - return new cdk.FnConcat(...components); + return new S3Url(new cdk.FnConcat(...components)); } /** @@ -570,13 +570,6 @@ export enum BucketEncryption { Kms = 'KMS', } -/** - * The name of the bucket. - */ -export class BucketName extends cdk.Token { - -} - /** * A key to an S3 object. */ diff --git a/packages/@aws-cdk/aws-s3/test/notification-dests.ts b/packages/@aws-cdk/aws-s3/test/notification-dests.ts index c707a38dfd12c..c49367c35db53 100644 --- a/packages/@aws-cdk/aws-s3/test/notification-dests.ts +++ b/packages/@aws-cdk/aws-s3/test/notification-dests.ts @@ -14,16 +14,17 @@ export class Topic extends cdk.Construct implements s3notifications.IBucketNotif super(parent, id); const resource = new cdk.Resource(this, 'Resource', { type: 'AWS::SNS::Topic' }); + const topicArn = new cdk.Ref(resource); new cdk.Resource(this, 'Policy', { type: 'AWS::SNS::TopicPolicy', properties: { - Topics: [ resource.ref ], + Topics: [ topicArn ], PolicyDocument: this.policy } }); - this.topicArn = resource.ref; + this.topicArn = topicArn; } public asBucketNotificationDestination(bucketArn: cdk.Arn, bucketId: string): s3notifications.BucketNotificationDestinationProps { diff --git a/packages/@aws-cdk/aws-sns/lib/topic-ref.ts b/packages/@aws-cdk/aws-sns/lib/topic-ref.ts index ec16ea348d5a3..07ffdf18430dd 100644 --- a/packages/@aws-cdk/aws-sns/lib/topic-ref.ts +++ b/packages/@aws-cdk/aws-sns/lib/topic-ref.ts @@ -6,14 +6,9 @@ import s3n = require('@aws-cdk/aws-s3-notifications'); import sqs = require('@aws-cdk/aws-sqs'); import cdk = require('@aws-cdk/cdk'); import { TopicPolicy } from './policy'; -import { TopicName } from './sns.generated'; +import { TopicArn, TopicName } from './sns.generated'; import { Subscription, SubscriptionProtocol } from './subscription'; -/** - * ARN of a Topic - */ -export class TopicArn extends cdk.Arn { } - /** * Either a new or imported Topic */ diff --git a/packages/@aws-cdk/aws-sns/lib/topic.ts b/packages/@aws-cdk/aws-sns/lib/topic.ts index 22f70983240fe..66bae18547c59 100644 --- a/packages/@aws-cdk/aws-sns/lib/topic.ts +++ b/packages/@aws-cdk/aws-sns/lib/topic.ts @@ -1,6 +1,6 @@ import { Construct, } from '@aws-cdk/cdk'; -import { cloudformation, TopicName } from './sns.generated'; -import { TopicArn, TopicRef } from './topic-ref'; +import { cloudformation, TopicArn, TopicName } from './sns.generated'; +import { TopicRef } from './topic-ref'; /** * Properties for a new SNS topic diff --git a/packages/@aws-cdk/aws-sqs/lib/queue-ref.ts b/packages/@aws-cdk/aws-sqs/lib/queue-ref.ts index 047abfa325222..81f2677acaa7b 100644 --- a/packages/@aws-cdk/aws-sqs/lib/queue-ref.ts +++ b/packages/@aws-cdk/aws-sqs/lib/queue-ref.ts @@ -2,7 +2,7 @@ import kms = require('@aws-cdk/aws-kms'); import s3n = require('@aws-cdk/aws-s3-notifications'); import cdk = require('@aws-cdk/cdk'); import { QueuePolicy } from './policy'; -import { QueueArn } from './sqs.generated'; +import { QueueArn, QueueUrl } from './sqs.generated'; /** * Reference to a new or existing Amazon SQS queue @@ -153,10 +153,4 @@ class ImportedQueue extends QueueRef { }); } } -} - -/** - * URL of a queue - */ -export class QueueUrl extends cdk.Token { -} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-sqs/lib/queue.ts b/packages/@aws-cdk/aws-sqs/lib/queue.ts index e301133f389be..f0bf362f21f27 100644 --- a/packages/@aws-cdk/aws-sqs/lib/queue.ts +++ b/packages/@aws-cdk/aws-sqs/lib/queue.ts @@ -1,7 +1,7 @@ import kms = require('@aws-cdk/aws-kms'); import cdk = require('@aws-cdk/cdk'); -import { QueueRef, QueueUrl } from './queue-ref'; -import { cloudformation, QueueArn, QueueName } from './sqs.generated'; +import { QueueRef } from './queue-ref'; +import { cloudformation, QueueArn, QueueName, QueueUrl } from './sqs.generated'; import { validateProps } from './validate-props'; /** diff --git a/packages/@aws-cdk/cdk/lib/cloudformation/resource.ts b/packages/@aws-cdk/cdk/lib/cloudformation/resource.ts index ad831f7f27e20..42b17425057c2 100644 --- a/packages/@aws-cdk/cdk/lib/cloudformation/resource.ts +++ b/packages/@aws-cdk/cdk/lib/cloudformation/resource.ts @@ -4,7 +4,7 @@ import { capitalizePropertyNames, ignoreEmpty } from '../core/util'; import { CloudFormationToken } from './cloudformation-token'; import { Condition } from './condition'; import { CreationPolicy, DeletionPolicy, UpdatePolicy } from './resource-policy'; -import { IDependable, Referenceable, StackElement } from './stack'; +import { IDependable, StackElement } from './stack'; export interface ResourceProps { /** @@ -21,7 +21,7 @@ export interface ResourceProps { /** * Represents a CloudFormation resource. */ -export class Resource extends Referenceable { +export class Resource extends StackElement { /** * A decoration used to create a CloudFormation attribute property. * @param customName Custom name for the attribute (default is the name of the property) diff --git a/packages/@aws-cdk/cdk/lib/cloudformation/stack.ts b/packages/@aws-cdk/cdk/lib/cloudformation/stack.ts index 8a4211ad3cf0d..b24ee91e4dbcb 100644 --- a/packages/@aws-cdk/cdk/lib/cloudformation/stack.ts +++ b/packages/@aws-cdk/cdk/lib/cloudformation/stack.ts @@ -392,15 +392,21 @@ export interface TemplateOptions { } /** - * A construct, which is part of a stack and can be referenced using it's logical ID - * using the CloudFormation intrinsic function { Ref: ID }. + * Base class for referenceable CloudFormation constructs which are not Resources + * + * These constructs are things like Conditions and Parameters, can be + * referenced by taking the `.ref` attribute. + * + * Resource constructs do not inherit from Referenceable because they have their + * own, more specific types returned from the .ref attribute. Also, some + * resources aren't referenceable at all (such as BucketPolicies or GatewayAttachments). */ export abstract class Referenceable extends StackElement { /** * Returns a token to a CloudFormation { Ref } that references this entity based on it's logical ID. */ public get ref(): Token { - return new CloudFormationToken({ Ref: this.logicalId }, `${this.logicalId}.Ref`); + return new Ref(this); } } @@ -432,3 +438,12 @@ function stackElements(node: Construct, into: StackElement[] = []): StackElement return into; } + +/** + * A generic, untyped reference to a Stack Element + */ +export class Ref extends CloudFormationToken { + constructor(element: StackElement) { + super({ Ref: element.logicalId }, `${element.logicalId}.Ref`); + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/cdk/test/cloudformation/test.logical-id.ts b/packages/@aws-cdk/cdk/test/cloudformation/test.logical-id.ts index da8bda26f7672..cd90bc1451f23 100644 --- a/packages/@aws-cdk/cdk/test/cloudformation/test.logical-id.ts +++ b/packages/@aws-cdk/cdk/test/cloudformation/test.logical-id.ts @@ -1,5 +1,5 @@ import { Test } from 'nodeunit'; -import { Construct, HashedAddressingScheme, IAddressingScheme, Resource, Stack } from '../../lib'; +import { Construct, HashedAddressingScheme, IAddressingScheme, Ref, Resource, Stack } from '../../lib'; /** * These tests are executed once (for specific ID schemes) @@ -195,7 +195,9 @@ const allSchemesTests: {[name: string]: (scheme: IAddressingScheme, test: Test) // WHEN const c1 = new Resource(stack, 'OriginalName', { type: 'R1' }); - const c2 = new Resource(stack, 'Construct2', { type: 'R2', properties: { ReferenceToR1: c1.ref } }); + const ref = new Ref(c1); + + const c2 = new Resource(stack, 'Construct2', { type: 'R2', properties: { ReferenceToR1: ref } }); c2.addDependency(c1); // THEN diff --git a/packages/@aws-cdk/cdk/test/cloudformation/test.output.ts b/packages/@aws-cdk/cdk/test/cloudformation/test.output.ts index bfbf0693318a7..2cb7870c6b818 100644 --- a/packages/@aws-cdk/cdk/test/cloudformation/test.output.ts +++ b/packages/@aws-cdk/cdk/test/cloudformation/test.output.ts @@ -1,13 +1,15 @@ import { Test } from 'nodeunit'; -import { Construct, Output, resolve, Resource, Stack } from '../../lib'; +import { Construct, Output, Ref, resolve, Resource, Stack } from '../../lib'; export = { 'outputs can be added to the stack'(test: Test) { const stack = new Stack(); const res = new Resource(stack, 'MyResource', { type: 'R' }); + const ref = new Ref(res); + new Output(stack, 'MyOutput', { export: 'ExportName', - value: res.ref, + value: ref, description: 'Output properties' }); test.deepEqual(stack.toCloudFormation(), { Resources: { MyResource: { Type: 'R' } }, diff --git a/packages/@aws-cdk/cdk/test/cloudformation/test.resource.ts b/packages/@aws-cdk/cdk/test/cloudformation/test.resource.ts index 2497303c73d87..4941bf0ad8448 100644 --- a/packages/@aws-cdk/cdk/test/cloudformation/test.resource.ts +++ b/packages/@aws-cdk/cdk/test/cloudformation/test.resource.ts @@ -1,21 +1,19 @@ import { Test } from 'nodeunit'; import { applyRemovalPolicy, Arn, Condition, Construct, DeletionPolicy, - FnEquals, FnNot, HashedAddressingScheme, IDependable, PolicyStatement, Referenceable, + FnEquals, FnNot, HashedAddressingScheme, IDependable, PolicyStatement, RemovalPolicy, Resource, Root, Stack, Token } from '../../lib'; export = { 'all resources derive from Resource, which derives from Entity'(test: Test) { const stack = new Stack(); - const r = new Resource(stack, 'MyResource', { + new Resource(stack, 'MyResource', { type: 'MyResourceType', properties: { Prop1: 'p1', Prop2: 123 } }); - test.ok(r instanceof Referenceable); - test.deepEqual(stack.toCloudFormation(), { Resources: { MyResource: { @@ -51,13 +49,6 @@ export = { test.done(); }, - 'entity.ref will return a token for a CloudFormation {Ref} for this entity'(test: Test) { - const stack = new Stack(); - const res = new Resource(stack, 'MyResource', { type: 'ResourceType' }); - test.deepEqual(res.ref.resolve(), { Ref: 'MyResource' }); - test.done(); - }, - 'resource.props can only be accessed by derived classes'(test: Test) { const stack = new Stack(); const res = new Counter(stack, 'MyResource', { Count: 10 }); diff --git a/packages/@aws-cdk/cfnspec/lib/schema/resource-type.ts b/packages/@aws-cdk/cfnspec/lib/schema/resource-type.ts index 03335a74c5965..a335fa37b7346 100644 --- a/packages/@aws-cdk/cfnspec/lib/schema/resource-type.ts +++ b/packages/@aws-cdk/cfnspec/lib/schema/resource-type.ts @@ -14,6 +14,11 @@ export interface ResourceType extends Documented { * The ``Transform`` required by the resource type, if any. */ RequiredTransform?: string; + + /** + * What kind of value the 'Ref' operator refers to, if any. + */ + RefKind?: string; } export type Attribute = PrimitiveAttribute | ListAttribute; @@ -49,3 +54,20 @@ export function isPrimitiveListAttribute(spec: Attribute): spec is PrimitiveList export function isComplexListAttribute(spec: Attribute): spec is ComplexListAttribute { return isListAttribute(spec) && !!(spec as ComplexListAttribute).ItemType; } + +/** + * Type declaration for special values of the "Ref" attribute represents. + * + * The attribute can take on more values than these, but these are treated specially. + */ +export enum SpecialRefKind { + /** + * No '.ref' member is generated for this type, because it doesn't have a meaningful value. + */ + None = 'None', + + /** + * The generated class will inherit from the built-in 'Arn' type. + */ + Arn = 'Arn' +} diff --git a/packages/@aws-cdk/cfnspec/spec-source/600_RefKinds_patch.json b/packages/@aws-cdk/cfnspec/spec-source/600_RefKinds_patch.json new file mode 100644 index 0000000000000..f0bf3d08c6299 --- /dev/null +++ b/packages/@aws-cdk/cfnspec/spec-source/600_RefKinds_patch.json @@ -0,0 +1,3616 @@ +{ + "ResourceTypes": { + "AWS::AmazonMQ::Broker": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::AmazonMQ::Broker to Id" + } + }, + "AWS::AmazonMQ::Configuration": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::AmazonMQ::Configuration to Id" + } + }, + "AWS::ApiGateway::Account": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::ApiGateway::Account to Id" + } + }, + "AWS::ApiGateway::ApiKey": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::ApiGateway::ApiKey to Id" + } + }, + "AWS::ApiGateway::Authorizer": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::ApiGateway::Authorizer to Id" + } + }, + "AWS::ApiGateway::BasePathMapping": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::ApiGateway::BasePathMapping to Id" + } + }, + "AWS::ApiGateway::ClientCertificate": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::ApiGateway::ClientCertificate to Name" + } + }, + "AWS::ApiGateway::Deployment": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::ApiGateway::Deployment to Id" + } + }, + "AWS::ApiGateway::DocumentationPart": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::ApiGateway::DocumentationPart to Id" + } + }, + "AWS::ApiGateway::DocumentationVersion": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::ApiGateway::DocumentationVersion to Id" + } + }, + "AWS::ApiGateway::DomainName": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::ApiGateway::DomainName to Name" + } + }, + "AWS::ApiGateway::GatewayResponse": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::ApiGateway::GatewayResponse to Id" + } + }, + "AWS::ApiGateway::Method": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::ApiGateway::Method to Id" + } + }, + "AWS::ApiGateway::Model": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::ApiGateway::Model to Name" + } + }, + "AWS::ApiGateway::RequestValidator": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::ApiGateway::RequestValidator to Id" + } + }, + "AWS::ApiGateway::Resource": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::ApiGateway::Resource to Id" + } + }, + "AWS::ApiGateway::RestApi": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::ApiGateway::RestApi to Id" + } + }, + "AWS::ApiGateway::Stage": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::ApiGateway::Stage to Name" + } + }, + "AWS::ApiGateway::UsagePlan": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::ApiGateway::UsagePlan to Id" + } + }, + "AWS::ApiGateway::UsagePlanKey": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::ApiGateway::UsagePlanKey to Id" + } + }, + "AWS::ApiGateway::VpcLink": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::ApiGateway::VpcLink to Id" + } + }, + "AWS::AppSync::ApiKey": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Arn" + } + ], + "description": "Set RefKind of AWS::AppSync::ApiKey to Arn" + } + }, + "AWS::AppSync::DataSource": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Arn" + } + ], + "description": "Set RefKind of AWS::AppSync::DataSource to Arn" + } + }, + "AWS::AppSync::GraphQLApi": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Arn" + } + ], + "description": "Set RefKind of AWS::AppSync::GraphQLApi to Arn" + } + }, + "AWS::AppSync::GraphQLSchema": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::AppSync::GraphQLSchema to Id" + } + }, + "AWS::AppSync::Resolver": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Arn" + } + ], + "description": "Set RefKind of AWS::AppSync::Resolver to Arn" + } + }, + "AWS::ApplicationAutoScaling::ScalableTarget": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::ApplicationAutoScaling::ScalableTarget to Id" + } + }, + "AWS::ApplicationAutoScaling::ScalingPolicy": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Arn" + } + ], + "description": "Set RefKind of AWS::ApplicationAutoScaling::ScalingPolicy to Arn" + } + }, + "AWS::Athena::NamedQuery": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::Athena::NamedQuery to Name" + } + }, + "AWS::AutoScaling::AutoScalingGroup": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::AutoScaling::AutoScalingGroup to Name" + } + }, + "AWS::AutoScaling::LaunchConfiguration": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::AutoScaling::LaunchConfiguration to Name" + } + }, + "AWS::AutoScaling::LifecycleHook": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::AutoScaling::LifecycleHook to Name" + } + }, + "AWS::AutoScaling::ScalingPolicy": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Arn" + } + ], + "description": "Set RefKind of AWS::AutoScaling::ScalingPolicy to Arn" + } + }, + "AWS::AutoScaling::ScheduledAction": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::AutoScaling::ScheduledAction to Name" + } + }, + "AWS::AutoScalingPlans::ScalingPlan": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Arn" + } + ], + "description": "Set RefKind of AWS::AutoScalingPlans::ScalingPlan to Arn" + } + }, + "AWS::Batch::ComputeEnvironment": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Arn" + } + ], + "description": "Set RefKind of AWS::Batch::ComputeEnvironment to Arn" + } + }, + "AWS::Batch::JobDefinition": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Arn" + } + ], + "description": "Set RefKind of AWS::Batch::JobDefinition to Arn" + } + }, + "AWS::Batch::JobQueue": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Arn" + } + ], + "description": "Set RefKind of AWS::Batch::JobQueue to Arn" + } + }, + "AWS::Budgets::Budget": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::Budgets::Budget to Name" + } + }, + "AWS::CertificateManager::Certificate": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Arn" + } + ], + "description": "Set RefKind of AWS::CertificateManager::Certificate to Arn" + } + }, + "AWS::Cloud9::EnvironmentEC2": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::Cloud9::EnvironmentEC2 to Id" + } + }, + "AWS::CloudFormation::CustomResource": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "None" + } + ], + "description": "Set RefKind of AWS::CloudFormation::CustomResource to None" + } + }, + "AWS::CloudFormation::Stack": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::CloudFormation::Stack to Id" + } + }, + "AWS::CloudFormation::WaitCondition": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::CloudFormation::WaitCondition to Name" + } + }, + "AWS::CloudFormation::WaitConditionHandle": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Url" + } + ], + "description": "Set RefKind of AWS::CloudFormation::WaitConditionHandle to Url" + } + }, + "AWS::CloudFront::CloudFrontOriginAccessIdentity": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::CloudFront::CloudFrontOriginAccessIdentity to Id" + } + }, + "AWS::CloudFront::Distribution": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::CloudFront::Distribution to Id" + } + }, + "AWS::CloudFront::StreamingDistribution": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::CloudFront::StreamingDistribution to Id" + } + }, + "AWS::CloudTrail::Trail": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::CloudTrail::Trail to Name" + } + }, + "AWS::CloudWatch::Alarm": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::CloudWatch::Alarm to Name" + } + }, + "AWS::CloudWatch::Dashboard": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::CloudWatch::Dashboard to Name" + } + }, + "AWS::CodeBuild::Project": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::CodeBuild::Project to Name" + } + }, + "AWS::CodeCommit::Repository": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::CodeCommit::Repository to Id" + } + }, + "AWS::CodeDeploy::Application": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::CodeDeploy::Application to Name" + } + }, + "AWS::CodeDeploy::DeploymentConfig": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::CodeDeploy::DeploymentConfig to Id" + } + }, + "AWS::CodeDeploy::DeploymentGroup": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::CodeDeploy::DeploymentGroup to Name" + } + }, + "AWS::CodePipeline::CustomActionType": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::CodePipeline::CustomActionType to Name" + } + }, + "AWS::CodePipeline::Pipeline": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::CodePipeline::Pipeline to Name" + } + }, + "AWS::CodePipeline::Webhook": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::CodePipeline::Webhook to Name" + } + }, + "AWS::Cognito::IdentityPool": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::Cognito::IdentityPool to Id" + } + }, + "AWS::Cognito::IdentityPoolRoleAttachment": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::Cognito::IdentityPoolRoleAttachment to Id" + } + }, + "AWS::Cognito::UserPool": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::Cognito::UserPool to Id" + } + }, + "AWS::Cognito::UserPoolClient": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::Cognito::UserPoolClient to Id" + } + }, + "AWS::Cognito::UserPoolGroup": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::Cognito::UserPoolGroup to Name" + } + }, + "AWS::Cognito::UserPoolUser": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::Cognito::UserPoolUser to Name" + } + }, + "AWS::Cognito::UserPoolUserToGroupAttachment": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::Cognito::UserPoolUserToGroupAttachment to Id" + } + }, + "AWS::Config::AggregationAuthorization": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Arn" + } + ], + "description": "Set RefKind of AWS::Config::AggregationAuthorization to Arn" + } + }, + "AWS::Config::ConfigRule": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::Config::ConfigRule to Name" + } + }, + "AWS::Config::ConfigurationAggregator": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::Config::ConfigurationAggregator to Name" + } + }, + "AWS::Config::ConfigurationRecorder": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::Config::ConfigurationRecorder to Name" + } + }, + "AWS::Config::DeliveryChannel": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::Config::DeliveryChannel to Name" + } + }, + "AWS::DAX::Cluster": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::DAX::Cluster to Name" + } + }, + "AWS::DAX::ParameterGroup": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Arn" + } + ], + "description": "Set RefKind of AWS::DAX::ParameterGroup to Arn" + } + }, + "AWS::DAX::SubnetGroup": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Arn" + } + ], + "description": "Set RefKind of AWS::DAX::SubnetGroup to Arn" + } + }, + "AWS::DMS::Certificate": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Arn" + } + ], + "description": "Set RefKind of AWS::DMS::Certificate to Arn" + } + }, + "AWS::DMS::Endpoint": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Arn" + } + ], + "description": "Set RefKind of AWS::DMS::Endpoint to Arn" + } + }, + "AWS::DMS::EventSubscription": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::DMS::EventSubscription to Name" + } + }, + "AWS::DMS::ReplicationInstance": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Arn" + } + ], + "description": "Set RefKind of AWS::DMS::ReplicationInstance to Arn" + } + }, + "AWS::DMS::ReplicationSubnetGroup": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::DMS::ReplicationSubnetGroup to Name" + } + }, + "AWS::DMS::ReplicationTask": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Arn" + } + ], + "description": "Set RefKind of AWS::DMS::ReplicationTask to Arn" + } + }, + "AWS::DataPipeline::Pipeline": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::DataPipeline::Pipeline to Id" + } + }, + "AWS::DirectoryService::MicrosoftAD": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::DirectoryService::MicrosoftAD to Id" + } + }, + "AWS::DirectoryService::SimpleAD": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::DirectoryService::SimpleAD to Id" + } + }, + "AWS::DynamoDB::Table": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::DynamoDB::Table to Name" + } + }, + "AWS::EC2::CustomerGateway": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::EC2::CustomerGateway to Name" + } + }, + "AWS::EC2::DHCPOptions": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::EC2::DHCPOptions to Name" + } + }, + "AWS::EC2::EIP": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Ip" + } + ], + "description": "Set RefKind of AWS::EC2::EIP to Ip" + } + }, + "AWS::EC2::EIPAssociation": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::EC2::EIPAssociation to Name" + } + }, + "AWS::EC2::EgressOnlyInternetGateway": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::EC2::EgressOnlyInternetGateway to Id" + } + }, + "AWS::EC2::FlowLog": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::EC2::FlowLog to Id" + } + }, + "AWS::EC2::Host": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::EC2::Host to Id" + } + }, + "AWS::EC2::Instance": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::EC2::Instance to Id" + } + }, + "AWS::EC2::InternetGateway": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::EC2::InternetGateway to Name" + } + }, + "AWS::EC2::LaunchTemplate": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::EC2::LaunchTemplate to Id" + } + }, + "AWS::EC2::NatGateway": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::EC2::NatGateway to Id" + } + }, + "AWS::EC2::NetworkAcl": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::EC2::NetworkAcl to Name" + } + }, + "AWS::EC2::NetworkAclEntry": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::EC2::NetworkAclEntry to Name" + } + }, + "AWS::EC2::NetworkInterface": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::EC2::NetworkInterface to Name" + } + }, + "AWS::EC2::NetworkInterfaceAttachment": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::EC2::NetworkInterfaceAttachment to Name" + } + }, + "AWS::EC2::NetworkInterfacePermission": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::EC2::NetworkInterfacePermission to Id" + } + }, + "AWS::EC2::PlacementGroup": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::EC2::PlacementGroup to Name" + } + }, + "AWS::EC2::Route": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::EC2::Route to Name" + } + }, + "AWS::EC2::RouteTable": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::EC2::RouteTable to Id" + } + }, + "AWS::EC2::SecurityGroup": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::EC2::SecurityGroup to Name" + } + }, + "AWS::EC2::SecurityGroupEgress": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::EC2::SecurityGroupEgress to Id" + } + }, + "AWS::EC2::SecurityGroupIngress": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::EC2::SecurityGroupIngress to Id" + } + }, + "AWS::EC2::SpotFleet": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::EC2::SpotFleet to Name" + } + }, + "AWS::EC2::Subnet": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::EC2::Subnet to Id" + } + }, + "AWS::EC2::SubnetCidrBlock": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::EC2::SubnetCidrBlock to Id" + } + }, + "AWS::EC2::SubnetNetworkAclAssociation": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::EC2::SubnetNetworkAclAssociation to Name" + } + }, + "AWS::EC2::SubnetRouteTableAssociation": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::EC2::SubnetRouteTableAssociation to Name" + } + }, + "AWS::EC2::TrunkInterfaceAssociation": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::EC2::TrunkInterfaceAssociation to Id" + } + }, + "AWS::EC2::VPC": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::EC2::VPC to Id" + } + }, + "AWS::EC2::VPCCidrBlock": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::EC2::VPCCidrBlock to Id" + } + }, + "AWS::EC2::VPCDHCPOptionsAssociation": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::EC2::VPCDHCPOptionsAssociation to Name" + } + }, + "AWS::EC2::VPCEndpoint": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::EC2::VPCEndpoint to Id" + } + }, + "AWS::EC2::VPCEndpointConnectionNotification": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "None" + } + ], + "description": "Set RefKind of AWS::EC2::VPCEndpointConnectionNotification to None" + } + }, + "AWS::EC2::VPCEndpointServicePermissions": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "None" + } + ], + "description": "Set RefKind of AWS::EC2::VPCEndpointServicePermissions to None" + } + }, + "AWS::EC2::VPCGatewayAttachment": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::EC2::VPCGatewayAttachment to Name" + } + }, + "AWS::EC2::VPCPeeringConnection": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::EC2::VPCPeeringConnection to Name" + } + }, + "AWS::EC2::VPNConnection": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::EC2::VPNConnection to Name" + } + }, + "AWS::EC2::VPNConnectionRoute": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::EC2::VPNConnectionRoute to Name" + } + }, + "AWS::EC2::VPNGateway": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::EC2::VPNGateway to Name" + } + }, + "AWS::EC2::VPNGatewayRoutePropagation": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::EC2::VPNGatewayRoutePropagation to Name" + } + }, + "AWS::EC2::Volume": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::EC2::Volume to Id" + } + }, + "AWS::EC2::VolumeAttachment": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::EC2::VolumeAttachment to Id" + } + }, + "AWS::ECR::Repository": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::ECR::Repository to Name" + } + }, + "AWS::ECS::Cluster": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::ECS::Cluster to Name" + } + }, + "AWS::ECS::Service": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Arn" + } + ], + "description": "Set RefKind of AWS::ECS::Service to Arn" + } + }, + "AWS::ECS::TaskDefinition": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Arn" + } + ], + "description": "Set RefKind of AWS::ECS::TaskDefinition to Arn" + } + }, + "AWS::EFS::FileSystem": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::EFS::FileSystem to Id" + } + }, + "AWS::EFS::MountTarget": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::EFS::MountTarget to Id" + } + }, + "AWS::EKS::Cluster": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::EKS::Cluster to Name" + } + }, + "AWS::EMR::Cluster": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::EMR::Cluster to Id" + } + }, + "AWS::EMR::InstanceFleetConfig": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::EMR::InstanceFleetConfig to Id" + } + }, + "AWS::EMR::InstanceGroupConfig": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::EMR::InstanceGroupConfig to Id" + } + }, + "AWS::EMR::SecurityConfiguration": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::EMR::SecurityConfiguration to Name" + } + }, + "AWS::EMR::Step": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::EMR::Step to Id" + } + }, + "AWS::ElastiCache::CacheCluster": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::ElastiCache::CacheCluster to Name" + } + }, + "AWS::ElastiCache::ParameterGroup": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::ElastiCache::ParameterGroup to Name" + } + }, + "AWS::ElastiCache::ReplicationGroup": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::ElastiCache::ReplicationGroup to Name" + } + }, + "AWS::ElastiCache::SecurityGroup": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::ElastiCache::SecurityGroup to Name" + } + }, + "AWS::ElastiCache::SecurityGroupIngress": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::ElastiCache::SecurityGroupIngress to Id" + } + }, + "AWS::ElastiCache::SubnetGroup": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::ElastiCache::SubnetGroup to Name" + } + }, + "AWS::ElasticBeanstalk::Application": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::ElasticBeanstalk::Application to Name" + } + }, + "AWS::ElasticBeanstalk::ApplicationVersion": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::ElasticBeanstalk::ApplicationVersion to Name" + } + }, + "AWS::ElasticBeanstalk::ConfigurationTemplate": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::ElasticBeanstalk::ConfigurationTemplate to Name" + } + }, + "AWS::ElasticBeanstalk::Environment": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::ElasticBeanstalk::Environment to Name" + } + }, + "AWS::ElasticLoadBalancing::LoadBalancer": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::ElasticLoadBalancing::LoadBalancer to Name" + } + }, + "AWS::ElasticLoadBalancingV2::Listener": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Arn" + } + ], + "description": "Set RefKind of AWS::ElasticLoadBalancingV2::Listener to Arn" + } + }, + "AWS::ElasticLoadBalancingV2::ListenerCertificate": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Arn" + } + ], + "description": "Set RefKind of AWS::ElasticLoadBalancingV2::ListenerCertificate to Arn" + } + }, + "AWS::ElasticLoadBalancingV2::ListenerRule": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Arn" + } + ], + "description": "Set RefKind of AWS::ElasticLoadBalancingV2::ListenerRule to Arn" + } + }, + "AWS::ElasticLoadBalancingV2::LoadBalancer": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Arn" + } + ], + "description": "Set RefKind of AWS::ElasticLoadBalancingV2::LoadBalancer to Arn" + } + }, + "AWS::ElasticLoadBalancingV2::TargetGroup": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Arn" + } + ], + "description": "Set RefKind of AWS::ElasticLoadBalancingV2::TargetGroup to Arn" + } + }, + "AWS::Elasticsearch::Domain": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::Elasticsearch::Domain to Name" + } + }, + "AWS::Events::Rule": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::Events::Rule to Id" + } + }, + "AWS::GameLift::Alias": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::GameLift::Alias to Id" + } + }, + "AWS::GameLift::Build": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::GameLift::Build to Id" + } + }, + "AWS::GameLift::Fleet": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::GameLift::Fleet to Id" + } + }, + "AWS::Glue::Classifier": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::Glue::Classifier to Name" + } + }, + "AWS::Glue::Connection": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::Glue::Connection to Name" + } + }, + "AWS::Glue::Crawler": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::Glue::Crawler to Name" + } + }, + "AWS::Glue::Database": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::Glue::Database to Name" + } + }, + "AWS::Glue::DevEndpoint": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::Glue::DevEndpoint to Id" + } + }, + "AWS::Glue::Job": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::Glue::Job to Name" + } + }, + "AWS::Glue::Partition": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::Glue::Partition to Id" + } + }, + "AWS::Glue::Table": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::Glue::Table to Name" + } + }, + "AWS::Glue::Trigger": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::Glue::Trigger to Name" + } + }, + "AWS::GuardDuty::Detector": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::GuardDuty::Detector to Id" + } + }, + "AWS::GuardDuty::Filter": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::GuardDuty::Filter to Name" + } + }, + "AWS::GuardDuty::IPSet": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::GuardDuty::IPSet to Id" + } + }, + "AWS::GuardDuty::Master": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "None" + } + ], + "description": "Set RefKind of AWS::GuardDuty::Master to None" + } + }, + "AWS::GuardDuty::Member": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "None" + } + ], + "description": "Set RefKind of AWS::GuardDuty::Member to None" + } + }, + "AWS::GuardDuty::ThreatIntelSet": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::GuardDuty::ThreatIntelSet to Id" + } + }, + "AWS::IAM::AccessKey": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::IAM::AccessKey to Id" + } + }, + "AWS::IAM::Group": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::IAM::Group to Name" + } + }, + "AWS::IAM::InstanceProfile": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::IAM::InstanceProfile to Name" + } + }, + "AWS::IAM::ManagedPolicy": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Arn" + } + ], + "description": "Set RefKind of AWS::IAM::ManagedPolicy to Arn" + } + }, + "AWS::IAM::Policy": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::IAM::Policy to Name" + } + }, + "AWS::IAM::Role": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::IAM::Role to Name" + } + }, + "AWS::IAM::ServiceLinkedRole": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "None" + } + ], + "description": "Set RefKind of AWS::IAM::ServiceLinkedRole to None" + } + }, + "AWS::IAM::User": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::IAM::User to Name" + } + }, + "AWS::IAM::UserToGroupAddition": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "None" + } + ], + "description": "Set RefKind of AWS::IAM::UserToGroupAddition to None" + } + }, + "AWS::Inspector::AssessmentTarget": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "None" + } + ], + "description": "Set RefKind of AWS::Inspector::AssessmentTarget to None" + } + }, + "AWS::Inspector::AssessmentTemplate": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "None" + } + ], + "description": "Set RefKind of AWS::Inspector::AssessmentTemplate to None" + } + }, + "AWS::Inspector::ResourceGroup": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "None" + } + ], + "description": "Set RefKind of AWS::Inspector::ResourceGroup to None" + } + }, + "AWS::IoT::Certificate": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::IoT::Certificate to Id" + } + }, + "AWS::IoT::Policy": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::IoT::Policy to Name" + } + }, + "AWS::IoT::PolicyPrincipalAttachment": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "None" + } + ], + "description": "Set RefKind of AWS::IoT::PolicyPrincipalAttachment to None" + } + }, + "AWS::IoT::Thing": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::IoT::Thing to Name" + } + }, + "AWS::IoT::ThingPrincipalAttachment": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "None" + } + ], + "description": "Set RefKind of AWS::IoT::ThingPrincipalAttachment to None" + } + }, + "AWS::IoT::TopicRule": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::IoT::TopicRule to Name" + } + }, + "AWS::KMS::Alias": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::KMS::Alias to Name" + } + }, + "AWS::KMS::Key": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::KMS::Key to Id" + } + }, + "AWS::Kinesis::Stream": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::Kinesis::Stream to Id" + } + }, + "AWS::KinesisAnalytics::Application": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::KinesisAnalytics::Application to Id" + } + }, + "AWS::KinesisAnalytics::ApplicationOutput": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::KinesisAnalytics::ApplicationOutput to Id" + } + }, + "AWS::KinesisAnalytics::ApplicationReferenceDataSource": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::KinesisAnalytics::ApplicationReferenceDataSource to Id" + } + }, + "AWS::KinesisFirehose::DeliveryStream": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::KinesisFirehose::DeliveryStream to Name" + } + }, + "AWS::Lambda::Alias": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Arn" + } + ], + "description": "Set RefKind of AWS::Lambda::Alias to Arn" + } + }, + "AWS::Lambda::EventSourceMapping": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::Lambda::EventSourceMapping to Name" + } + }, + "AWS::Lambda::Function": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::Lambda::Function to Name" + } + }, + "AWS::Lambda::Permission": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "None" + } + ], + "description": "Set RefKind of AWS::Lambda::Permission to None" + } + }, + "AWS::Lambda::Version": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Arn" + } + ], + "description": "Set RefKind of AWS::Lambda::Version to Arn" + } + }, + "AWS::Logs::Destination": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::Logs::Destination to Name" + } + }, + "AWS::Logs::LogGroup": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::Logs::LogGroup to Name" + } + }, + "AWS::Logs::LogStream": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::Logs::LogStream to Name" + } + }, + "AWS::Logs::MetricFilter": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::Logs::MetricFilter to Name" + } + }, + "AWS::Logs::SubscriptionFilter": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::Logs::SubscriptionFilter to Name" + } + }, + "AWS::Neptune::DBCluster": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::Neptune::DBCluster to Name" + } + }, + "AWS::Neptune::DBClusterParameterGroup": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::Neptune::DBClusterParameterGroup to Name" + } + }, + "AWS::Neptune::DBInstance": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::Neptune::DBInstance to Id" + } + }, + "AWS::Neptune::DBParameterGroup": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::Neptune::DBParameterGroup to Name" + } + }, + "AWS::Neptune::DBSubnetGroup": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::Neptune::DBSubnetGroup to Name" + } + }, + "AWS::OpsWorks::App": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::OpsWorks::App to Id" + } + }, + "AWS::OpsWorks::ElasticLoadBalancerAttachment": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "None" + } + ], + "description": "Set RefKind of AWS::OpsWorks::ElasticLoadBalancerAttachment to None" + } + }, + "AWS::OpsWorks::Instance": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::OpsWorks::Instance to Id" + } + }, + "AWS::OpsWorks::Layer": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::OpsWorks::Layer to Id" + } + }, + "AWS::OpsWorks::Stack": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::OpsWorks::Stack to Id" + } + }, + "AWS::OpsWorks::UserProfile": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Arn" + } + ], + "description": "Set RefKind of AWS::OpsWorks::UserProfile to Arn" + } + }, + "AWS::OpsWorks::Volume": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::OpsWorks::Volume to Id" + } + }, + "AWS::RDS::DBCluster": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::RDS::DBCluster to Name" + } + }, + "AWS::RDS::DBClusterParameterGroup": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::RDS::DBClusterParameterGroup to Name" + } + }, + "AWS::RDS::DBInstance": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::RDS::DBInstance to Id" + } + }, + "AWS::RDS::DBParameterGroup": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::RDS::DBParameterGroup to Name" + } + }, + "AWS::RDS::DBSecurityGroup": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::RDS::DBSecurityGroup to Name" + } + }, + "AWS::RDS::DBSecurityGroupIngress": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::RDS::DBSecurityGroupIngress to Name" + } + }, + "AWS::RDS::DBSubnetGroup": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::RDS::DBSubnetGroup to Name" + } + }, + "AWS::RDS::EventSubscription": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::RDS::EventSubscription to Name" + } + }, + "AWS::RDS::OptionGroup": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::RDS::OptionGroup to Name" + } + }, + "AWS::Redshift::Cluster": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::Redshift::Cluster to Name" + } + }, + "AWS::Redshift::ClusterParameterGroup": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::Redshift::ClusterParameterGroup to Name" + } + }, + "AWS::Redshift::ClusterSecurityGroup": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::Redshift::ClusterSecurityGroup to Name" + } + }, + "AWS::Redshift::ClusterSecurityGroupIngress": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "None" + } + ], + "description": "Set RefKind of AWS::Redshift::ClusterSecurityGroupIngress to None" + } + }, + "AWS::Redshift::ClusterSubnetGroup": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::Redshift::ClusterSubnetGroup to Name" + } + }, + "AWS::Route53::HealthCheck": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::Route53::HealthCheck to Id" + } + }, + "AWS::Route53::HostedZone": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::Route53::HostedZone to Id" + } + }, + "AWS::Route53::RecordSet": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "DomainName" + } + ], + "description": "Set RefKind of AWS::Route53::RecordSet to DomainName" + } + }, + "AWS::Route53::RecordSetGroup": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::Route53::RecordSetGroup to Name" + } + }, + "AWS::S3::Bucket": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::S3::Bucket to Name" + } + }, + "AWS::S3::BucketPolicy": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "None" + } + ], + "description": "Set RefKind of AWS::S3::BucketPolicy to None" + } + }, + "AWS::SDB::Domain": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "None" + } + ], + "description": "Set RefKind of AWS::SDB::Domain to None" + } + }, + "AWS::SES::ConfigurationSet": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::SES::ConfigurationSet to Name" + } + }, + "AWS::SES::ConfigurationSetEventDestination": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "None" + } + ], + "description": "Set RefKind of AWS::SES::ConfigurationSetEventDestination to None" + } + }, + "AWS::SES::ReceiptFilter": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::SES::ReceiptFilter to Name" + } + }, + "AWS::SES::ReceiptRule": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::SES::ReceiptRule to Name" + } + }, + "AWS::SES::ReceiptRuleSet": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::SES::ReceiptRuleSet to Name" + } + }, + "AWS::SES::Template": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::SES::Template to Id" + } + }, + "AWS::SNS::Subscription": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Arn" + } + ], + "description": "Set RefKind of AWS::SNS::Subscription to Arn" + } + }, + "AWS::SNS::Topic": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Arn" + } + ], + "description": "Set RefKind of AWS::SNS::Topic to Arn" + } + }, + "AWS::SNS::TopicPolicy": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "None" + } + ], + "description": "Set RefKind of AWS::SNS::TopicPolicy to None" + } + }, + "AWS::SQS::Queue": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Url" + } + ], + "description": "Set RefKind of AWS::SQS::Queue to Url" + } + }, + "AWS::SQS::QueuePolicy": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "None" + } + ], + "description": "Set RefKind of AWS::SQS::QueuePolicy to None" + } + }, + "AWS::SSM::Association": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "None" + } + ], + "description": "Set RefKind of AWS::SSM::Association to None" + } + }, + "AWS::SSM::Document": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::SSM::Document to Name" + } + }, + "AWS::SSM::MaintenanceWindowTask": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::SSM::MaintenanceWindowTask to Id" + } + }, + "AWS::SSM::Parameter": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::SSM::Parameter to Name" + } + }, + "AWS::SSM::PatchBaseline": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::SSM::PatchBaseline to Id" + } + }, + "AWS::SSM::ResourceDataSync": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::SSM::ResourceDataSync to Name" + } + }, + "AWS::SageMaker::Endpoint": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Arn" + } + ], + "description": "Set RefKind of AWS::SageMaker::Endpoint to Arn" + } + }, + "AWS::SageMaker::EndpointConfig": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Arn" + } + ], + "description": "Set RefKind of AWS::SageMaker::EndpointConfig to Arn" + } + }, + "AWS::SageMaker::Model": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Arn" + } + ], + "description": "Set RefKind of AWS::SageMaker::Model to Arn" + } + }, + "AWS::SageMaker::NotebookInstance": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Arn" + } + ], + "description": "Set RefKind of AWS::SageMaker::NotebookInstance to Arn" + } + }, + "AWS::SageMaker::NotebookInstanceLifecycleConfig": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Arn" + } + ], + "description": "Set RefKind of AWS::SageMaker::NotebookInstanceLifecycleConfig to Arn" + } + }, + "AWS::Serverless::Api": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::Serverless::Api to Name" + } + }, + "AWS::Serverless::Function": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::Serverless::Function to Name" + } + }, + "AWS::Serverless::SimpleTable": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::Serverless::SimpleTable to Name" + } + }, + "AWS::ServiceCatalog::AcceptedPortfolioShare": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::ServiceCatalog::AcceptedPortfolioShare to Id" + } + }, + "AWS::ServiceCatalog::CloudFormationProduct": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::ServiceCatalog::CloudFormationProduct to Id" + } + }, + "AWS::ServiceCatalog::CloudFormationProvisionedProduct": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::ServiceCatalog::CloudFormationProvisionedProduct to Id" + } + }, + "AWS::ServiceCatalog::LaunchNotificationConstraint": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::ServiceCatalog::LaunchNotificationConstraint to Id" + } + }, + "AWS::ServiceCatalog::LaunchRoleConstraint": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::ServiceCatalog::LaunchRoleConstraint to Id" + } + }, + "AWS::ServiceCatalog::LaunchTemplateConstraint": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::ServiceCatalog::LaunchTemplateConstraint to Id" + } + }, + "AWS::ServiceCatalog::Portfolio": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::ServiceCatalog::Portfolio to Id" + } + }, + "AWS::ServiceCatalog::PortfolioPrincipalAssociation": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::ServiceCatalog::PortfolioPrincipalAssociation to Id" + } + }, + "AWS::ServiceCatalog::PortfolioProductAssociation": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::ServiceCatalog::PortfolioProductAssociation to Id" + } + }, + "AWS::ServiceCatalog::PortfolioShare": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::ServiceCatalog::PortfolioShare to Id" + } + }, + "AWS::ServiceCatalog::TagOption": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::ServiceCatalog::TagOption to Id" + } + }, + "AWS::ServiceCatalog::TagOptionAssociation": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::ServiceCatalog::TagOptionAssociation to Id" + } + }, + "AWS::ServiceDiscovery::Instance": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::ServiceDiscovery::Instance to Id" + } + }, + "AWS::ServiceDiscovery::PrivateDnsNamespace": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::ServiceDiscovery::PrivateDnsNamespace to Id" + } + }, + "AWS::ServiceDiscovery::PublicDnsNamespace": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::ServiceDiscovery::PublicDnsNamespace to Id" + } + }, + "AWS::ServiceDiscovery::Service": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::ServiceDiscovery::Service to Id" + } + }, + "AWS::StepFunctions::Activity": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Arn" + } + ], + "description": "Set RefKind of AWS::StepFunctions::Activity to Arn" + } + }, + "AWS::StepFunctions::StateMachine": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Arn" + } + ], + "description": "Set RefKind of AWS::StepFunctions::StateMachine to Arn" + } + }, + "AWS::WAF::ByteMatchSet": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::WAF::ByteMatchSet to Id" + } + }, + "AWS::WAF::IPSet": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::WAF::IPSet to Id" + } + }, + "AWS::WAF::Rule": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::WAF::Rule to Id" + } + }, + "AWS::WAF::SizeConstraintSet": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::WAF::SizeConstraintSet to Id" + } + }, + "AWS::WAF::SqlInjectionMatchSet": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::WAF::SqlInjectionMatchSet to Id" + } + }, + "AWS::WAF::WebACL": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::WAF::WebACL to Id" + } + }, + "AWS::WAF::XssMatchSet": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::WAF::XssMatchSet to Id" + } + }, + "AWS::WAFRegional::ByteMatchSet": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::WAFRegional::ByteMatchSet to Id" + } + }, + "AWS::WAFRegional::IPSet": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::WAFRegional::IPSet to Id" + } + }, + "AWS::WAFRegional::Rule": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::WAFRegional::Rule to Id" + } + }, + "AWS::WAFRegional::SizeConstraintSet": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::WAFRegional::SizeConstraintSet to Id" + } + }, + "AWS::WAFRegional::SqlInjectionMatchSet": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::WAFRegional::SqlInjectionMatchSet to Id" + } + }, + "AWS::WAFRegional::WebACL": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::WAFRegional::WebACL to Id" + } + }, + "AWS::WAFRegional::WebACLAssociation": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::WAFRegional::WebACLAssociation to Id" + } + }, + "AWS::WAFRegional::XssMatchSet": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Id" + } + ], + "description": "Set RefKind of AWS::WAFRegional::XssMatchSet to Id" + } + }, + "AWS::WorkSpaces::Workspace": { + "patch": { + "operations": [ + { + "op": "add", + "path": "/RefKind", + "value": "Name" + } + ], + "description": "Set RefKind of AWS::WorkSpaces::Workspace to Name" + } + } + } +} diff --git a/tools/cfn2ts/lib/codegen.ts b/tools/cfn2ts/lib/codegen.ts index 7db0e23609c85..4e62651eb3b87 100644 --- a/tools/cfn2ts/lib/codegen.ts +++ b/tools/cfn2ts/lib/codegen.ts @@ -65,11 +65,15 @@ export default class CodeGenerator { public emitCode() { for (const name of Object.keys(this.spec.ResourceTypes).sort()) { + const resourceType = this.spec.ResourceTypes[name]; + + this.validateRefKindPresence(name, resourceType); + const cfnName = SpecName.parse(name); const resourceName = genspec.CodeName.forResource(cfnName); this.code.line(); this.code.openBlock('export namespace cloudformation'); - const attributeTypes = this.emitResourceType(resourceName, this.spec.ResourceTypes[name]); + const attributeTypes = this.emitResourceType(resourceName, resourceType); this.emitPropertyTypes(name); @@ -218,17 +222,37 @@ export default class CodeGenerator { // Attributes // - const attributeTypes = new Array(); + const attributeTypes = new Array(); + const attributes = new Array(); if (spec.Attributes) { - this.code.line(); for (const attributeName of Object.keys(spec.Attributes).sort()) { + this.code.line(); + this.docLink(undefined, `@cloudformation_attribute ${attributeName}`); const attr = genspec.attributeDefinition(resourceName, attributeName, undefined); - this.code.line(`public readonly ${attr.propertyName}: ${attr.typeName.className};`); - attributeTypes.push(attr); + this.code.line(`public readonly ${attr.propertyName}: ${attr.attributeType.typeName.className};`); + + attributes.push(attr); + attributeTypes.push(attr.attributeType); + } + } + + // + // Ref attribute + // + if (spec.RefKind !== schema.SpecialRefKind.None) { + const refAttribute = genspec.refAttributeDefinition(resourceName, spec.RefKind!); + this.code.line(`public readonly ${refAttribute.propertyName}: ${refAttribute.attributeType.typeName.className};`); + + // If there's already an attribute with the same declared type, we don't have to duplicate + // the type, but we do have to initialize the attribute variable. + attributes.push(refAttribute); + const alreadyAnAttributeType = attributeTypes.some(t => t.typeName.fqn === refAttribute.attributeType.typeName.fqn); + if (!alreadyAnAttributeType) { + attributeTypes.push(refAttribute.attributeType); } } @@ -269,12 +293,8 @@ export default class CodeGenerator { } // initialize all attribute properties - for (const at of attributeTypes) { - if (!(at.typeName.specName instanceof PropertyAttributeName)) { - throw new Error('SpecName must be a PropertyAttributeName'); - } - - this.code.line(`this.${at.propertyName} = new ${at.typeName.className}(this.getAtt('${at.typeName.specName.propAttrName}'));`); + for (const at of attributes) { + this.code.line(`this.${at.propertyName} = new ${at.attributeType.typeName.className}(${at.constructorArguments});`); } this.code.closeBlock(); @@ -455,8 +475,8 @@ export default class CodeGenerator { /** * Attribute types are classes that represent resource attributes (e.g. QueueArnAttribute). */ - private emitAttributeType(attr: genspec.Attribute) { - this.openClass(attr.typeName, attr.docLink, attr.baseClassName); + private emitAttributeType(attr: genspec.ClassDeclaration) { + this.openClass(attr.typeName, attr.docLink, attr.baseClassName.fqn); this.closeClass(attr.typeName); } @@ -570,6 +590,12 @@ export default class CodeGenerator { this.code.line(' */'); return; } + + private validateRefKindPresence(name: string, resourceType: schema.ResourceType): any { + if (!resourceType.RefKind) { // Both empty string and undefined + throw new Error(`Resource ${name} does not have a RefKind; please annotate this new resources in @aws-cdk/cfnspec`); + } + } } /** diff --git a/tools/cfn2ts/lib/genspec.ts b/tools/cfn2ts/lib/genspec.ts index 2ae8c2ad840ad..b43ebefb07e2d 100644 --- a/tools/cfn2ts/lib/genspec.ts +++ b/tools/cfn2ts/lib/genspec.ts @@ -12,7 +12,9 @@ const RESOURCE_CLASS_POSTFIX = 'Resource'; export const CORE_NAMESPACE = 'cdk'; /** - * The name of corresponding objects in the generated code + * The name of a class or method in the generated code. + * + * Has constructor functions to generate them from the CloudFormation specification. * * This refers to TypeScript constructs (typically a class) */ @@ -99,11 +101,30 @@ export class CodeName { } } +/** + * Class declaration + */ +export class ClassDeclaration { + constructor( + readonly typeName: CodeName, + readonly baseClassName: CodeName, + readonly docLink?: string + ) { + } +} + export const TAG_NAME = new CodeName('', CORE_NAMESPACE, 'Tag'); -export const TOKEN_NAME = new CodeName('', CORE_NAMESPACE, 'Token'); +export const ARN_NAME = new CodeName('', CORE_NAMESPACE, 'Arn'); +export const TOKEN_NAME = new CodeName('', CORE_NAMESPACE, 'CloudFormationToken'); +/** + * Resource attribute + */ export class Attribute { - constructor(readonly propertyName: string, readonly typeName: CodeName, readonly baseClassName: string, readonly docLink?: string) { + constructor( + readonly propertyName: string, + readonly attributeType: ClassDeclaration, + readonly constructorArguments: string) { } } @@ -164,21 +185,31 @@ export function validatorName(typeName: CodeName): CodeName { * - The property name we will use to refer to the attribute. */ export function attributeDefinition(resourceName: CodeName, attributeName: string, docLink?: string): Attribute { - // Original, unmodified CloudFormation name - const specName = new PropertyAttributeName(resourceName.specName!.module, resourceName.specName!.resourceName, attributeName); // "Arn" - const descriptiveName = descriptiveAttributeName(resourceName, attributeName); // "BucketArn" const propertyName = cloudFormationToScriptName(descriptiveName); // "bucketArn" // Not in a namespace, base the name on the descriptive name - const typeName = new CodeName(resourceName.packageName, '', descriptiveName, specName); // "BucketArn" + const typeName = new CodeName(resourceName.packageName, '', descriptiveName); // "BucketArn" + const baseClass = attributeName.endsWith('Arn') ? ARN_NAME : TOKEN_NAME; - let baseClass = `${CORE_NAMESPACE}.Token`; - if (attributeName.endsWith('Arn')) { - baseClass = `${CORE_NAMESPACE}.Arn`; - } + const constructorArguments = `this.getAtt('${attributeName}')`; + + const attrType = new ClassDeclaration(typeName, baseClass, docLink); + return new Attribute(propertyName, attrType, constructorArguments); +} + +/** + * Return an attribute definition name for the RefKind for this class + */ +export function refAttributeDefinition(resourceName: CodeName, refKind: string): Attribute { + const refClassName = descriptiveAttributeName(resourceName, refKind); + const refClass = new CodeName(resourceName.packageName, '', refClassName); + const baseClass = refKind === schema.SpecialRefKind.Arn ? ARN_NAME : TOKEN_NAME; + + const constructorArguments = '{ Ref: this.logicalId }, `${this.logicalId}.Ref`'; - return new Attribute(propertyName, typeName, baseClass, docLink); + const refType = new ClassDeclaration(refClass, baseClass); + return new Attribute('ref', refType, constructorArguments); } /**