Skip to content

Commit

Permalink
feat(cdk): Tokens can be converted to strings (#518)
Browse files Browse the repository at this point in the history
Tokens (such as resource attributes) can now be implicitly converted
into strings. This allows using any late-bound CloudFormation value
where strings can be used in the host language, and the native string
facilities of the host language can be used as well to further process
strings.

The process is reversed by the resolve() function during synthesis,
which will split the string up again into string literals and
CloudFormation intrinsics (combined by `{Fn::Join}`).

Introduces `CloudFormationJSON.stringify` to produce a similar result,
but used for JSON-encoding of complex objects that may contain Tokens.
This is used in JSON-encoded policy statements, CloudFormation actions,
state machine definitions, and more.

Additional changes:
- Add a VSCode launch config (with a helper script) to directly debug a
  unit test from within the IDE. This allows setting breakpoints.
- SecretParameter no longer duckily implements Token; this will not work
  in other jsii languages anyway.
- Nested `FnConcat` structures will be flattened in the CloudFormation
  output.

Fixes #24 and #168.
  • Loading branch information
rix0rrr authored Aug 15, 2018
1 parent f0e7bb5 commit 939015a
Show file tree
Hide file tree
Showing 33 changed files with 1,005 additions and 464 deletions.
4 changes: 2 additions & 2 deletions packages/@aws-cdk/aws-cloudwatch/lib/dashboard.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Construct, Stack, Token, tokenAwareJsonify } from "@aws-cdk/cdk";
import { CloudFormationJSON, Construct, Stack, Token } from "@aws-cdk/cdk";
import { cloudformation } from './cloudwatch.generated';
import { Column, Row } from "./layout";
import { IWidget } from "./widget";
Expand Down Expand Up @@ -33,7 +33,7 @@ export class Dashboard extends Construct {
dashboardBody: new Token(() => {
const column = new Column(...this.rows);
column.position(0, 0);
return tokenAwareJsonify({ widgets: column.toJson() });
return CloudFormationJSON.stringify({ widgets: column.toJson() });
})
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
"Type": "AWS::CloudWatch::Alarm",
"Properties": {
"ComparisonOperator": "GreaterThanOrEqualToThreshold",
"EvaluationPeriods": 3,
"MetricName": "ApproximateNumberOfMessagesVisible",
"Namespace": "AWS/SQS",
"Period": 300,
"Threshold": 100,
"Dimensions": [
{
"Name": "QueueName",
Expand All @@ -18,41 +23,55 @@
}
}
],
"EvaluationPeriods": 3,
"MetricName": "ApproximateNumberOfMessagesVisible",
"Namespace": "AWS/SQS",
"Period": 300,
"Statistic": "Average",
"Threshold": 100
"Statistic": "Average"
}
},
"DashCCD7F836": {
"Type": "AWS::CloudWatch::Dashboard",
"Properties": {
"DashboardName": "aws-cdk-cloudwatch-DashCCD7F836",
"DashboardBody": {
"Fn::Sub": [
"{\"widgets\":[{\"type\":\"text\",\"width\":6,\"height\":2,\"x\":0,\"y\":0,\"properties\":{\"markdown\":\"# This is my dashboard\"}},{\"type\":\"text\",\"width\":6,\"height\":2,\"x\":6,\"y\":0,\"properties\":{\"markdown\":\"you like?\"}},{\"type\":\"metric\",\"width\":6,\"height\":6,\"x\":0,\"y\":2,\"properties\":{\"view\":\"timeSeries\",\"title\":\"Messages in queue\",\"region\":\"${ref0}\",\"annotations\":{\"alarms\":[\"${ref1}\"]},\"yAxis\":{\"left\":{\"min\":0}}}},{\"type\":\"metric\",\"width\":6,\"height\":6,\"x\":0,\"y\":8,\"properties\":{\"view\":\"timeSeries\",\"title\":\"More messages in queue with alarm annotation\",\"region\":\"${ref0}\",\"metrics\":[[\"AWS/SQS\",\"ApproximateNumberOfMessagesVisible\",\"QueueName\",\"${ref2}\",{\"yAxis\":\"left\",\"period\":300,\"stat\":\"Average\"}]],\"annotations\":{\"horizontal\":[{\"label\":\"ApproximateNumberOfMessagesVisible >= 100 for 3 datapoints within 15 minutes\",\"value\":100,\"yAxis\":\"left\"}]},\"yAxis\":{\"left\":{\"min\":0},\"right\":{\"min\":0}}}},{\"type\":\"metric\",\"width\":6,\"height\":3,\"x\":0,\"y\":14,\"properties\":{\"view\":\"singleValue\",\"title\":\"Current messages in queue\",\"region\":\"${ref0}\",\"metrics\":[[\"AWS/SQS\",\"ApproximateNumberOfMessagesVisible\",\"QueueName\",\"${ref2}\",{\"yAxis\":\"left\",\"period\":300,\"stat\":\"Average\"}]]}}]}",
{
"ref0": {
"Fn::Join": [
"",
[
"{\"widgets\":[{\"type\":\"text\",\"width\":6,\"height\":2,\"x\":0,\"y\":0,\"properties\":{\"markdown\":\"# This is my dashboard\"}},{\"type\":\"text\",\"width\":6,\"height\":2,\"x\":6,\"y\":0,\"properties\":{\"markdown\":\"you like?\"}},{\"type\":\"metric\",\"width\":6,\"height\":6,\"x\":0,\"y\":2,\"properties\":{\"view\":\"timeSeries\",\"title\":\"Messages in queue\",\"region\":\"",
{
"Ref": "AWS::Region"
},
"ref1": {
"\",\"annotations\":{\"alarms\":[\"",
{
"Fn::GetAtt": [
"Alarm7103F465",
"Arn"
]
},
"ref2": {
"\"]},\"yAxis\":{\"left\":{\"min\":0}}}},{\"type\":\"metric\",\"width\":6,\"height\":6,\"x\":0,\"y\":8,\"properties\":{\"view\":\"timeSeries\",\"title\":\"More messages in queue with alarm annotation\",\"region\":\"",
{
"Ref": "AWS::Region"
},
"\",\"metrics\":[[\"AWS/SQS\",\"ApproximateNumberOfMessagesVisible\",\"QueueName\",\"",
{
"Fn::GetAtt": [
"queue",
"QueueName"
]
}
}
},
"\",{\"yAxis\":\"left\",\"period\":300,\"stat\":\"Average\"}]],\"annotations\":{\"horizontal\":[{\"label\":\"ApproximateNumberOfMessagesVisible >= 100 for 3 datapoints within 15 minutes\",\"value\":100,\"yAxis\":\"left\"}]},\"yAxis\":{\"left\":{\"min\":0},\"right\":{\"min\":0}}}},{\"type\":\"metric\",\"width\":6,\"height\":3,\"x\":0,\"y\":14,\"properties\":{\"view\":\"singleValue\",\"title\":\"Current messages in queue\",\"region\":\"",
{
"Ref": "AWS::Region"
},
"\",\"metrics\":[[\"AWS/SQS\",\"ApproximateNumberOfMessagesVisible\",\"QueueName\",\"",
{
"Fn::GetAtt": [
"queue",
"QueueName"
]
},
"\",{\"yAxis\":\"left\",\"period\":300,\"stat\":\"Average\"}]]}}]}"
]
]
}
},
"DashboardName": "aws-cdk-cloudwatch-DashCCD7F836"
}
}
}
}
}
15 changes: 6 additions & 9 deletions packages/@aws-cdk/aws-cloudwatch/test/test.dashboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export = {
test.done();
},

