• 沒有找到結果。

not recommended. You should be very careful when mutating the construct tree during this phase, because the order of operations could impact behavior.

3. Validation

All constructs that have implemented the validate method can validate themselves to ensure that they're in a state that will correctly deploy. You will get notified of any validation failures that happen during this phase. Generally, we recommend that you perform validation as soon as possible (usually as soon as you get some input) and throw exceptions as early as possible. Performing validation early improves diagnosability as stack traces will be more accurate, and ensures that your code can continue to execute safely.

4. Synthesis

This is the final stage of the execution of your AWS CDK app. It's triggered by a call to app.synth(), and it traverses the construct tree and invokes the synthesize method on all constructs. Constructs that implement synthesize can participate in synthesis and emit deployment artifacts to the resulting cloud assembly. These artifacts include AWS CloudFormation templates, AWS Lambda application bundles, file and Docker image assets, and other deployment artifacts. the section called “Cloud assemblies” (p. 89) describes the output of this phase. In most cases, you won't need to implement the synthesize method

5. Deployment

In this phase, the AWS CDK Toolkit takes the deployment artifacts cloud assembly produced by the synthesis phase and deploys it to an AWS environment. It uploads assets to Amazon S3 and Amazon ECR, or wherever they need to go, and then starts an AWS CloudFormation deployment to deploy the application and create the resources.

By the time the AWS CloudFormation deployment phase (step 5) starts, your AWS CDK app has already finished and exited. This has the following implications:

• The AWS CDK app can't respond to events that happen during deployment, such as a resource being created or the whole deployment finishing. To run code during the deployment phase, you have to inject it into the AWS CloudFormation template as a custom resource (p. 180). For more information about adding a custom resource to your app, see the AWS CloudFormation module, or the custom-resource example.

• The AWS CDK app might have to work with values that can't be known at the time it runs. For example, if the AWS CDK app defines an Amazon S3 bucket with an automatically generated name, and you retrieve the bucket.bucketName (Python: bucket_name) attribute, that value is not the name of the deployed bucket. Instead, you get a Token value. To determine whether a particular value is available, call cdk.isToken(value) (Python: is_token). See the section called

“Tokens” (p. 127) for details.

Cloud assemblies

The call to app.synth() is what tells the AWS CDK to synthesize a cloud assembly from an app.

Typically you don't interact directly with cloud assemblies. They are files that include everything needed to deploy your app to a cloud environment. For example, it includes an AWS CloudFormation template for each stack in your app, and a copy of any file assets or Docker images that you reference in your app.

See the cloud assembly specification for details on how cloud assemblies are formatted.

To interact with the cloud assembly that your AWS CDK app creates, you typically use the AWS CDK Toolkit, a command-line tool. But any tool that can read the cloud assembly format can be used to deploy your app.

The CDK Toolkit needs to know how to execute your AWS CDK app. If you created the project from a template using the cdk init command, your app's cdk.json file includes an app key that specifies the

Stacks

necessary command for the language the app is written in. If your language requires compilation, the command line performs this step before running the app, so you can't forget to do it.

TypeScript

{ "app": "npx ts-node --prefer-ts-exts bin/my-app.ts"

}

JavaScript {

"app": "node bin/my-app.js"

}

Python

{ "app": "python app.py"

} Java

{ "app": "mvn -e -q compile exec:java"

} C#

{ "app": "dotnet run -p src/MyApp/MyApp.csproj"

}

If you did not create your project using the CDK Toolkit, or wish to override the command line given in cdk.json, you can use the --app option when issuing the cdk command.

cdk --app 'executable' cdk-command ...

The executable part of the command indicates the command that should be run to execute your CDK application. Use quotation marks as shown, since such commands contain spaces. The cdk-command is a subcommand like synth or deploy that tells the CDK Toolkit what you want to do with your app. Follow this with any additional options needed for that subcommand.

The CLI can also interact directly with an already-synthesized cloud assembly. To do that, just pass the directory in which the cloud assembly is stored in --app. The following example lists the stacks defined in the cloud assembly stored under ./my-cloud-assembly.

cdk --app ./my-cloud-assembly ls

Stacks

The unit of deployment in the AWS CDK is called a stack. All AWS resources defined within the scope of a stack, either directly or indirectly, are provisioned as a single unit.

Stacks

Because AWS CDK stacks are implemented through AWS CloudFormation stacks, they have the same limitations as in AWS CloudFormation.

You can define any number of stacks in your AWS CDK app. Any instance of the Stack construct represents a stack, and can be either defined directly within the scope of the app, like the MyFirstStack example shown previously, or indirectly by any construct within the tree.

For example, the following code defines an AWS CDK app with two stacks.

TypeScript

const app = new App();

new MyFirstStack(app, 'stack1');

new MySecondStack(app, 'stack2');

app.synth();

JavaScript

const app = new App();

new MyFirstStack(app, 'stack1');

new MySecondStack(app, 'stack2');

app.synth();

Python

app = App()

MyFirstStack(app, 'stack1') MySecondStack(app, 'stack2') app.synth()

Java

App app = new App();

new MyFirstStack(app, "stack1");

new MySecondStack(app, "stack2");

app.synth();

C#

var app = new App();

new MyFirstStack(app, "stack1");

new MySecondStack(app, "stack2");

app.Synth();

To list all the stacks in an AWS CDK app, run the cdk ls command, which for the previous AWS CDK app would have the following output.

stack1

Stacks

stack2

