Skip to content

Commit

Permalink
feat: deprecate "cloudformation" namespace in favor of "CfnXxx" (#1311)
Browse files Browse the repository at this point in the history
Rename generated CloudFormation resource constructs from `cloudformation.XxxResource` to `CfnXxx`. This fixes #878 and eliminates the use of namespaces in the CDK.

This is done in a backwards compatible way, which means that we still generate the old resources under the `cloudformation` namespace so we can remove them in a subsequent release. Those resources also include a deprecation warning which is emitted upon `cdk synth`.

Documentation updated to reflect changes.

Related: aws/jsii#283 and aws/jsii#270
  • Loading branch information
Elad Ben-Israel authored Dec 13, 2018
1 parent 19fefc6 commit d20938c
Show file tree
Hide file tree
Showing 108 changed files with 459 additions and 876 deletions.
23 changes: 11 additions & 12 deletions docs/src/aws-construct-lib.rst
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,9 @@ the AWS Construct and patch the underlying resources.

AWS constructs, such as :py:class:`Topic <@aws-cdk/aws-sns.Topic>`, encapsulate
one or more AWS CloudFormation resources behind their APIs. These resources are
also represented as constructs under the ``cloudformation`` namespace in each
also represented as ``CfnXxx`` constructs in each
library. For example, the :py:class:`@aws-cdk/aws-s3.Bucket` construct
encapsulates the :py:class:`@aws-cdk/aws-s3.cloudformation.BucketResource`. When
encapsulates the :py:class:`@aws-cdk/aws-s3.CfnBucket`. When
a stack that includes an AWS construct is synthesized, the CloudFormation
definition of the underlying resources are included in the resulting template.

Expand Down Expand Up @@ -167,11 +167,11 @@ given an :py:class:`s3.Bucket <@aws-cdk/s3.Bucket>` construct:
const bucket = new s3.Bucket(this, 'MyBucket');
// we use our knowledge that the main construct is called "Resource" and
// that it's actual type is s3.cloudformation.BucketResource; const
const bucketResource = bucket.findChild('Resource') as s3.cloudformation.BucketResource;
// that it's actual type is s3.CfnBucket; const
const bucketResource = bucket.findChild('Resource') as s3.CfnBucket;
At this point, ``bucketResource`` represents the low-level CloudFormation resource of type
:py:class:`s3.cloudformation.BucketResource <@aws-cdk/aws-s3.cloudformation.BucketResource>`
:py:class:`s3.CfnBucket <@aws-cdk/aws-s3.CfnBucket>`
encapsulated by our bucket.

:py:meth:`construct.findChild(id) <@aws-cdk/cdk.Construct.findChild>` will fail
Expand All @@ -186,7 +186,7 @@ type:
const bucketResource =
bucket.children.find(c => (c as cdk.Resource).resourceType === 'AWS::S3::Bucket')
as s3.cloudformation.BucketResource;
as s3.CfnBucket;
From that point, users are interacting with CloudFormation resource classes
(which extend :py:class:`cdk.Resource <@aws-cdk/cdk.Resource>`), so we will look
Expand All @@ -203,7 +203,7 @@ For example, this code:

.. code-block:: ts
const bucketResource = bucket.findChild('Resource') as s3.cloudformation.BucketResource;
const bucketResource = bucket.findChild('Resource') as s3.CfnBucket;
bucketResource.options.metadata = { MetadataKey: 'MetadataValue' };
bucketResource.options.updatePolicy = {
Expand Down Expand Up @@ -321,7 +321,7 @@ to delete values:
encryption: s3.BucketEncryption.KmsManaged
});
const bucketResource = bucket.findChild('Resource') as s3.cloudformation.BucketResource;
const bucketResource = bucket.findChild('Resource') as s3.CfnBucket;
bucketResource.addPropertyOverride('BucketEncryption.ServerSideEncryptionConfiguration.0.EncryptEverythingAndAlways', true);
bucketResource.addPropertyDeletionOverride('BucketEncryption.ServerSideEncryptionConfiguration.0.ServerSideEncryptionByDefault');
Expand Down Expand Up @@ -349,19 +349,18 @@ Directly Defining CloudFormation Resources
-------------------------------------------