'tokens in widgets are retained through FnSub'(test: Test) {
'tokens in widgets are retained'(test: Test) {
// GIVEN
const stack = new Stack();
const dashboard = new Dashboard(stack, 'Dash');
Expand All @@ -82,14 +82,11 @@ export = {

// THEN
expect(stack).to(haveResource('AWS::CloudWatch::Dashboard', {
DashboardBody: { "Fn::Sub": [
// tslint:disable-next-line:max-line-length
"{\"widgets\":[{\"type\":\"metric\",\"width\":1,\"height\":1,\"x\":0,\"y\":0,\"properties\":{\"view\":\"timeSeries\",\"region\":\"${ref0}\",\"metrics\":[],\"annotations\":{\"horizontal\":[]},\"yAxis\":{\"left\":{\"min\":0},\"right\":{\"min\":0}}}}]}",
{
ref0: { Ref: "AWS::Region" }
}
]
}
DashboardBody: { "Fn::Join": [ "", [
"{\"widgets\":[{\"type\":\"metric\",\"width\":1,\"height\":1,\"x\":0,\"y\":0,\"properties\":{\"view\":\"timeSeries\",\"region\":\"",
{ Ref: "AWS::Region" },
"\",\"metrics\":[],\"annotations\":{\"horizontal\":[]},\"yAxis\":{\"left\":{\"min\":0},\"right\":{\"min\":0}}}}]}"
]]}
}));

test.done();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,16 +86,9 @@
":",
"log-group",
":",
"/aws/codebuild/",
{
"Fn::Join": [
"",
[
"/aws/codebuild/",
{
"Ref": "MyProject39F7B0AE"
}
]
]
"Ref": "MyProject39F7B0AE"
}
]
]
Expand Down Expand Up @@ -126,16 +119,9 @@
":",
"log-group",
":",
"/aws/codebuild/",
{
"Fn::Join": [
"",
[
"/aws/codebuild/",
{
"Ref": "MyProject39F7B0AE"
}
]
]
"Ref": "MyProject39F7B0AE"
}
]
]
Expand All @@ -160,8 +146,22 @@
"MyProject39F7B0AE": {
"Type": "AWS::CodeBuild::Project",
"Properties": {
"Artifacts": {
"Type": "NO_ARTIFACTS"
},
"Environment": {
"ComputeType": "BUILD_GENERAL1_LARGE",
"Image": "aws/codebuild/ubuntu-base:14.04",
"PrivilegedMode": false,
"Type": "LINUX_CONTAINER"
},
"ServiceRole": {
"Fn::GetAtt": [
"MyProjectRole9BBE5233",
"Arn"
]
},
"Source": {
"Type": "S3",
"Location": {
"Fn::Join": [
"",
Expand All @@ -173,22 +173,8 @@
"path/to/my/source.zip"
]
]
}
},
"Artifacts": {
"Type": "NO_ARTIFACTS"
},
"ServiceRole": {
"Fn::GetAtt": [
"MyProjectRole9BBE5233",
"Arn"
]
},
"Environment": {
"Type": "LINUX_CONTAINER",
"PrivilegedMode": false,
"Image": "aws/codebuild/ubuntu-base:14.04",
"ComputeType": "BUILD_GENERAL1_LARGE"
},
"Type": "S3"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,16 +129,9 @@
":",
"log-group",
":",
"/aws/codebuild/",
{
"Fn::Join": [
"",
[
"/aws/codebuild/",
{
"Ref": "MyProject39F7B0AE"
}
]
]
"Ref": "MyProject39F7B0AE"
}
]
]
Expand Down Expand Up @@ -169,16 +162,9 @@
":",
"log-group",
":",
"/aws/codebuild/",
{
"Fn::Join": [
"",
[
"/aws/codebuild/",
{
"Ref": "MyProject39F7B0AE"
}
]
]
"Ref": "MyProject39F7B0AE"
}
]
]
Expand All @@ -203,29 +189,29 @@
"MyProject39F7B0AE": {
"Type": "AWS::CodeBuild::Project",
"Properties": {
"Source": {
"Type": "CODECOMMIT",
"Location": {
"Fn::GetAtt": [
"MyRepoF4F48043",
"CloneUrlHttp"
]
}
},
"Artifacts": {
"Type": "NO_ARTIFACTS"
},
"Environment": {
"ComputeType": "BUILD_GENERAL1_SMALL",
"Image": "aws/codebuild/ubuntu-base:14.04",
"PrivilegedMode": false,
"Type": "LINUX_CONTAINER"
},
"ServiceRole": {
"Fn::GetAtt": [
"MyProjectRole9BBE5233",
"Arn"
]
},
"Environment": {
"Type": "LINUX_CONTAINER",
"PrivilegedMode": false,
"Image": "aws/codebuild/ubuntu-base:14.04",
"ComputeType": "BUILD_GENERAL1_SMALL"
"Source": {
"Location": {
"Fn::GetAtt": [
"MyRepoF4F48043",
"CloneUrlHttp"
]
},
"Type": "CODECOMMIT"
}
}
},
Expand Down
Loading

0 comments on commit 939015a

Please sign in to comment.