When you run the cdk synth command for an app with multiple stacks, the cloud assembly includes a separate template for each stack instance. Even if the two stacks are instances of the same class, the AWS CDK emits them as two individual templates.

You can synthesize each template by specifying the stack name in the cdk synth command. The following example synthesizes the template for stack1.

cdk synth stack1

This approach is conceptually different from how AWS CloudFormation templates are normally used, where a template can be deployed multiple times and parameterized through AWS CloudFormation parameters. Although AWS CloudFormation parameters can be defined in the AWS CDK, they are generally discouraged because AWS CloudFormation parameters are resolved only during deployment.

This means that you cannot determine their value in your code. For example, to conditionally include a resource in your app based on the value of a parameter, you must set up an AWS CloudFormation condition and tag the resource with this condition. Because the AWS CDK takes an approach where concrete templates are resolved at synthesis time, you can use an if statement to check the value to determine whether a resource should be defined or some behavior should be applied.

NoteThe AWS CDK provides as much resolution as possible during synthesis time to enable idiomatic and natural usage of your programming language.

Like any other construct, stacks can be composed together into groups. The following code shows an example of a service that consists of three stacks: a control plane, a data plane, and monitoring stacks.

The service construct is defined twice: once for the beta environment and once for the production environment.

TypeScript

import { App, Stack } from 'aws-cdk-lib';

import { Construct } from 'constructs';

interface EnvProps { prod: boolean;

}

// imagine these stacks declare a bunch of related resources class ControlPlane extends Stack {}

class DataPlane extends Stack {}

class Monitoring extends Stack {}

class MyService extends Construct {

constructor(scope: Construct, id: string, props?: EnvProps) {

super(scope, id);

// we might use the prod argument to change how the service is configured new ControlPlane(this, "cp");

new DataPlane(this, "data");

new Monitoring(this, "mon"); } }

const app = new App();

new MyService(app, "beta");

new MyService(app, "prod", { prod: true });

Stacks

app.synth();

JavaScript

const { App, Stack } = require('aws-cdk-lib');

const { Construct } = require('constructs');

// imagine these stacks declare a bunch of related resources class ControlPlane extends Stack {}

class DataPlane extends Stack {}

class Monitoring extends Stack {}

class MyService extends Construct { constructor(scope, id, props) { super(scope, id);

// we might use the prod argument to change how the service is configured new ControlPlane(this, "cp");

new DataPlane(this, "data");

new Monitoring(this, "mon");

} }

const app = new App();

new MyService(app, "beta");

new MyService(app, "prod", { prod: true });

app.synth();

Python

from aws_cdk import App, Stack from constructs import Construct

# imagine these stacks declare a bunch of related resources class ControlPlane(Stack): pass

class DataPlane(Stack): pass class Monitoring(Stack): pass class MyService(Construct):

def __init__(self, scope: Construct, id: str, *, prod=False):

super().__init__(scope, id)

# we might use the prod argument to change how the service is configured ControlPlane(self, "cp")

DataPlane(self, "data") Monitoring(self, "mon")

app = App();

MyService(app, "beta")

MyService(app, "prod", prod=True) app.synth()

Java

package com.myorg;

import software.amazon.awscdk.App;

Stacks

import software.amazon.awscdk.Stack;

import software.constructs.Construct;

public class MyApp {

// imagine these stacks declare a bunch of related resources static class ControlPlane extends Stack {

ControlPlane(Construct scope, String id) { super(scope, id);

} }

static class DataPlane extends Stack { DataPlane(Construct scope, String id) { super(scope, id);

} }

static class Monitoring extends Stack { Monitoring(Construct scope, String id) { super(scope, id);

} }

static class MyService extends Construct { MyService(Construct scope, String id) {

public static void main(final String argv[]) { App app = new App();

// imagine these stacks declare a bunch of related resources public class ControlPlane : Stack {

public ControlPlane(Construct scope, string id=null) : base(scope, id) { } }

public class DataPlane : Stack {

public DataPlane(Construct scope, string id=null) : base(scope, id) { } }

public class Monitoring : Stack {

Stacks

public Monitoring(Construct scope, string id=null) : base(scope, id) { } }

public class MyService : Construct

{ public MyService(Construct scope, string id, Boolean prod=false) : base(scope, id) {

// we might use the prod argument to change how the service is configured new ControlPlane(this, "cp");

new DataPlane(this, "data");

new Monitoring(this, "mon");

} }

class Program {

static void Main(string[] args) {

var app = new App();

new MyService(app, "beta");

new MyService(app, "prod", prod: true);

app.Synth();

} }

This AWS CDK app eventually consists of six stacks, three for each environment:

$ cdk ls betacpDA8372D3 betadataE23DB2BA betamon632BD457 prodcp187264CE proddataF7378CE5 prodmon631A1083

The physical names of the AWS CloudFormation stacks are automatically determined by the AWS CDK based on the stack's construct path in the tree. By default, a stack's name is derived from the construct ID of the Stack object, but you can specify an explicit name using the stackName prop (in Python, stack_name), as follows.

TypeScript

new MyStack(this, 'not:a:stack:name', { stackName: 'this-is-stack-name' });

JavaScript

new MyStack(this, 'not:a:stack:name', { stackName: 'this-is-stack-name' });

Python

MyStack(self, "not:a:stack:name", stack_name="this-is-stack-name") Java

new MyStack(this, "not:a:stack:name", StackProps.builder() .StackName("this-is-stack-name").build());

相關文件