Increasing development speed with CDK Watch

海外精选
海外精选的内容汇集了全球优质的亚马逊云科技相关技术内容。同时,内容中提到的“AWS” 是 “Amazon Web Services” 的缩写,在此网站不作为商标展示。
0
0
{"value":"The [AWS Cloud Development Kit (CDK)](https://aws.amazon.com/cdk/) CLI introduces a new mode of operation, ```cdk watch```, and two new flags for ```cdk deploy```, ```--hotswap``` and ```--no-rollback```. ```cdk watch``` makes development faster by monitoring your code and assets for changes and automatically performing the optimal form of deployment every time a file change is detected, meaning you no longer have to run ```cdk deploy``` each time you make a change to your CDK application. Where possible, ```cdk watch``` will use the ```--hotswap``` flag, which inspects the changes in your project and determines if those changes can be updated in-place without a full deployment through [AWS CloudFormation](https://aws.amazon.com/cloudformation/). For CDK assets like your [AWS Lambda](https://aws.amazon.com/lambda/) handler code, [Amazon ECS](https://aws.amazon.com/ecs/) container images, or [AWS Step Functions](https://aws.amazon.com/step-functions/) state machines, the CDK CLI will use AWS service APIs to directly make the changes; otherwise it will fall back to performing a full CloudFormation deployment. The ```--no-rollback``` flag will prevent CloudFormation from rolling back failed changes, saving more iteration time on failed deployments.\n\nTo see ```cdk watch``` and the ```--hotswap``` and ```--no-rollback``` flags in action, follow the instructions below. You will be using CDK in TypeScript in this blog post, but ```watch``` works with all CDK-supported languages. First, you will create a blank CDK application, and then you will add a simple containerized application using TypeScript and Express to your CDK application. Next, you will write the CDK stack that will create the infrastructure needed to deploy your application. Finally, you will use ```cdk watch``` to iterate on the application code.\n\n### **Prerequisites**\n\n- An AWS account\n- A local CDK installation\n\n### **Setup**\n\nEnsure you have the CDK CLI V2 installed (```cdk watch``` will also work with V1, but these examples are all written with V2 style imports). If you don’t have it installed, see the instructions in the [AWS CDK Developer Guide](https://docs.aws.amazon.com/cdk/latest/guide/getting_started.html#getting_started_install). To verify your installation works correctly, run the ```cdk --version``` command in a terminal; you should see output similar to:\n```\\ncdk --version\\n2.0.0 (build 4b6ce31)\\n```\nFirst, create a new CDK application in TypeScript by running the following commands in your terminal.\n\n```\\nmkdir cdk-watch\\ncd cdk-watch\\ncdk init --language=typescript\\n```\n\n### **Application Code**\n\nFrom the ```cdk-watch``` directory, create a directory and the files you will need to build your Docker image.\n\n```\\nmkdir docker-app\\n```\n\nNext, you must create the ```package.json``` that will declare our application’s dependencies. Note that the only dependency you need is Express; TypeScript does not need to be declared as a dependency, because it will be compiled to JavaScript before the application is deployed. Create ```docker-app/package.json``` and add the following contents.\n\nJSON\n\n```\\n{\\n \\"name\\": \\"simple-webpage\\",\\n \\"version\\": \\"1.0.0\\",\\n \\"description\\": \\"Demo web app running on Amazon ECS\\",\\n \\"license\\": \\"MIT-0\\",\\n \\"dependencies\\": {\\n \\"express\\": \\"^4.17.1\\"\\n },\\n \\"devDependencies\\": {\\n \\"@types/express\\": \\"^4.17.13\\"\\n }\\n}\\n```\nNext, you must create the HTML file that will serve as your webpage. Create ```docker-app/index.html``` and add the following code.\n\nJSON\n\n```\\n<!DOCTYPE html>\\n\\n<html lang=\\"en\\" dir=\\"ltr\\">\\n<head>\\n <meta charset=\\"utf-8\\">\\n <title>Simple Webpage </title>\\n</head>\\n\\n<body>\\n<div align=\\"center\\"\\n <h2>Hello World</h2>\\n <hr width=\\"25%\\">\\n</div>\\n</body>\\n</html>\\n```\nNow, you will create your Express code that will serve the HTML file you just created to any visitors to the site. Create ```docker-app/webpage.ts``` and add the following code.\n\nTypeScript\n\n```\\nimport * as express from 'express';\\n\\nconst app = express();\\n\\napp.get(\\"/\\", (req, res) => {\\n res.sendFile(__dirname + \\"/index.html\\");\\n});\\n\\napp.listen(80, function () {\\n console.log(\\"server started on port 80\\");\\n});\\n```\nLastly, you will create the ```Dockerfile``` that will start your application. Create docker-app/Dockerfile and add the following code.\n\n```\\nFROM node:alpine\\nRUN mkdir -p /usr/src/www\\nWORKDIR /usr/src/www\\nCOPY . .\\nRUN npm install --production-only\\nCMD [\\"node\\", \\"webpage.js\\"]\\n```\n### **Infrastructure Code**\n\nYou will now create the CDK stack that defines the infrastructure that will host your webpage. You will use the ```ApplicationLoadBalancedFargateService``` construct from the ```aws_ecs_patterns``` module to greatly simplify your stack. Modify ```lib/cdk-watch-stack.ts``` so that it looks like the following example.\n\nTypeScript\n\n```\\nimport { \\n Stack,\\n StackProps,\\n aws_ec2 as ec2,\\n aws_ecs as ecs,\\n aws_ecs_patterns as ecs_patterns,\\n} from 'aws-cdk-lib';\\n\\nimport { Construct } from 'constructs';\\n\\nexport class CdkWatchStack extends Stack {\\n constructor(scope: Construct, id: string, props?: StackProps) {\\n super(scope, id, props);\\n\\nconst vpc = new ec2.Vpc(this, 'Vpc', {\\n maxAzs: 2,\\n natGateways: 1,\\n});\\n\\nnew ecs_patterns.ApplicationLoadBalancedFargateService(this, 'EcsService', {\\n vpc,\\n taskImageOptions: {\\n image: ecs.ContainerImage.fromAsset('docker-app'),\\n containerPort: 80,\\n },\\n });\\n }\\n}\\n```\nAny command specified in the build key (found in ```cdk.json```) will be invoked prior to synthesis by any deployment, including those from ```cdk watch```. Your application has TypeScript that needs to be compiled to JavaScript, so add this code to ```cdk.json``` at the same level as the ```“app”``` key:\n\n```\\n\\"build\\": \\"cd docker-app && tsc\\",\\n```\nThis creates an entire serverless Docker application. With these changes, run the following commands.\n\n```\\nyarn install # or, if you prefer, npm install\\ncdk deploy\\n```\nYou should see output similar to example below when the deployment finishes.\n\nBash\n\n```\\n✅ CdkWatchStack\\n\\nOutputs:\\nCdkWatchStack.EcsServiceLoadBalancerDNS6D595ACE = CdkWa-EcsSe-18QPSCKV5G8XP-1157603428.us-east-2.elb.amazonaws.com\\nCdkWatchStack.EcsServiceServiceURLE56F060F = http://CdkWa-EcsSe-18QPSCKV5G8XP-1157603428.us-east-2.elb.amazonaws.com\\n\\nStack ARN:\\narn:aws:cloudformation:us-east-2:131099214097:stack/CdkWatchStack/1b15db20-428a-11ec-b96f-0a2907d0130e\\n```\nOpen the link included in the second line of the Outputs section. You should see a page that says Hello World.\n\n![image.png](https://dev-media.amazoncloud.cn/5850483cc82441edb392086359b90ba9_image.png)\n\n\n### **Making an Application Code Change**\n\nNow that you’ve deployed your application, you can use ```cdk watch``` to make changes to it. Run ```cdk watch``` in a terminal, which should show the following output.\n\nBash\n\n```\\n'watch' is observing directory '' for changes\\n'watch' is observing the file 'cdk.context.json' for changes\\n'watch' is observing directory 'bin' for changes\\n'watch' is observing directory 'docker-app' for changes\\n'watch' is observing directory 'lib' for changes\\n'watch' is observing the file 'bin/cdk-watch.ts' for changes\\n'watch' is observing the file 'lib/cdk-watch-stack.ts' for changes\\n'watch' is observing the file 'docker-app/Dockerfile' for changes\\n'watch' is observing the file 'docker-app/index.html' for changes\\n'watch' is observing the file 'docker-app/package.json' for changes\\n'watch' is observing the file 'docker-app/webpage.ts' for changes\\n```\nWhen making application code changes, ```cdk watch``` can speedup the deployment. To see it, make the following change to ```index.html```.\n\nHTML\n\n```\\n<!DOCTYPE html>\\n\\n<html lang=\\"en\\" dir=\\"ltr\\">\\n<head>\\n <meta charset=\\"utf-8\\">\\n <title> Simple Webpage </title>\\n</head>\\n\\n<body>\\n<div align=\\"center\\">\\n <h2>Hello World</h2>\\n <hr width=\\"25%\\">\\n <p>A paragraph</p>\\n</div>\\n</body>\\n</html>\\n```\nIn the terminal you will see ```cdk watch``` deploy this change.\n\n```\\nDetected change to 'docker-app/index.html' (type: change). Triggering 'cdk deploy'\\n⚠️ The --hotswap flag deliberately introduces CloudFormation drift to speed up deployments\\n⚠️ It should only be used for development - never use it for your production Stacks!\\n```\nThe warning message lets you know that this change is being hotswapped. This means that this change is made by going directly to the service API that provides the resource(s) being updated, bypassing CloudFormation entirely. This introduces drift between your CloudFormation template and your deployed application code. Because of this drift, hotswapping should never be used in a production environment. Hotswap deployments are faster, but lack the robust safety features of CloudFormation deployments, making hotswap deployments ideal for performing rapid code-compile-test loops in your development environment. If you need to disable hotswapping while running ```watch```, pass the ```--no-hotswap``` flag to ```watch```. If you need to remove the drift between CloudFormation and your application entirely, simply perform a full CloudFormation deployment by executing ```cdk deploy```. If you want to perform a hotswap deployment without running ```cdk watch```, run ```cdk deploy --hotswap```.\n\nOnce this change has been deployed, refresh the page. You should now see the following update to the Hello World page.\n\n![image.png](https://dev-media.amazoncloud.cn/2aa9799c986f4293932aa078e5ecbd8a_image.png)\n\n### **Making an Infrastructure Change**\n\nNot all resource changes can be hotswapped. Currently, only Lambda Function code changes, ECS Service container definition changes, and Step Functions state machine definition changes can be hotswapped. If any other changes are made, hotswap deployments will fall back to full CloudFormation deployments. To see this, make the following code change to ```cdk-watch-stack.ts```.\n\nTypeScript\n\n```\\nimport { \\n Stack,\\n StackProps,\\n aws_ec2 as ec2,\\n aws_ecs as ecs,\\n aws_ecs_patterns as ecs_patterns,\\n} from 'aws-cdk-lib';\\n\\nimport { Construct } from 'constructs';\\n\\nexport class CdkWatchStack extends Stack {\\n constructor(scope: Construct, id: string, props?: StackProps) {\\n super(scope, id, props);\\n\\n // Fargate does not work with default VPCs\\n const vpc = new ec2.Vpc(this, 'Vpc', {\\n maxAzs: 2, // ALB requires 2 AZs\\n natGateways: 2, //changing this property does not trigger a hotswap, and a full deployment occurs instead\\n });\\n\\n new ecs_patterns.ApplicationLoadBalancedFargateService(this, 'EcsService', {\\n vpc,\\n taskImageOptions: {\\n image: ecs.ContainerImage.fromAsset('docker-app'),\\n containerPort: 80,\\n },\\n });\\n }\\n}\\n```\nObserve the terminal window. After the assets have finished publishing, you will see the following output.\n\n```\\nCould not perform a hotswap deployment, as the stack CdkWatchStack contains non-Asset changes\\nFalling back to doing a full deployment\\n```\nThis means that the changes included a non-hotswappable change. Generally, changes to your application’s infrastructure are not hotswappable, while changes to assets used by your application are. This change increases the number of ```natGateways``` used by the ```vpc```, so this is an infrastructure change and is therefore not hotswappable; thus, ```watch``` will fall back to performing a full CloudFormation deployment.\n\n\n### **Disabling Rollback**\n\nBy default, ```cdk watch``` does not use ```--no-rollback```. Before disabling rollback, enter the ```^C``` character (```control+c```) in the terminal window running cdk watch, and then run the ```cdk deploy``` command from your terminal.\n\n```\\ncdk deploy\\n```\nThe full deployment is performed first to make CloudFormation aware of the changes you made earlier. These changes are considered replacement type changes by CloudFormation, which do not support the ```--no-rollback flag```, because they require the deletion and creation of one of the resources that make up the ```ApplicationLoadBalancedFargateService```. Once the deployment finishes, run the following command.\n\n```\\ncdk watch --no-rollback\\n```\n\nYou should see the same output you did when you first ran ```cdk watch```. Now make the following change to your stack:\n\nTypeScript\n\n```\\nimport { \\n Stack,\\n StackProps,\\n aws_ec2 as ec2,\\n aws_ecs as ecs,\\n aws_ecs_patterns as ecs_patterns,\\n} from 'aws-cdk-lib';\\n\\nimport { Construct } from 'constructs';\\n\\nexport class CdkWatchStack extends Stack {\\n constructor(scope: Construct, id: string, props?: StackProps) {\\n super(scope, id, props);\\n\\n // Fargate does not work with default VPCs\\n const vpc = new ec2.Vpc(this, 'Vpc', {\\n maxAzs: 2, // ALB requires 2 AZs\\n natGateways: 2, \\n });\\n\\n new ec2.CfnVPC(this, 'mycfnvpc', { \\n cidrBlock: '10.0.0/16' //intentionally incorrect code\\n });\\n\\n new ecs_patterns.ApplicationLoadBalancedFargateService(this, 'EcsService', {\\n vpc,\\n taskImageOptions: {\\n image: ecs.ContainerImage.fromAsset('docker-app'),\\n containerPort: 80,\\n },\\n });\\n }\\n}\\n```\nNote that this change specifies an invalid ```cidrBlock```. The full deployment result is expected: this is an infrastructure change, so it is not hotswappable. As ```cdk watch``` is attempting the deployment, you will see the following error message.\n\n```\\nCould not perform a hotswap deployment, as the stack CdkWatchStack contains non-Asset changes\\nFalling back to doing a full deployment\\nCdkWatchStack: creating CloudFormation changeset...\\n3:17:02 PM | CREATE_FAILED | AWS::EC2::VPC | mycfnvpc\\nValue (10.0.0/16) for parameter cidrBlock is invalid. This is not a valid CIDR block. (Service: AmazonEC2; Status Code: 400; Error Code: InvalidParameterValue; Request ID: 4b670ce5-32bd-46dd-88de-33765f18d479; Proxy: null)\\n\\n❌ CdkWatchStack failed: Error: The stack named CdkWatchStack failed to deploy: UPDATE_FAILED (The following resource(s) failed to create: [mycfnvpc]. )\\nat Object.waitForStackDeploy (/usr/local/lib/node_modules/aws-cdk/lib/api/util/cloudformation.ts:309:11)\\nat processTicksAndRejections (internal/process/task_queues.js:95:5)\\nat prepareAndExecuteChangeSet (/usr/local/lib/node_modules/aws-cdk/lib/api/deploy-stack.ts:337:26)\\nat CdkToolkit.deploy (/usr/local/lib/node_modules/aws-cdk/lib/cdk-toolkit.ts:194:24)\\nat CdkToolkit.invokeDeployFromWatch (/usr/local/lib/node_modules/aws-cdk/lib/cdk-toolkit.ts:594:7)\\nat FSWatcher.<anonymous>(/usr/local/lib/node_modules/aws-cdk/lib/cdk-toolkit.ts:310:9)\\n```\nWithout ```--no-rollback```, this change would be rolled back by CloudFormation. Now make this ```cidrBlock``` valid by making this change:\n\nTypeScript\n\n```\\nimport { \\n Stack,\\n StackProps,\\n aws_ec2 as ec2,\\n aws_ecs as ecs,\\n aws_ecs_patterns as ecs_patterns,\\n} from 'aws-cdk-lib';\\n\\nimport { Construct } from 'constructs';\\n\\nexport class CdkWatchStack extends Stack {\\n constructor(scope: Construct, id: string, props?: StackProps) {\\n super(scope, id, props);\\n\\n // Fargate does not work with default VPCs\\n const vpc = new ec2.Vpc(this, 'Vpc', {\\n maxAzs: 2, // ALB requires 2 AZs\\n natGateways: 2, \\n });\\n \\n new ec2.CfnVPC(this, 'mycfnvpc', {\\n cidrBlock: '10.0.0.0/16' //corrected code \\n });\\n\\n new ecs_patterns.ApplicationLoadBalancedFargateService(this, 'EcsService', {\\n vpc,\\n taskImageOptions: {\\n image: ecs.ContainerImage.fromAsset('docker-app'),\\n containerPort: 80,\\n },\\n });\\n }\\n}\\n```\n```cdk watch``` will detect this change and automatically successfully deploy it with the following output.\n\n\n```\\nCould not perform a hotswap deployment, as the stack CdkWatchStack contains non-Asset changes\\nFalling back to doing a full deployment\\nCdkWatchStack: creating CloudFormation changeset...\\n\\n\\n ✅ CdkWatchStack\\n\\nOutputs:\\nCdkWatchStack.EcsServiceLoadBalancerDNS6D595ACE = CdkWa-EcsSe-T2ZOAGRO8LGP-297129573.us-east-2.elb.amazonaws.com\\nCdkWatchStack.EcsServiceServiceURLE56F060F = http://CdkWa-EcsSe-T2ZOAGRO8LGP-297129573.us-east-2.elb.amazonaws.com\\n\\nStack ARN:\\narn:aws:cloudformation:us-east-2:131099214097:stack/CdkWatchStack/95d784f0-4d73-11ec-a8b8-062cd5cc0070\\n```\n### **Cleaning up**\n\nTo delete the stack and application that you just deployed, run the ```cdk destroy``` command in your CDK project’s root directory.\n\n```\\ncdk destroy\\n```\n### **Summary**\n\n```cdk watch``` allows you to make more rapid updates to your development stacks by leveraging hotswapping, where possible, to bypass CloudFormation. Not all resource changes can be hotswapped; if a hotswap deployment cannot be performed, ```watch``` will fall back to a full CloudFormation deployment. Due to the intentional drift introduced by hotswapping, it should never be used in a production environment. If desired, hotswapping can be turned off by passing the ```--no-hotswap``` flag. ```cdk watch``` can be invoked with the ```--no-rollback``` flag to disable rollback of failed updates, but any updates that CloudFormation considers as replacement type updates are not affected by this flag.","render":"<p>The <a href=\\"https://aws.amazon.com/cdk/\\" target=\\"_blank\\">AWS Cloud Development Kit (CDK)</a> CLI introduces a new mode of operation, <code>cdk watch</code>, and two new flags for <code>cdk deploy</code>, <code>--hotswap</code> and <code>--no-rollback</code>. <code>cdk watch</code> makes development faster by monitoring your code and assets for changes and automatically performing the optimal form of deployment every time a file change is detected, meaning you no longer have to run <code>cdk deploy</code> each time you make a change to your CDK application. Where possible, <code>cdk watch</code> will use the <code>--hotswap</code> flag, which inspects the changes in your project and determines if those changes can be updated in-place without a full deployment through <a href=\\"https://aws.amazon.com/cloudformation/\\" target=\\"_blank\\">AWS CloudFormation</a>. For CDK assets like your <a href=\\"https://aws.amazon.com/lambda/\\" target=\\"_blank\\">AWS Lambda</a> handler code, <a href=\\"https://aws.amazon.com/ecs/\\" target=\\"_blank\\">Amazon ECS</a> container images, or <a href=\\"https://aws.amazon.com/step-functions/\\" target=\\"_blank\\">AWS Step Functions</a> state machines, the CDK CLI will use AWS service APIs to directly make the changes; otherwise it will fall back to performing a full CloudFormation deployment. The <code>--no-rollback</code> flag will prevent CloudFormation from rolling back failed changes, saving more iteration time on failed deployments.</p>\\n<p>To see <code>cdk watch</code> and the <code>--hotswap</code> and <code>--no-rollback</code> flags in action, follow the instructions below. You will be using CDK in TypeScript in this blog post, but <code>watch</code> works with all CDK-supported languages. First, you will create a blank CDK application, and then you will add a simple containerized application using TypeScript and Express to your CDK application. Next, you will write the CDK stack that will create the infrastructure needed to deploy your application. Finally, you will use <code>cdk watch</code> to iterate on the application code.</p>\\n<h3><a id=\\"Prerequisites_4\\"></a><strong>Prerequisites</strong></h3>\\n<ul>\\n<li>An AWS account</li>\n<li>A local CDK installation</li>\n</ul>\\n<h3><a id=\\"Setup_9\\"></a><strong>Setup</strong></h3>\\n<p>Ensure you have the CDK CLI V2 installed (<code>cdk watch</code> will also work with V1, but these examples are all written with V2 style imports). If you don’t have it installed, see the instructions in the <a href=\\"https://docs.aws.amazon.com/cdk/latest/guide/getting_started.html#getting_started_install\\" target=\\"_blank\\">AWS CDK Developer Guide</a>. To verify your installation works correctly, run the <code>cdk --version</code> command in a terminal; you should see output similar to:</p>\\n<pre><code class=\\"lang-\\">cdk --version\\n2.0.0 (build 4b6ce31)\\n</code></pre>\\n<p>First, create a new CDK application in TypeScript by running the following commands in your terminal.</p>\n<pre><code class=\\"lang-\\">mkdir cdk-watch\\ncd cdk-watch\\ncdk init --language=typescript\\n</code></pre>\\n<h3><a id=\\"Application_Code_24\\"></a><strong>Application Code</strong></h3>\\n<p>From the <code>cdk-watch</code> directory, create a directory and the files you will need to build your Docker image.</p>\\n<pre><code class=\\"lang-\\">mkdir docker-app\\n</code></pre>\\n<p>Next, you must create the <code>package.json</code> that will declare our application’s dependencies. Note that the only dependency you need is Express; TypeScript does not need to be declared as a dependency, because it will be compiled to JavaScript before the application is deployed. Create <code>docker-app/package.json</code> and add the following contents.</p>\\n<p>JSON</p>\n<pre><code class=\\"lang-\\">{\\n &quot;name&quot;: &quot;simple-webpage&quot;,\\n &quot;version&quot;: &quot;1.0.0&quot;,\\n &quot;description&quot;: &quot;Demo web app running on Amazon ECS&quot;,\\n &quot;license&quot;: &quot;MIT-0&quot;,\\n &quot;dependencies&quot;: {\\n &quot;express&quot;: &quot;^4.17.1&quot;\\n },\\n &quot;devDependencies&quot;: {\\n &quot;@types/express&quot;: &quot;^4.17.13&quot;\\n }\\n}\\n</code></pre>\\n<p>Next, you must create the HTML file that will serve as your webpage. Create <code>docker-app/index.html</code> and add the following code.</p>\\n<p>JSON</p>\n<pre><code class=\\"lang-\\">&lt;!DOCTYPE html&gt;\\n\\n&lt;html lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;\\n&lt;head&gt;\\n &lt;meta charset=&quot;utf-8&quot;&gt;\\n &lt;title&gt;Simple Webpage &lt;/title&gt;\\n&lt;/head&gt;\\n\\n&lt;body&gt;\\n&lt;div align=&quot;center&quot;\\n &lt;h2&gt;Hello World&lt;/h2&gt;\\n &lt;hr width=&quot;25%&quot;&gt;\\n&lt;/div&gt;\\n&lt;/body&gt;\\n&lt;/html&gt;\\n</code></pre>\\n<p>Now, you will create your Express code that will serve the HTML file you just created to any visitors to the site. Create <code>docker-app/webpage.ts</code> and add the following code.</p>\\n<p>TypeScript</p>\n<pre><code class=\\"lang-\\">import * as express from 'express';\\n\\nconst app = express();\\n\\napp.get(&quot;/&quot;, (req, res) =&gt; {\\n res.sendFile(__dirname + &quot;/index.html&quot;);\\n});\\n\\napp.listen(80, function () {\\n console.log(&quot;server started on port 80&quot;);\\n});\\n</code></pre>\\n<p>Lastly, you will create the <code>Dockerfile</code> that will start your application. Create docker-app/Dockerfile and add the following code.</p>\\n<pre><code class=\\"lang-\\">FROM node:alpine\\nRUN mkdir -p /usr/src/www\\nWORKDIR /usr/src/www\\nCOPY . .\\nRUN npm install --production-only\\nCMD [&quot;node&quot;, &quot;webpage.js&quot;]\\n</code></pre>\\n<h3><a id=\\"Infrastructure_Code_98\\"></a><strong>Infrastructure Code</strong></h3>\\n<p>You will now create the CDK stack that defines the infrastructure that will host your webpage. You will use the <code>ApplicationLoadBalancedFargateService</code> construct from the <code>aws_ecs_patterns</code> module to greatly simplify your stack. Modify <code>lib/cdk-watch-stack.ts</code> so that it looks like the following example.</p>\\n<p>TypeScript</p>\n<pre><code class=\\"lang-\\">import { \\n Stack,\\n StackProps,\\n aws_ec2 as ec2,\\n aws_ecs as ecs,\\n aws_ecs_patterns as ecs_patterns,\\n} from 'aws-cdk-lib';\\n\\nimport { Construct } from 'constructs';\\n\\nexport class CdkWatchStack extends Stack {\\n constructor(scope: Construct, id: string, props?: StackProps) {\\n super(scope, id, props);\\n\\nconst vpc = new ec2.Vpc(this, 'Vpc', {\\n maxAzs: 2,\\n natGateways: 1,\\n});\\n\\nnew ecs_patterns.ApplicationLoadBalancedFargateService(this, 'EcsService', {\\n vpc,\\n taskImageOptions: {\\n image: ecs.ContainerImage.fromAsset('docker-app'),\\n containerPort: 80,\\n },\\n });\\n }\\n}\\n</code></pre>\\n<p>Any command specified in the build key (found in <code>cdk.json</code>) will be invoked prior to synthesis by any deployment, including those from <code>cdk watch</code>. Your application has TypeScript that needs to be compiled to JavaScript, so add this code to <code>cdk.json</code> at the same level as the <code>“app”</code> key:</p>\\n<pre><code class=\\"lang-\\">&quot;build&quot;: &quot;cd docker-app &amp;&amp; tsc&quot;,\\n</code></pre>\\n<p>This creates an entire serverless Docker application. With these changes, run the following commands.</p>\n<pre><code class=\\"lang-\\">yarn install # or, if you prefer, npm install\\ncdk deploy\\n</code></pre>\\n<p>You should see output similar to example below when the deployment finishes.</p>\n<p>Bash</p>\n<pre><code class=\\"lang-\\">✅ CdkWatchStack\\n\\nOutputs:\\nCdkWatchStack.EcsServiceLoadBalancerDNS6D595ACE = CdkWa-EcsSe-18QPSCKV5G8XP-1157603428.us-east-2.elb.amazonaws.com\\nCdkWatchStack.EcsServiceServiceURLE56F060F = http://CdkWa-EcsSe-18QPSCKV5G8XP-1157603428.us-east-2.elb.amazonaws.com\\n\\nStack ARN:\\narn:aws:cloudformation:us-east-2:131099214097:stack/CdkWatchStack/1b15db20-428a-11ec-b96f-0a2907d0130e\\n</code></pre>\\n<p>Open the link included in the second line of the Outputs section. You should see a page that says Hello World.</p>\n<p><img src=\\"https://dev-media.amazoncloud.cn/5850483cc82441edb392086359b90ba9_image.png\\" alt=\\"image.png\\" /></p>\n<h3><a id=\\"Making_an_Application_Code_Change_164\\"></a><strong>Making an Application Code Change</strong></h3>\\n<p>Now that you’ve deployed your application, you can use <code>cdk watch</code> to make changes to it. Run <code>cdk watch</code> in a terminal, which should show the following output.</p>\\n<p>Bash</p>\n<pre><code class=\\"lang-\\">'watch' is observing directory '' for changes\\n'watch' is observing the file 'cdk.context.json' for changes\\n'watch' is observing directory 'bin' for changes\\n'watch' is observing directory 'docker-app' for changes\\n'watch' is observing directory 'lib' for changes\\n'watch' is observing the file 'bin/cdk-watch.ts' for changes\\n'watch' is observing the file 'lib/cdk-watch-stack.ts' for changes\\n'watch' is observing the file 'docker-app/Dockerfile' for changes\\n'watch' is observing the file 'docker-app/index.html' for changes\\n'watch' is observing the file 'docker-app/package.json' for changes\\n'watch' is observing the file 'docker-app/webpage.ts' for changes\\n</code></pre>\\n<p>When making application code changes, <code>cdk watch</code> can speedup the deployment. To see it, make the following change to <code>index.html</code>.</p>\\n<p>HTML</p>\n<pre><code class=\\"lang-\\">&lt;!DOCTYPE html&gt;\\n\\n&lt;html lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;\\n&lt;head&gt;\\n &lt;meta charset=&quot;utf-8&quot;&gt;\\n &lt;title&gt; Simple Webpage &lt;/title&gt;\\n&lt;/head&gt;\\n\\n&lt;body&gt;\\n&lt;div align=&quot;center&quot;&gt;\\n &lt;h2&gt;Hello World&lt;/h2&gt;\\n &lt;hr width=&quot;25%&quot;&gt;\\n &lt;p&gt;A paragraph&lt;/p&gt;\\n&lt;/div&gt;\\n&lt;/body&gt;\\n&lt;/html&gt;\\n</code></pre>\\n<p>In the terminal you will see <code>cdk watch</code> deploy this change.</p>\\n<pre><code class=\\"lang-\\">Detected change to 'docker-app/index.html' (type: change). Triggering 'cdk deploy'\\n⚠️ The --hotswap flag deliberately introduces CloudFormation drift to speed up deployments\\n⚠️ It should only be used for development - never use it for your production Stacks!\\n</code></pre>\\n<p>The warning message lets you know that this change is being hotswapped. This means that this change is made by going directly to the service API that provides the resource(s) being updated, bypassing CloudFormation entirely. This introduces drift between your CloudFormation template and your deployed application code. Because of this drift, hotswapping should never be used in a production environment. Hotswap deployments are faster, but lack the robust safety features of CloudFormation deployments, making hotswap deployments ideal for performing rapid code-compile-test loops in your development environment. If you need to disable hotswapping while running <code>watch</code>, pass the <code>--no-hotswap</code> flag to <code>watch</code>. If you need to remove the drift between CloudFormation and your application entirely, simply perform a full CloudFormation deployment by executing <code>cdk deploy</code>. If you want to perform a hotswap deployment without running <code>cdk watch</code>, run <code>cdk deploy --hotswap</code>.</p>\\n<p>Once this change has been deployed, refresh the page. You should now see the following update to the Hello World page.</p>\n<p><img src=\\"https://dev-media.amazoncloud.cn/2aa9799c986f4293932aa078e5ecbd8a_image.png\\" alt=\\"image.png\\" /></p>\n<h3><a id=\\"Making_an_Infrastructure_Change_218\\"></a><strong>Making an Infrastructure Change</strong></h3>\\n<p>Not all resource changes can be hotswapped. Currently, only Lambda Function code changes, ECS Service container definition changes, and Step Functions state machine definition changes can be hotswapped. If any other changes are made, hotswap deployments will fall back to full CloudFormation deployments. To see this, make the following code change to <code>cdk-watch-stack.ts</code>.</p>\\n<p>TypeScript</p>\n<pre><code class=\\"lang-\\">import { \\n Stack,\\n StackProps,\\n aws_ec2 as ec2,\\n aws_ecs as ecs,\\n aws_ecs_patterns as ecs_patterns,\\n} from 'aws-cdk-lib';\\n\\nimport { Construct } from 'constructs';\\n\\nexport class CdkWatchStack extends Stack {\\n constructor(scope: Construct, id: string, props?: StackProps) {\\n super(scope, id, props);\\n\\n // Fargate does not work with default VPCs\\n const vpc = new ec2.Vpc(this, 'Vpc', {\\n maxAzs: 2, // ALB requires 2 AZs\\n natGateways: 2, //changing this property does not trigger a hotswap, and a full deployment occurs instead\\n });\\n\\n new ecs_patterns.ApplicationLoadBalancedFargateService(this, 'EcsService', {\\n vpc,\\n taskImageOptions: {\\n image: ecs.ContainerImage.fromAsset('docker-app'),\\n containerPort: 80,\\n },\\n });\\n }\\n}\\n</code></pre>\\n<p>Observe the terminal window. After the assets have finished publishing, you will see the following output.</p>\n<pre><code class=\\"lang-\\">Could not perform a hotswap deployment, as the stack CdkWatchStack contains non-Asset changes\\nFalling back to doing a full deployment\\n</code></pre>\\n<p>This means that the changes included a non-hotswappable change. Generally, changes to your application’s infrastructure are not hotswappable, while changes to assets used by your application are. This change increases the number of <code>natGateways</code> used by the <code>vpc</code>, so this is an infrastructure change and is therefore not hotswappable; thus, <code>watch</code> will fall back to performing a full CloudFormation deployment.</p>\\n<h3><a id=\\"Disabling_Rollback_264\\"></a><strong>Disabling Rollback</strong></h3>\\n<p>By default, <code>cdk watch</code> does not use <code>--no-rollback</code>. Before disabling rollback, enter the <code>^C</code> character (<code>control+c</code>) in the terminal window running cdk watch, and then run the <code>cdk deploy</code> command from your terminal.</p>\\n<pre><code class=\\"lang-\\">cdk deploy\\n</code></pre>\\n<p>The full deployment is performed first to make CloudFormation aware of the changes you made earlier. These changes are considered replacement type changes by CloudFormation, which do not support the <code>--no-rollback flag</code>, because they require the deletion and creation of one of the resources that make up the <code>ApplicationLoadBalancedFargateService</code>. Once the deployment finishes, run the following command.</p>\\n<pre><code class=\\"lang-\\">cdk watch --no-rollback\\n</code></pre>\\n<p>You should see the same output you did when you first ran <code>cdk watch</code>. Now make the following change to your stack:</p>\\n<p>TypeScript</p>\n<pre><code class=\\"lang-\\">import { \\n Stack,\\n StackProps,\\n aws_ec2 as ec2,\\n aws_ecs as ecs,\\n aws_ecs_patterns as ecs_patterns,\\n} from 'aws-cdk-lib';\\n\\nimport { Construct } from 'constructs';\\n\\nexport class CdkWatchStack extends Stack {\\n constructor(scope: Construct, id: string, props?: StackProps) {\\n super(scope, id, props);\\n\\n // Fargate does not work with default VPCs\\n const vpc = new ec2.Vpc(this, 'Vpc', {\\n maxAzs: 2, // ALB requires 2 AZs\\n natGateways: 2, \\n });\\n\\n new ec2.CfnVPC(this, 'mycfnvpc', { \\n cidrBlock: '10.0.0/16' //intentionally incorrect code\\n });\\n\\n new ecs_patterns.ApplicationLoadBalancedFargateService(this, 'EcsService', {\\n vpc,\\n taskImageOptions: {\\n image: ecs.ContainerImage.fromAsset('docker-app'),\\n containerPort: 80,\\n },\\n });\\n }\\n}\\n</code></pre>\\n<p>Note that this change specifies an invalid <code>cidrBlock</code>. The full deployment result is expected: this is an infrastructure change, so it is not hotswappable. As <code>cdk watch</code> is attempting the deployment, you will see the following error message.</p>\\n<pre><code class=\\"lang-\\">Could not perform a hotswap deployment, as the stack CdkWatchStack contains non-Asset changes\\nFalling back to doing a full deployment\\nCdkWatchStack: creating CloudFormation changeset...\\n3:17:02 PM | CREATE_FAILED | AWS::EC2::VPC | mycfnvpc\\nValue (10.0.0/16) for parameter cidrBlock is invalid. This is not a valid CIDR block. (Service: AmazonEC2; Status Code: 400; Error Code: InvalidParameterValue; Request ID: 4b670ce5-32bd-46dd-88de-33765f18d479; Proxy: null)\\n\\n❌ CdkWatchStack failed: Error: The stack named CdkWatchStack failed to deploy: UPDATE_FAILED (The following resource(s) failed to create: [mycfnvpc]. )\\nat Object.waitForStackDeploy (/usr/local/lib/node_modules/aws-cdk/lib/api/util/cloudformation.ts:309:11)\\nat processTicksAndRejections (internal/process/task_queues.js:95:5)\\nat prepareAndExecuteChangeSet (/usr/local/lib/node_modules/aws-cdk/lib/api/deploy-stack.ts:337:26)\\nat CdkToolkit.deploy (/usr/local/lib/node_modules/aws-cdk/lib/cdk-toolkit.ts:194:24)\\nat CdkToolkit.invokeDeployFromWatch (/usr/local/lib/node_modules/aws-cdk/lib/cdk-toolkit.ts:594:7)\\nat FSWatcher.&lt;anonymous&gt;(/usr/local/lib/node_modules/aws-cdk/lib/cdk-toolkit.ts:310:9)\\n</code></pre>\\n<p>Without <code>--no-rollback</code>, this change would be rolled back by CloudFormation. Now make this <code>cidrBlock</code> valid by making this change:</p>\\n<p>TypeScript</p>\n<pre><code class=\\"lang-\\">import { \\n Stack,\\n StackProps,\\n aws_ec2 as ec2,\\n aws_ecs as ecs,\\n aws_ecs_patterns as ecs_patterns,\\n} from 'aws-cdk-lib';\\n\\nimport { Construct } from 'constructs';\\n\\nexport class CdkWatchStack extends Stack {\\n constructor(scope: Construct, id: string, props?: StackProps) {\\n super(scope, id, props);\\n\\n // Fargate does not work with default VPCs\\n const vpc = new ec2.Vpc(this, 'Vpc', {\\n maxAzs: 2, // ALB requires 2 AZs\\n natGateways: 2, \\n });\\n \\n new ec2.CfnVPC(this, 'mycfnvpc', {\\n cidrBlock: '10.0.0.0/16' //corrected code \\n });\\n\\n new ecs_patterns.ApplicationLoadBalancedFargateService(this, 'EcsService', {\\n vpc,\\n taskImageOptions: {\\n image: ecs.ContainerImage.fromAsset('docker-app'),\\n containerPort: 80,\\n },\\n });\\n }\\n}\\n</code></pre>\\n<p><code>cdk watch</code> will detect this change and automatically successfully deploy it with the following output.</p>\\n<pre><code class=\\"lang-\\">Could not perform a hotswap deployment, as the stack CdkWatchStack contains non-Asset changes\\nFalling back to doing a full deployment\\nCdkWatchStack: creating CloudFormation changeset...\\n\\n\\n ✅ CdkWatchStack\\n\\nOutputs:\\nCdkWatchStack.EcsServiceLoadBalancerDNS6D595ACE = CdkWa-EcsSe-T2ZOAGRO8LGP-297129573.us-east-2.elb.amazonaws.com\\nCdkWatchStack.EcsServiceServiceURLE56F060F = http://CdkWa-EcsSe-T2ZOAGRO8LGP-297129573.us-east-2.elb.amazonaws.com\\n\\nStack ARN:\\narn:aws:cloudformation:us-east-2:131099214097:stack/CdkWatchStack/95d784f0-4d73-11ec-a8b8-062cd5cc0070\\n</code></pre>\\n<h3><a id=\\"Cleaning_up_390\\"></a><strong>Cleaning up</strong></h3>\\n<p>To delete the stack and application that you just deployed, run the <code>cdk destroy</code> command in your CDK project’s root directory.</p>\\n<pre><code class=\\"lang-\\">cdk destroy\\n</code></pre>\\n<h3><a id=\\"Summary_397\\"></a><strong>Summary</strong></h3>\\n<p><code>cdk watch</code> allows you to make more rapid updates to your development stacks by leveraging hotswapping, where possible, to bypass CloudFormation. Not all resource changes can be hotswapped; if a hotswap deployment cannot be performed, <code>watch</code> will fall back to a full CloudFormation deployment. Due to the intentional drift introduced by hotswapping, it should never be used in a production environment. If desired, hotswapping can be turned off by passing the <code>--no-hotswap</code> flag. <code>cdk watch</code> can be invoked with the <code>--no-rollback</code> flag to disable rollback of failed updates, but any updates that CloudFormation considers as replacement type updates are not affected by this flag.</p>\n"}
目录
亚马逊云科技解决方案 基于行业客户应用场景及技术领域的解决方案
联系亚马逊云科技专家
亚马逊云科技解决方案
基于行业客户应用场景及技术领域的解决方案
联系专家
0
目录
关闭