AWS Security ChangesHomeSearch

AWS cdk documentation change

Service: cdk · 2025-05-10 · Documentation low

File: cdk/v2/guide/best-practices.md

Summary

Updated punctuation (straight quotes to curly quotes), adjusted markdown headings, and minor wording changes for consistency

Security assessment

Changes primarily involve grammatical corrections, typo fixes, and formatting adjustments (e.g., quote styles). No explicit security vulnerabilities, mitigations, or new security features are introduced in these changes.

Diff

diff --git a/cdk/v2/guide/best-practices.md b/cdk/v2/guide/best-practices.md
index e458a4b08..3b9893e52 100644
--- a//cdk/v2/guide/best-practices.md
+++ b//cdk/v2/guide/best-practices.md
@@ -24 +24 @@ Stacks define the deployment model of these logical units. For a more detailed i
-The AWS CDK reflects careful consideration of the needs of our customers and internal teams and of the failure patterns that often arise during the deployment and ongoing maintenance of complex cloud applications. We discovered that failures are often related to "out-of-band" changes to an application that aren't fully tested, such as configuration changes. Therefore, we developed the AWS CDK around a model in which your entire application is defined in code, not only business logic but also infrastructure and configuration. That way, proposed changes can be carefully reviewed, comprehensively tested in environments resembling production to varying degrees, and fully rolled back if something goes wrong.
+The AWS CDK reflects careful consideration of the needs of our customers and internal teams and of the failure patterns that often arise during the deployment and ongoing maintenance of complex cloud applications. We discovered that failures are often related to "out-of-band" changes to an application that aren’t fully tested, such as configuration changes. Therefore, we developed the AWS CDK around a model in which your entire application is defined in code, not only business logic but also infrastructure and configuration. That way, proposed changes can be carefully reviewed, comprehensively tested in environments resembling production to varying degrees, and fully rolled back if something goes wrong.
@@ -37 +37 @@ At deployment time, the AWS CDK synthesizes a cloud assembly that contains the f
-With the CDK, every commit in your application's main version control branch can represent a complete, consistent, deployable version of your application. Your application can then be deployed automatically whenever a change is made.
+With the CDK, every commit in your application’s main version control branch can represent a complete, consistent, deployable version of your application. Your application can then be deployed automatically whenever a change is made.
@@ -58 +58 @@ Also consider [best practices for AWS CloudFormation](https://docs.aws.amazon.co
-In the beginning stages of AWS CDK adoption, it's important to consider how to set up your organization for success. It's a best practice to have a team of experts responsible for training and guiding the rest of the company as they adopt the CDK. The size of this team might vary, from one or two people at a small company to a full-fledged Cloud Center of Excellence (CCoE) at a larger company. This team is responsible for setting standards and policies for cloud infrastructure at your company, and also for training and mentoring developers.
+In the beginning stages of AWS CDK adoption, it’s important to consider how to set up your organization for success. It’s a best practice to have a team of experts responsible for training and guiding the rest of the company as they adopt the CDK. The size of this team might vary, from one or two people at a small company to a full-fledged Cloud Center of Excellence (CCoE) at a larger company. This team is responsible for setting standards and policies for cloud infrastructure at your company, and also for training and mentoring developers.
@@ -60 +60 @@ In the beginning stages of AWS CDK adoption, it's important to consider how to s
-The CCoE might provide guidance on what programming languages should be used for cloud infrastructure. Details will vary from one organization to the next, but a good policy helps make sure that developers can understand and maintain the company's cloud infrastructure.
+The CCoE might provide guidance on what programming languages should be used for cloud infrastructure. Details will vary from one organization to the next, but a good policy helps make sure that developers can understand and maintain the company’s cloud infrastructure.
@@ -64 +64 @@ The CCoE also creates a "landing zone" that defines your organizational units wi
-Development teams should be able to use their own accounts for testing and deploy new resources in these accounts as needed. Individual developers can treat these resources as extensions of their own development workstation. Using [CDK Pipelines](./cdk-pipeline.html), the AWS CDK applications can then be deployed via a CI/CD account to testing, integration, and production environments (each isolated in its own AWS Region or account). This is done by merging the developers' code into your organization's canonical repository.
+Development teams should be able to use their own accounts for testing and deploy new resources in these accounts as needed. Individual developers can treat these resources as extensions of their own development workstation. Using [CDK Pipelines](./cdk-pipeline.html), the AWS CDK applications can then be deployed via a CI/CD account to testing, integration, and production environments (each isolated in its own AWS Region or account). This is done by merging the developers' code into your organization’s canonical repository.
@@ -70 +70 @@ Development teams should be able to use their own accounts for testing and deplo
-This section presents best practices for organizing your AWS CDK code. The following diagram shows the relationship between a team and that team's code repositories, packages, applications, and construct libraries. 
+This section presents best practices for organizing your AWS CDK code. The following diagram shows the relationship between a team and that team’s code repositories, packages, applications, and construct libraries.
@@ -72 +72 @@ This section presents best practices for organizing your AWS CDK code. The follo
-![Diagram showing team's code organization: repository, package, CDK app or construct library.](/images/cdk/v2/guide/images/code-organization.jpg)
+![Diagram showing team’s code organization: repository, package, CDK app or construct library.](/images/cdk/v2/guide/images/code-organization.jpg)
@@ -74 +74 @@ This section presents best practices for organizing your AWS CDK code. The follo
-### Start simple and add complexity only when you need it
+**Start simple and add complexity only when you need it**
@@ -76 +75,0 @@ This section presents best practices for organizing your AWS CDK code. The follo
-The guiding principle for most of our best practices is to keep things simple as possible—but no simpler. Add complexity only when your requirements dictate a more complicated solution. With the AWS CDK, you can refactor your code as necessary to support new requirements. You don't have to architect for all possible scenarios upfront.
@@ -78 +77,4 @@ The guiding principle for most of our best practices is to keep things simple as
-### Align with the AWS Well-Architected Framework
+The guiding principle for most of our best practices is to keep things simple as possible—​but no simpler. Add complexity only when your requirements dictate a more complicated solution. With the AWS CDK, you can refactor your code as necessary to support new requirements. You don’t have to architect for all possible scenarios upfront.
+
+**Align with the AWS Well-Architected Framework**
+    
@@ -84 +86,2 @@ An AWS CDK application maps to a component as defined by the AWS Well-Architecte
-### Every application starts with a single package in a single repository
+**Every application starts with a single package in a single repository**
+    
@@ -86 +89 @@ An AWS CDK application maps to a component as defined by the AWS Well-Architecte
-A single package is the entry point of your AWS CDK app. Here, you define how and where to deploy the different logical units of your application. You also define the CI/CD pipeline to deploy the application. The app's constructs define the logical units of your solution.
+A single package is the entry point of your AWS CDK app. Here, you define how and where to deploy the different logical units of your application. You also define the CI/CD pipeline to deploy the application. The app’s constructs define the logical units of your solution.
@@ -88 +91 @@ A single package is the entry point of your AWS CDK app. Here, you define how an
-Use additional packages for constructs that you use in more than one application. (Shared constructs should also have their own lifecycle and testing strategy.) Dependencies between packages in the same repository are managed by your repo's build tooling. 
+Use additional packages for constructs that you use in more than one application. (Shared constructs should also have their own lifecycle and testing strategy.) Dependencies between packages in the same repository are managed by your repo’s build tooling.
@@ -90 +93,3 @@ Use additional packages for constructs that you use in more than one application
-Although it's possible, we don't recommend putting multiple applications in the same repository, especially when using automated deployment pipelines. Doing this increases the "blast radius" of changes during deployment. When there are multiple applications in a repository, changes to one application trigger deployment of the others (even if the others haven't changed). Furthermore, a break in one application prevents the other applications from being deployed.
+Although it’s possible, we don’t recommend putting multiple applications in the same repository, especially when using automated deployment pipelines. Doing this increases the "blast radius" of changes during deployment. When there are multiple applications in a repository, changes to one application trigger deployment of the others (even if the others haven’t changed). Furthermore, a break in one application prevents the other applications from being deployed.
+
+**Move code into repositories based on code lifecycle or team ownership**
@@ -92 +96,0 @@ Although it's possible, we don't recommend putting multiple applications in the
-### Move code into repositories based on code lifecycle or team ownership
@@ -98 +102 @@ Also, move packages to their own repository when different teams are working on
-To consume packages across repository boundaries, you need a private package repository—similar to NPM, PyPi, or Maven Central, but internal to your organization. You also need a release process that builds, tests, and publishes the package to the private package repository. [CodeArtifact](https://docs.aws.amazon.com/codeartifact/latest/ug/) can host packages for most popular programming languages.
+To consume packages across repository boundaries, you need a private package repository—​similar to NPM, PyPi, or Maven Central, but internal to your organization. You also need a release process that builds, tests, and publishes the package to the private package repository. [CodeArtifact](https://docs.aws.amazon.com/codeartifact/latest/ug/) can host packages for most popular programming languages.
@@ -100 +104 @@ To consume packages across repository boundaries, you need a private package rep
-Dependencies on packages in the package repository are managed by your language's package manager, such as NPM for TypeScript or JavaScript applications. Your package manager helps to make sure that builds are repeatable. It does this by recording the specific versions of every package that your application depends on. It also lets you upgrade those dependencies in a controlled manner.
+Dependencies on packages in the package repository are managed by your language’s package manager, such as NPM for TypeScript or JavaScript applications. Your package manager helps to make sure that builds are repeatable. It does this by recording the specific versions of every package that your application depends on. It also lets you upgrade those dependencies in a controlled manner.
@@ -106 +110,2 @@ Keep in mind that a construct can be arbitrarily simple or complex. A `Bucket` i
-### Infrastructure and runtime code live in the same package
+**Infrastructure and runtime code live in the same package**
+    
@@ -108 +113 @@ Keep in mind that a construct can be arbitrarily simple or complex. A `Bucket` i
-In addition to generating AWS CloudFormation templates for deploying infrastructure, the AWS CDK also bundles runtime assets like Lambda functions and Docker images and deploys them alongside your infrastructure. This makes it possible to combine the code that defines your infrastructure and the code that implements your runtime logic into a single construct. It's a best practice to do this. These two kinds of code don't need to live in separate repositories or even in separate packages.
+In addition to generating AWS CloudFormation templates for deploying infrastructure, the AWS CDK also bundles runtime assets like Lambda functions and Docker images and deploys them alongside your infrastructure. This makes it possible to combine the code that defines your infrastructure and the code that implements your runtime logic into a single construct. It’s a best practice to do this. These two kinds of code don’t need to live in separate repositories or even in separate packages.
@@ -114 +119 @@ To evolve the two kinds of code together, you can use a self-contained construct
-This section contains best practices for developing constructs. Constructs are reusable, composable modules that encapsulate resources. They're the building blocks of AWS CDK apps.
+This section contains best practices for developing constructs. Constructs are reusable, composable modules that encapsulate resources. They’re the building blocks of AWS CDK apps.
@@ -116 +121 @@ This section contains best practices for developing constructs. Constructs are r
-### Model with constructs, deploy with stacks
+**Model with constructs, deploy with stacks**
@@ -118 +123,2 @@ This section contains best practices for developing constructs. Constructs are r
-Stacks are the unit of deployment: everything in a stack is deployed together. So when building your application's higher-level logical units from multiple AWS resources, represent each logical unit as a [`Construct`](https://docs.aws.amazon.com/cdk/api/v2/docs/constructs.Construct.html), not as a [`Stack`](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html). Use stacks only to describe how your constructs should be composed and connected for your various deployment scenarios.
+
+Stacks are the unit of deployment: everything in a stack is deployed together. So when building your application’s higher-level logical units from multiple AWS resources, represent each logical unit as a [Construct](https://docs.aws.amazon.com/cdk/api/v2/docs/constructs.Construct.html), not as a [Stack](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html). Use stacks only to describe how your constructs should be composed and connected for your various deployment scenarios.
@@ -122 +128,3 @@ For example, if one of your logical units is a website, the constructs that make
-By using constructs for building and stacks for deploying, you improve reuse potential of your infrastructure and give yourself more flexibility in how it's deployed.
+By using constructs for building and stacks for deploying, you improve reuse potential of your infrastructure and give yourself more flexibility in how it’s deployed.
+
+**Configure with properties and methods, not environment variables**
@@ -124 +131,0 @@ By using constructs for building and stacks for deploying, you improve reuse pot
-### Configure with properties and methods, not environment variables
@@ -128 +135,3 @@ Environment variable lookups inside constructs and stacks are a common anti-patt
-In general, environment variable lookups should be limited to the top level of an AWS CDK app. They should also be used to pass in information that's needed for running in a development environment. For more information, see [Environments for the AWS CDK](./environments.html).
+In general, environment variable lookups should be limited to the top level of an AWS CDK app. They should also be used to pass in information that’s needed for running in a development environment. For more information, see [Environments for the AWS CDK](./environments.html).
+
+**Unit test your infrastructure**
@@ -130 +138,0 @@ In general, environment variable lookups should be limited to the top level of a
-### Unit test your infrastructure
@@ -134 +142,2 @@ To consistently run a full suite of unit tests at build time in all environments
-### Don't change the logical ID of stateful resources
+**Don’t change the logical ID of stateful resources**
+    
@@ -136 +145 @@ To consistently run a full suite of unit tests at build time in all environments
-Changing the logical ID of a resource results in the resource being replaced with a new one at the next deployment. For stateful resources like databases and S3 buckets, or persistent infrastructure like an Amazon VPC, this is seldom what you want. Be careful about any refactoring of your AWS CDK code that could cause the ID to change. Write unit tests that assert that the logical IDs of your stateful resources remain static. The logical ID is derived from the `id` you specify when you instantiate the construct, and the construct's position in the construct tree. For more information, see [Logical IDs](./identifiers.html#identifiers-logical-ids).
+Changing the logical ID of a resource results in the resource being replaced with a new one at the next deployment. For stateful resources like databases and S3 buckets, or persistent infrastructure like an Amazon VPC, this is seldom what you want. Be careful about any refactoring of your AWS CDK code that could cause the ID to change. Write unit tests that assert that the logical IDs of your stateful resources remain static. The logical ID is derived from the `id` you specify when you instantiate the construct, and the construct’s position in the construct tree. For more information, see [Logical IDs](./identifiers.html#identifiers-logical-ids).
@@ -138 +147 @@ Changing the logical ID of a resource results in the resource being replaced wit
-### Constructs aren't enough for compliance
+**Constructs aren’t enough for compliance**
@@ -140 +149,2 @@ Changing the logical ID of a resource results in the resource being replaced wit
-Many enterprise customers write their own wrappers for L2 constructs (the "curated" constructs that represent individual AWS resources with built-in sane defaults and best practices). These wrappers enforce security best practices such as static encryption and specific IAM policies. For example, you might create a `MyCompanyBucket` that you then use in your applications in place of the usual Amazon S3 `Bucket` construct. This pattern is useful for surfacing security guidance early in the software development lifecycle, but don't rely on it as the sole means of enforcement.
+
+Many enterprise customers write their own wrappers for L2 constructs (the "curated" constructs that represent individual AWS resources with built-in sane defaults and best practices). These wrappers enforce security best practices such as static encryption and specific IAM policies. For example, you might create a `MyCompanyBucket` that you then use in your applications in place of the usual Amazon S3 `Bucket` construct. This pattern is useful for surfacing security guidance early in the software development lifecycle, but don’t rely on it as the sole means of enforcement.
@@ -144 +154 @@ Instead, use AWS features such as [service control policies](https://docs.aws.am
-Finally, keep in mind that writing your own "L2+" constructs might prevent your developers from taking advantage of AWS CDK packages such as [AWS Solutions Constructs](https://docs.aws.amazon.com/solutions/latest/constructs/welcome.html) or third-party constructs from Construct Hub. These packages are typically built on standard AWS CDK constructs and won't be able to use your wrapper constructs.
+Finally, keep in mind that writing your own "L2+" constructs might prevent your developers from taking advantage of AWS CDK packages such as [AWS Solutions Constructs](https://docs.aws.amazon.com/solutions/latest/constructs/welcome.html) or third-party constructs from Construct Hub. These packages are typically built on standard AWS CDK constructs and won’t be able to use your wrapper constructs.
@@ -150 +160,4 @@ In this section we discuss how to write your AWS CDK applications, combining con
-### Make decisions at synthesis time
+**Make decisions at synthesis time**
+    
+
+Although AWS CloudFormation lets you make decisions at deployment time (using `Conditions`, `{ Fn::If }`, and `Parameters`), and the AWS CDK gives you some access to these mechanisms, we recommend against using them. The types of values that you can use and the types of operations you can perform on them are limited compared to what’s available in a general-purpose programming language.
@@ -152 +165 @@ In this section we discuss how to write your AWS CDK applications, combining con
-Although AWS CloudFormation lets you make decisions at deployment time (using `Conditions`, `{ Fn::If }`, and `Parameters`), and the AWS CDK gives you some access to these mechanisms, we recommend against using them. The types of values that you can use and the types of operations you can perform on them are limited compared to what's available in a general-purpose programming language.
+Instead, try to make all decisions, such as which construct to instantiate, in your AWS CDK application by using your programming language’s `if` statements and other features. For example, a common CDK idiom, iterating over a list and instantiating a construct with values from each item in the list, simply isn’t possible using AWS CloudFormation expressions.
@@ -154 +167 @@ Although AWS CloudFormation lets you make decisions at deployment time (using `C
-Instead, try to make all decisions, such as which construct to instantiate, in your AWS CDK application by using your programming language's `if` statements and other features. For example, a common CDK idiom, iterating over a list and instantiating a construct with values from each item in the list, simply isn't possible using AWS CloudFormation expressions.
+Treat AWS CloudFormation as an implementation detail that the AWS CDK uses for robust cloud deployments, not as a language target. You’re not writing AWS CloudFormation templates in TypeScript or Python, you’re writing CDK code that happens to use CloudFormation for deployment.
@@ -156 +169 @@ Instead, try to make all decisions, such as which construct to instantiate, in y
-Treat AWS CloudFormation as an implementation detail that the AWS CDK uses for robust cloud deployments, not as a language target. You're not writing AWS CloudFormation templates in TypeScript or Python, you're writing CDK code that happens to use CloudFormation for deployment.
+**Use generated resource names, not physical names**
@@ -158 +170,0 @@ Treat AWS CloudFormation as an implementation detail that the AWS CDK uses for r
-### Use generated resource names, not physical names
@@ -160 +172 @@ Treat AWS CloudFormation as an implementation detail that the AWS CDK uses for r
-Names are a precious resource. Each name can only be used once. Therefore, if you hardcode a table name or bucket name into your infrastructure and application, you can't deploy that piece of infrastructure twice in the same account. (The name we're talking about here is the name specified by, for example, the `bucketName` property on an Amazon S3 bucket construct.)
+Names are a precious resource. Each name can only be used once. Therefore, if you hardcode a table name or bucket name into your infrastructure and application, you can’t deploy that piece of infrastructure twice in the same account. (The name we’re talking about here is the name specified by, for example, the `bucketName` property on an Amazon S3 bucket construct.)
@@ -162 +174 @@ Names are a precious resource. Each name can only be used once. Therefore, if yo
-What's worse, you can't make changes to the resource that require it to be replaced. If a property can only be set at resource creation, such as the `KeySchema` of an Amazon DynamoDB table, then that property is immutable. Changing this property requires a new resource. However, the new resource must have the same name in order to be a true replacement. But it can't have the same name while the existing resource is still using that name.
+What’s worse, you can’t make changes to the resource that require it to be replaced. If a property can only be set at resource creation, such as the `KeySchema` of an Amazon DynamoDB table, then that property is immutable. Changing this property requires a new resource. However, the new resource must have the same name in order to be a true replacement. But it can’t have the same name while the existing resource is still using that name.
@@ -164 +176 @@ What's worse, you can't make changes to the resource that require it to be repla
-A better approach is to specify as few names as possible. If you omit resource names, the AWS CDK will generate them for you in a way that won't cause problems. Suppose you have a table as a resource. You can then pass the generated table name as an environment variable into your AWS Lambda function. In your AWS CDK application, you can reference the table name as `table.tableName`. Alternatively, you can generate a configuration file on your Amazon EC2 instance on startup, or write the actual table name to the AWS Systems Manager Parameter Store so your application can read it from there.
+A better approach is to specify as few names as possible. If you omit resource names, the AWS CDK will generate them for you in a way that won’t cause problems. Suppose you have a table as a resource. You can then pass the generated table name as an environment variable into your AWS Lambda function. In your AWS CDK application, you can reference the table name as `table.tableName`. Alternatively, you can generate a configuration file on your Amazon EC2 instance on startup, or write the actual table name to the AWS Systems Manager Parameter Store so your application can read it from there.
@@ -166 +178 @@ A better approach is to specify as few names as possible. If you omit resource n
-If the place you need it is another AWS CDK stack, that's even more straightforward. Supposing that one stack defines the resource and another stack needs to use it, the following applies:
+If the place you need it is another AWS CDK stack, that’s even more straightforward. Supposing that one stack defines the resource and another stack needs to use it, the following applies:
@@ -168 +180 @@ If the place you need it is another AWS CDK stack, that's even more straightforw
-  * If the two stacks are in the same AWS CDK app, pass a reference between the two stacks. For example, save a reference to the resource's construct as an attribute of the defining stack (`this.stack.uploadBucket = amzn-s3-demo-bucket`). Then, pass that attribute to the constructor of the stack that needs the resource.
+  * If the two stacks are in the same AWS CDK app, pass a reference between the two stacks. For example, save a reference to the resource’s construct as an attribute of the defining stack (`this.stack.uploadBucket = amzn-s3-demo-bucket`). Then, pass that attribute to the constructor of the stack that needs the resource.
@@ -175 +187 @@ If the place you need it is another AWS CDK stack, that's even more straightforw
-### Define removal policies and log retention
+**Define removal policies and log retention**
@@ -177 +189,2 @@ If the place you need it is another AWS CDK stack, that's even more straightforw
-The AWS CDK attempts to keep you from losing data by defaulting to policies that retain everything you create. For example, the default removal policy on resources that contain data (such as Amazon S3 buckets and database tables) is not to delete the resource when it is removed from the stack. Instead, the resource is orphaned from the stack. Similarly, the CDK's default is to retain all logs forever. In production environments, these defaults can quickly result in the storage of large amounts of data that you don't actually need, and a corresponding AWS bill.
+
+The AWS CDK attempts to keep you from losing data by defaulting to policies that retain everything you create. For example, the default removal policy on resources that contain data (such as Amazon S3 buckets and database tables) is not to delete the resource when it is removed from the stack. Instead, the resource is orphaned from the stack. Similarly, the CDK’s default is to retain all logs forever. In production environments, these defaults can quickly result in the storage of large amounts of data that you don’t actually need, and a corresponding AWS bill.
@@ -181 +194,2 @@ Consider carefully what you want these policies to be for each production resour
-### Separate your application into multiple stacks as dictated by deployment requirements
+**Separate your application into multiple stacks as dictated by deployment requirements**
+    
@@ -183 +197 @@ Consider carefully what you want these policies to be for each production resour
-There is no hard and fast rule to how many stacks your application needs. You'll usually end up basing the decision on your deployment patterns. Keep in mind the following guidelines:
+There is no hard and fast rule to how many stacks your application needs. You’ll usually end up basing the decision on your deployment patterns. Keep in mind the following guidelines:
@@ -185 +199 @@ There is no hard and fast rule to how many stacks your application needs. You'll
-  * It's typically more straightforward to keep as many resources in the same stack as possible, so keep them together unless you know you want them separated.
+  * It’s typically more straightforward to keep as many resources in the same stack as possible, so keep them together unless you know you want them separated.
@@ -189 +203 @@ There is no hard and fast rule to how many stacks your application needs. You'll
-  * Stateful resources are more sensitive to construct renaming—renaming leads to resource replacement. Therefore, don't nest stateful resources inside constructs that are likely to be moved around or renamed (unless the state can be rebuilt if lost, like a cache). This is another good reason to put stateful resources in their own stack.
+  * Stateful resources are more sensitive to construct renaming—​renaming leads to resource replacement. Therefore, don’t nest stateful resources inside constructs that are likely to be moved around or renamed (unless the state can be rebuilt if lost, like a cache). This is another good reason to put stateful resources in their own stack.
@@ -194 +208,2 @@ There is no hard and fast rule to how many stacks your application needs. You'll
-### Commit `cdk.context.json` to avoid non-deterministic behavior
+**Commit`cdk.context.json` to avoid non-deterministic behavior**
+    
@@ -200 +215 @@ Since your AWS CDK app is written in a general-purpose programming language, it
-Never modify your AWS account or resources during synthesis. Synthesizing an app should not have side effects. Changes to your infrastructure should happen only in the deployment phase, after the AWS CloudFormation template has been generated. This way, if there's a problem, AWS CloudFormation can automatically roll back the change. To make changes that can't be easily made within the AWS CDK framework, use [custom resources](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.custom_resources-readme.html) to execute arbitrary code at deployment time.
+Never modify your AWS account or resources during synthesis. Synthesizing an app should not have side effects. Changes to your infrastructure should happen only in the deployment phase, after the AWS CloudFormation template has been generated. This way, if there’s a problem, AWS CloudFormation can automatically roll back the change. To make changes that can’t be easily made within the AWS CDK framework, use [custom resources](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.custom_resources-readme.html) to execute arbitrary code at deployment time.
@@ -204 +219 @@ Even strictly read-only calls are not necessarily safe. Consider what happens if
-  * If you provision an Amazon VPC to all available Availability Zones in a specified Region, and the number of AZs is two on deployment day, then your IP space gets split in half. If AWS launches a new Availability Zone the next day, the next deployment after that tries to split your IP space into thirds, requiring all subnets to be recreated. This probably won't be possible because your Amazon EC2 instances are still running, and you'll have to clean this up manually.
+  * If you provision an Amazon VPC to all available Availability Zones in a specified Region, and the number of AZs is two on deployment day, then your IP space gets split in half. If AWS launches a new Availability Zone the next day, the next deployment after that tries to split your IP space into thirds, requiring all subnets to be recreated. This probably won’t be possible because your Amazon EC2 instances are still running, and you’ll have to clean this up manually.
@@ -213 +228 @@ These situations can be pernicious because the AWS-side change might occur after
-Fortunately, the AWS CDK includes a mechanism called _context providers_ to record a snapshot of non-deterministic values. This allows future synthesis operations to produce exactly the same template as they did when first deployed. The only changes in the new template are the changes that _you_ made in your code. When you use a construct's `.fromLookup()` method, the result of the call is cached in `cdk.context.json`. You should commit this to version control along with the rest of your code to make sure that future executions of your CDK app use the same value. The CDK Toolkit includes commands to manage the context cache, so you can refresh specific entries when you need to. For more information, see [Context values and the AWS CDK](./context.html).
+Fortunately, the AWS CDK includes a mechanism called _context providers_ to record a snapshot of non-deterministic values. This allows future synthesis operations to produce exactly the same template as they did when first deployed. The only changes in the new template are the changes that _you_ made in your code. When you use a construct’s `.fromLookup()` method, the result of the call is cached in `cdk.context.json`. You should commit this to version control along with the rest of your code to make sure that future executions of your CDK app use the same value. The CDK Toolkit includes commands to manage the context cache, so you can refresh specific entries when you need to. For more information, see [Context values and the AWS CDK](./context.html).
@@ -217 +232,2 @@ If you need some value (from AWS or elsewhere) for which there is no native CDK
-### Let the AWS CDK manage roles and security groups
+**Let the AWS CDK manage roles and security groups**
+    
@@ -219 +235 @@ If you need some value (from AWS or elsewhere) for which there is no native CDK
-With the AWS CDK construct library's `grant()` convenience methods, you can create AWS Identity and Access Management roles that grant access to one resource by another using minimally scoped permissions. For example, consider a line like the following:
+With the AWS CDK construct library’s `grant()` convenience methods, you can create AWS Identity and Access Management roles that grant access to one resource by another using minimally scoped permissions. For example, consider a line like the following:
@@ -224 +240 @@ With the AWS CDK construct library's `grant()` convenience methods, you can crea
-This single line adds a policy to the Lambda function's role (which is also created for you). That role and its policies are more than a dozen lines of CloudFormation that you don't have to write. The AWS CDK grants only the minimal permissions required for the function to read from the bucket.
+This single line adds a policy to the Lambda function’s role (which is also created for you). That role and its policies are more than a dozen lines of CloudFormation that you don’t have to write. The AWS CDK grants only the minimal permissions required for the function to read from the bucket.
@@ -228 +244 @@ If you require developers to always use predefined roles that were created by a
-### Model all production stages in code
+**Model all production stages in code**
@@ -230 +246,2 @@ If you require developers to always use predefined roles that were created by a
-In traditional AWS CloudFormation scenarios, your goal is to produce a single artifact that is parameterized so that it can be deployed to various target environments after applying configuration values specific to those environments. In the CDK, you can, and should, build that configuration into your source code. Create a stack for your production environment, and create a separate stack for each of your other stages. Then, put the configuration values for each stack in the code. Use services like [Secrets Manager](https://aws.amazon.com/secrets-manager/) and [Systems Manager](https://aws.amazon.com/systems-manager/) Parameter Store for sensitive values that you don't want to check in to source control, using the names or ARNs of those resources.
+
+In traditional AWS CloudFormation scenarios, your goal is to produce a single artifact that is parameterized so that it can be deployed to various target environments after applying configuration values specific to those environments. In the CDK, you can, and should, build that configuration into your source code. Create a stack for your production environment, and create a separate stack for each of your other stages. Then, put the configuration values for each stack in the code. Use services like [Secrets Manager](https://aws.amazon.com/secrets-manager/) and [Systems Manager](https://aws.amazon.com/systems-manager/) Parameter Store for sensitive values that you don’t want to check in to source control, using the names or ARNs of those resources.
@@ -234 +251,2 @@ When you synthesize your application, the cloud assembly created in the `cdk.out
-### Measure everything
+**Measure everything**
+    
@@ -236 +254 @@ When you synthesize your application, the cloud assembly created in the `cdk.out
-Achieving the goal of full continuous deployment, with no human intervention, requires a high level of automation. That automation is only possible with extensive amounts of monitoring. To measure all aspects of your deployed resources, create metrics, alarms, and dashboards. Don't stop at measuring things like CPU usage and disk space. Also record your business metrics, and use those measurements to automate deployment decisions like rollbacks. Most of the L2 constructs in AWS CDK have convenience methods to help you create metrics, such as the `metricUserErrors()` method on the [dynamodb.Table](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_dynamodb.Table.html) class.
+Achieving the goal of full continuous deployment, with no human intervention, requires a high level of automation. That automation is only possible with extensive amounts of monitoring. To measure all aspects of your deployed resources, create metrics, alarms, and dashboards. Don’t stop at measuring things like CPU usage and disk space. Also record your business metrics, and use those measurements to automate deployment decisions like rollbacks. Most of the L2 constructs in AWS CDK have convenience methods to help you create metrics, such as the `metricUserErrors()` method on the [`dynamodb.Table`](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_dynamodb.Table.html) class.