It is also possible to explicitly define CloudFormation resources in your stack.
To that end, instantiate one of the constructs under the ``cloudformation``
namespace of the dedicated library.
To that end, instantiate one of the ``CfnXxx`` constructs of the dedicated library.

.. code-block:: ts
new s3.cloudformation.BucketResource(this, 'MyBucket', {
new s3.CfnBucket(this, 'MyBucket', {
analyticsConfigurations: [
// ...
]
});
In the rare case where you want to define a resource that doesn't have a
corresponding ``cloudformation`` class (such as a new resource that was not yet
corresponding ``CfnXxx`` class (such as a new resource that was not yet
published in the CloudFormation resource specification), you can instantiate the
:py:class:`cdk.Resource <@aws-cdk/cdk.Resource>` object:

Expand Down
36 changes: 18 additions & 18 deletions docs/src/cloudformation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ the :py:class:`@aws-cdk/aws-sns.Topic` construct can be used to define SNS
Topics, etc.

Under the hood, these constructs are implemented using CloudFormation resources,
which are available under the **cloudformation** namespace of each library. For
which are available under the **CfnXxx** classes in each library. For
example, the :py:class:`@aws-cdk/aws-s3.Bucket` construct uses the
:py:class:`@aws-cdk/aws-s3.cloudformation.BucketResource` resource (as well as
:py:class:`@aws-cdk/aws-s3.CfnBucket` resource (as well as
other resources, depending on what bucket APIs are used).

.. important::
Expand All @@ -39,7 +39,7 @@ Resources
CloudFormation resource classes are automatically generated from the `AWS
CloudFormation Resource Specification
<https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-resource-specification.html>`_
and available under the **cloudformation** namespace of each AWS library. Their
and available under the **CfnXxx** classes of each AWS library. Their
API matches 1:1 with how you would use these resources in CloudFormation.

When defining CloudFormation resource, the **props** argument of the class
Expand All @@ -51,11 +51,11 @@ resource encrypted with an AWS managed key you can directly specify the
`KmsMasterKeyId <https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sqs-queues.html#aws-sqs-queue-kmsmasterkeyid>`_
property.

.. code-block:: js
.. code-block:: ts
import { cloudformation } from '@aws-cdk/aws-sqs';
import sqs = require('@aws-cdk/aws-sqs');
new cloudformation.QueueResource(this, 'MyQueueResource', {
new sqs.CfnQueue(this, 'MyQueueResource', {
kmsMasterKeyId: 'alias/aws/sqs'
});
Expand All @@ -82,14 +82,14 @@ use one of the properties available on the resource object.
The following example configures a |LAM| function's dead letter queue to use a
the ARN of an |SQS| queue resource.

.. code-block:: js
.. code-block:: ts
import { cloudformation as sqscfn } from '@aws-cdk/aws-sqs';
import { cloudformation as lambdacfn } from '@aws-cdk/aws-lambda';
import sqs = require('@aws-cdk/aws-sqs');
import lambda = require('@aws-cdk/aws-lambda');
const dlq = new sqscfn.QueueResource(this, { name: 'DLQ' });
const dlq = new sqs.CfnQueue(this, { name: 'DLQ' });
new lambdacfn.FunctionResource(this, {
new lambda.CfnFunction(this, {
deadLetterConfig: {
targetArn: dlq.queueArn
}
Expand Down Expand Up @@ -118,13 +118,13 @@ Parameters

.. NEEDS SOME INTRO TEXT
.. code-block:: js
.. code-block:: ts
import { cloudformation } from '@aws-cdk/aws-sns';
import sns = require('@aws-cdk/aws-sns');
import cdk = require('@aws-cdk/cdk');
const p = new cdk.Parameter(this, 'MyParam', { type: 'String' });
new cloudformation.TopicResource(this, 'MyTopic', { displayName: p.ref });
new sns.CfnTopic(this, 'MyTopic', { displayName: p.ref });
.. _outputs:

Expand All @@ -135,10 +135,10 @@ Outputs
.. code-block:: js
import { cloudformation } from '@aws-cdk/aws-sqs';
import sqs = require('@aws-cdk/aws-sqs');
import cdk = require('@aws-cdk/cdk');
const queue = new cloudformation.QueueResource(this, 'MyQueue');
const queue = new sqs.CfnQueue(this, 'MyQueue');
const out = new cdk.Output(this, 'MyQueueArn', { value: queue.queueArn });
const import = out.makeImportValue();
Expand All @@ -153,13 +153,13 @@ Conditions
.. code-block:: js
import { cloudformation } from '@aws-cdk/aws-sqs';
import sqs = require('@aws-cdk/aws-sqs');
import cdk = require('@aws-cdk/cdk');
const cond = new cdk.Condition(this, 'MyCondition', {
expression: new cdk.FnIf(...)
});
const queue = new cloudformation.QueueResource(this, 'MyQueue');
const queue = new sqs.CfnQueue(this, 'MyQueue');
queue.options.condition = cond;
.. _intrinsic_functions:
Expand Down
14 changes: 7 additions & 7 deletions examples/cdk-examples-typescript/advanced-usage/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { cloudformation } from '@aws-cdk/aws-cloudformation';
import { CfnStack } from '@aws-cdk/aws-cloudformation';
import ec2 = require('@aws-cdk/aws-ec2');
import iam = require('@aws-cdk/aws-iam');
import s3 = require('@aws-cdk/aws-s3');
Expand Down Expand Up @@ -55,7 +55,7 @@ class EnvContextExample extends cdk.Stack {
// render construct name based on it's availablity zone
const constructName = `InstanceFor${az.replace(/-/g, '').toUpperCase()}`;

new ec2.cloudformation.InstanceResource(this, constructName, {
new ec2.CfnInstance(this, constructName, {
imageId: ami.imageId,
availabilityZone: az,
});
Expand Down Expand Up @@ -90,7 +90,7 @@ class IncludeExample extends cdk.Stack {

// add constructs (and resources) programmatically
new EnvContextExample(parent, 'Example');
new sqs.cloudformation.QueueResource(this, 'CDKQueue', {});
new sqs.CfnQueue(this, 'CDKQueue', {});
}
}

Expand All @@ -104,7 +104,7 @@ class NestedStackExample extends cdk.Stack {
// add an "AWS::CloudFormation::Stack" resource which uses the MongoDB quickstart
// https://aws.amazon.com/quickstart/architecture/mongodb/
// only non-default values are provided here.
new cloudformation.StackResource(this, 'NestedStack', {
new CfnStack(this, 'NestedStack', {
templateUrl: 'https://s3.amazonaws.com/quickstart-reference/mongodb/latest/templates/mongodb-master.template',
parameters: {
KeyPairName: 'my-key-pair',
Expand All @@ -125,10 +125,10 @@ class ResourceReferencesExample extends cdk.Stack {
constructor(parent: cdk.App, name: string, props?: cdk.StackProps) {
super(parent, name, props);

const topic = new sns.cloudformation.TopicResource(this, 'Topic', {});
const queue = new sqs.cloudformation.QueueResource(this, 'Queue', {});
const topic = new sns.CfnTopic(this, 'Topic', {});
const queue = new sqs.CfnQueue(this, 'Queue', {});

new sns.cloudformation.SubscriptionResource(this, 'Subscription', {
new sns.CfnSubscription(this, 'Subscription', {
topicArn: topic.ref, // resolves to { Ref: <topic-id> }
protocol: 'sqs',
endpoint: queue.queueArn // resolves to { "Fn::GetAtt": [ <queue-id>, "Arn" ] }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export class CognitoChatRoomPool extends cdk.Construct {
super(parent, name);

// Create chat room user pool
const chatPool = new cognito.cloudformation.UserPoolResource(this, 'UserPool', {
const chatPool = new cognito.CfnUserPool(this, 'UserPool', {
adminCreateUserConfig: {
allowAdminCreateUserOnly: false
},
Expand All @@ -26,7 +26,7 @@ export class CognitoChatRoomPool extends cdk.Construct {
});

// Now for the client
new cognito.cloudformation.UserPoolClientResource(this, 'UserPoolClient', {
new cognito.CfnUserPoolClient(this, 'UserPoolClient', {
clientName: 'Chat-Room',
explicitAuthFlows: [ 'ADMIN_NO_SRP_AUTH' ],
refreshTokenValidity: 30,
Expand Down
2 changes: 1 addition & 1 deletion examples/cdk-examples-typescript/cloudformation/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ class CloudFormationExample extends cdk.Stack {
constructor(parent: cdk.App) {
super(parent);

new sqs.cloudformation.QueueResource(this, 'MyQueue', {
new sqs.CfnQueue(this, 'MyQueue', {
visibilityTimeout: 300
});
}
Expand Down
4 changes: 2 additions & 2 deletions examples/cdk-examples-typescript/custom-resource/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { CustomResource } from '@aws-cdk/aws-cloudformation';
import lambda = require('@aws-cdk/aws-lambda');
import { cloudformation as s3 } from '@aws-cdk/aws-s3';
import { CfnBucket } from '@aws-cdk/aws-s3';
import cdk = require('@aws-cdk/cdk');
import fs = require('fs');

Expand Down Expand Up @@ -86,7 +86,7 @@ class FailAfterCreatingStack extends cdk.Stack {
});

// Bucket with an invalid name will fail the deployment and cause a rollback
const bucket = new s3.BucketResource(this, 'FailingBucket', {
const bucket = new CfnBucket(this, 'FailingBucket', {
bucketName: 'hello!@#$^'
});

Expand Down
8 changes: 4 additions & 4 deletions examples/cdk-examples-typescript/resource-overrides/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class ResourceOverridesExample extends cdk.Stack {
encryption: s3.BucketEncryption.KmsManaged
});

const bucketResource2 = bucket.findChild('Resource') as s3.cloudformation.BucketResource;
const bucketResource2 = bucket.findChild('Resource') as s3.CfnBucket;
bucketResource2.addPropertyOverride('BucketEncryption.ServerSideEncryptionConfiguration.0.EncryptEverythingAndAlways', true);
bucketResource2.addPropertyDeletionOverride('BucketEncryption.ServerSideEncryptionConfiguration.0.ServerSideEncryptionByDefault');

Expand All @@ -25,8 +25,8 @@ class ResourceOverridesExample extends cdk.Stack {
// Accessing the L1 bucket resource from an L2 bucket
//

const bucketResource = bucket.findChild('Resource') as s3.cloudformation.BucketResource;
const anotherWay = bucket.children.find(c => (c as cdk.Resource).resourceType === 'AWS::S3::Bucket') as s3.cloudformation.BucketResource;
const bucketResource = bucket.findChild('Resource') as s3.CfnBucket;
const anotherWay = bucket.children.find(c => (c as cdk.Resource).resourceType === 'AWS::S3::Bucket') as s3.CfnBucket;
assert.equal(bucketResource, anotherWay);

//
Expand Down Expand Up @@ -108,7 +108,7 @@ class ResourceOverridesExample extends cdk.Stack {
// need to consule the codebase or use the `.map.find` method above
//

const lc = asg.findChild('LaunchConfig') as autoscaling.cloudformation.LaunchConfigurationResource;
const lc = asg.findChild('LaunchConfig') as autoscaling.CfnLaunchConfiguration;
lc.addPropertyOverride('Foo.Bar', 'Hello');
}
}
Expand Down
8 changes: 4 additions & 4 deletions examples/cdk-examples-typescript/sns-sqs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ class CFN extends cdk.Stack {
constructor(parent: cdk.App, name: string) {
super(parent, name);

const topic = new sns.cloudformation.TopicResource(this, 'MyTopic');
const queue = new sqs.cloudformation.QueueResource(this, 'MyQueue');
const topic = new sns.CfnTopic(this, 'MyTopic');
const queue = new sqs.CfnQueue(this, 'MyQueue');

new sns.cloudformation.SubscriptionResource(this, 'TopicToQueue', {
new sns.CfnSubscription(this, 'TopicToQueue', {
topicArn: topic.ref, // ref == arn for topics
endpoint: queue.queueName,
protocol: 'sqs'
Expand All @@ -36,7 +36,7 @@ class CFN extends cdk.Stack {
.addServicePrincipal('sns.amazonaws.com')
.setCondition('ArnEquals', { 'aws:SourceArn': topic.ref }));

new sqs.cloudformation.QueuePolicyResource(this, 'MyQueuePolicy', {
new sqs.CfnQueuePolicy(this, 'MyQueuePolicy', {
policyDocument,
queues: [ queue.ref ]
});
Expand Down
6 changes: 3 additions & 3 deletions packages/@aws-cdk/aws-apigateway/lib/deployment.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import cdk = require('@aws-cdk/cdk');
import crypto = require('crypto');
import { cloudformation } from './apigateway.generated';
import { CfnDeployment, CfnDeploymentProps } from './apigateway.generated';
import { RestApiRef } from './restapi-ref';

export interface DeploymentProps {
Expand Down Expand Up @@ -103,13 +103,13 @@ export class Deployment extends cdk.Construct implements cdk.IDependable {
}
}

class LatestDeploymentResource extends cloudformation.DeploymentResource {
class LatestDeploymentResource extends CfnDeployment {
private originalLogicalId?: string;
private lazyLogicalIdRequired: boolean;
private lazyLogicalId?: string;
private hashComponents = new Array<any>();

constructor(parent: cdk.Construct, id: string, props: cloudformation.DeploymentResourceProps) {
constructor(parent: cdk.Construct, id: string, props: CfnDeploymentProps) {
super(parent, id, props);

// from this point, don't allow accessing logical ID before synthesis
Expand Down
8 changes: 4 additions & 4 deletions packages/@aws-cdk/aws-apigateway/lib/method.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import cdk = require('@aws-cdk/cdk');
import { cloudformation } from './apigateway.generated';
import { CfnMethod, CfnMethodProps } from './apigateway.generated';
import { Integration } from './integration';
import { MockIntegration } from './integrations/mock';
import { IRestApiResource } from './resource';
Expand Down Expand Up @@ -83,7 +83,7 @@ export class Method extends cdk.Construct {

const defaultMethodOptions = props.resource.defaultMethodOptions || {};

const methodProps: cloudformation.MethodResourceProps = {
const methodProps: CfnMethodProps = {
resourceId: props.resource.resourceId,
restApiId: this.restApi.restApiId,
httpMethod: props.httpMethod,
Expand All @@ -94,7 +94,7 @@ export class Method extends cdk.Construct {
integration: this.renderIntegration(props.integration)
};

const resource = new cloudformation.MethodResource(this, 'Resource', methodProps);
const resource = new CfnMethod(this, 'Resource', methodProps);

this.methodId = resource.ref;

Expand Down Expand Up @@ -134,7 +134,7 @@ export class Method extends cdk.Construct {
return this.restApi.executeApiArn(this.httpMethod, this.resource.resourcePath, 'test-invoke-stage');
}

private renderIntegration(integration?: Integration): cloudformation.MethodResource.IntegrationProperty {
private renderIntegration(integration?: Integration): CfnMethod.IntegrationProperty {
if (!integration) {
// use defaultIntegration from API if defined
if (this.resource.defaultIntegration) {
Expand Down
Loading

0 comments on commit d20938c

Please sign in to comment.