Deployment Projects with the new Amazon .NET Deployment Experience

海外精选
海外精选的内容汇集了全球优质的亚马逊云科技相关技术内容。同时,内容中提到的“AWS” 是 “Amazon Web Services” 的缩写,在此网站不作为商标展示。
0
0
{"value":"In the [last post](https://aws.amazon.com/blogs/developer/update-new-net-deployment-experience/) about our new [AWS .NET Deployment tooling](https://aws.amazon.com/blogs/developer/reimagining-the-aws-net-deployment-experience/) I talked about some of the recent updates we have made. I did skip a very important feature called deployment projects because I thought it deserved it’s own post.\n\nA major goal with the new deployment tooling is not to have unseen magic happening under the covers. We want the experience to be as simple as possible but easily allow users to see what is happening if they choose. This also allows users to customize the deployment to match their exact need.\n\nWith deployment projects you can add additional AWS resources like [Amazon SQS](https://aws.amazon.com/sqs/) queues, [Amazon DynamoDB](https://aws.amazon.com/dynamodb/) tables, and more, as part of the deployment. You can also add your company’s requirements for deployments and share the project with other teams.\n\n### **What is a deployment project?**\n\nThe deployment tool contains a collection of what we call recipes. The tool turns these recipes into recommendations for a given .NET project. A recipe contains a JSON file holding all of the metadata the tool uses to drive the experience. This includes rules used in the recommendation engine to determine if the recipe is compatible with a project. It also has all of the settings that the deploy tool CLI, and eventually Visual Studio, uses to allow users to customize the experience.\n\nIn addition to the metadata file a recipe contains a .NET project template that uses the [AWS Cloud Development Kit (CDK)](https://aws.amazon.com/cdk/). The project takes the collected settings from the user and performs the deployment using the CDK. For simple deployments where you don’t want to further customize resources, you can feel free to ignore the CDK project.\n\nA deployment project is where you can take things to the next level and start adding additional resources or custom requirements. The tooling examines your project and generates a deployment project in your workspace. This deployment project will include the recipe’s JSON definition file and the related .NET CDK project. You can customize this project, or leave it as-is. When you want to deploy, instead of choosing one of the recipes supplied by AWS, you can choose your custom deployment project.\n\n### **Creating a deployment project**\n\nTo demonstrate how deployment projects can be helpful I have a web application that uses an Amazon DynamoDB table for its datastore. The normal deployment, using built-in recipes from AWS, will take care of creating the infrastructure resources but here I also want my DynamoDB table to be created during deployment. Deployment projects to the rescue!\n\nTo create a deployment project for the application, I run the following command in the web application’s project directory.\n\nBash\n```\ndotnet aws deployment-project generate\n```\nThe command will display a list of recommendations that are compatible with the project. This is very similar to what you would see when deploying but now, when select an option, the command generates a deployment project instead.\n\n![image.png](https://dev-media.amazoncloud.cn/be24b4d2d6464f9b9f9ca4cc62b4e1b6_image.png)\n\nI’m going to stay with the recommended option and choose option 1, to use [Amazon Elastic Container Service (ECS)](https://aws.amazon.com/ecs/) for my application. By default the deployment project will be created in a sibling directory from the project directory, with the ```.Deployment``` suffix. If you want the deployment project to be created in a different location you can use the ```--output``` switch.\n\nNow that I have a deployment project, when I start a deployment by running ```dotnet aws deploy``` in the project directory, the recommended deployment option is the new deployment project. The original recommended option, ASP.NET Core App to Amazon ECS using Fargate, is now listed in additional options.\n\n![image.png](https://dev-media.amazoncloud.cn/62c3c45aa8524bed802ed78b3ed48e57_image.png)\n\nYou can customize the name that shows up here by using the ```--project-display-name``` switch when creating the project. You can also edit the name in the deployment project, which I will show later.\n\nI want to customize the deployment project before deploying, to add my DynamoDB table, so I use Ctrl+C to exit out of the tool without deploying.\n\n\n### **Examine the deployment project**\n\nLet’s take a look at the deployment project, which is a .NET project that I added to my solution. It’s a standard C# console project that uses NuGet packages containing CDK construct types to define the AWS infrastructure needed by my application.\n\n![image.png](https://dev-media.amazoncloud.cn/1c3ae955f10943b2be4506b3744acdff_image.png)\n\n\nWhen you are working with a deployment project you are in charge of maintaining the project going forward, and are welcome to change it however you need to. Most of the meaningful code the deployment tool provides is in the generated folder. We don’t recommend you edit the files in there directly, and instead use it for reference. Then, if you want to take updates from the original recipe the deployment project was created from, you can just copy the code into the generated folder.\n\nThe ```AppStack``` class is the recommended place to add new AWS resources or customize the resources created in the generated code.\n\nAlso in the deployment project you’ll find the recipe definition file. This is the file with the ```.recipe``` extension. As I noted earlier, the recipe file contains the metadata that the deployment tooling uses to evaluate project compatibility, and the settings that are configurable in the tooling.\n\n### **Adding a DynamoDB table**\n\nBefore adding our table to the deployment project let’s take a look at the constructor of the ```AppStack``` class. There are 3 important things happening in this constructor.\n\n1. The ```_configuration``` field is set. This contains all of the settings the user made while configuring deployment in the CLI and eventually Visual Studio.\n2. A callback is added to the ```CustomizeCDKProps``` event. This callback allows you to customize the AWS resources created from the original recipe.\n3. The original recipe’s construct is created, containing all of AWS resources for deploying the application.\n\nC#\n\n```\ninternal AppStack(Construct scope, IDeployToolStackProps<Configuration> props)\n : base(scope, props.StackName, props)\n{\n _configuration = props.RecipeProps.Settings;\n\n // Setup callback for generated construct to provide access\n // to customize CDK properties before creating constructs.\n CDKRecipeCustomizer<Recipe>.CustomizeCDKProps += CustomizeCDKProps;\n\n // Create custom CDK constructs here that might need to be referenced\n // in the CustomizeCDKProps. For example, if creating a DynamoDB table\n // construct and then later using the CDK construct reference in\n // CustomizeCDKProps to pass the table name as an environment variable\n // to the container image.\n\n // Create the recipe defined CDK construct with all of its sub constructs.\n var generatedRecipe = new Recipe(this, props.RecipeProps);\n\n // Create additional CDK constructs here. The recipe's constructs can be\n // accessed as properties on the generatedRecipe variable.\n}\n```\n\nTo get started adding a DynamoDB table to the deployment project we first need to add the ```Amazon.CDK.AWS.DynamoDB ```NuGet package. When working with CDK NuGet packages it is important to keep the version number of all of the NuGet packages the same. So, before adding the package, check the project’s csproj file to see what version number is being referenced for the other CDK packages. You can also choose to update all of the references to the latest CDK version.\n\n***Note:** V2 of the CDK, which contains simplified package management, is currently in development *\n\nWith the package included in the project I can add the CDK code to create the table. When adding resources that need references to the resources that were created as part of the original recipe, add the code after the ```new Recipe(..)``` line. The resources created by the original recipe will be accessible as public properties on the ```generatedRecipe``` object. Since my table is not dependent on any of the resources created by the original recipe I’m going to add my code before calling ```new Recipe(..)```.\n\nC#\n\n```\nprivate Table? _backendDataStore;\n\ninternal AppStack(Construct scope, IDeployToolStackProps<Configuration> props)\n : base(scope, props.StackName, props)\n{\n _configuration = props.RecipeProps.Settings;\n CDKRecipeCustomizer<Recipe>.CustomizeCDKProps += CustomizeCDKProps;\n\n var backendDataStoreProps = new TableProps\n {\n RemovalPolicy = RemovalPolicy.RETAIN,\n PartitionKey = new Amazon.CDK.AWS.DynamoDB.Attribute\n {\n Name = \"Id\",\n Type = AttributeType.STRING\n },\n BillingMode = BillingMode.PAY_PER_REQUEST,\n };\n _backendDataStore = new Table(this, \"BackendDataStore\", backendDataStoreProps);\n\n _backendDataStore.AddGlobalSecondaryIndex(new GlobalSecondaryIndexProps\n {\n IndexName = \"Name\",\n PartitionKey = new Amazon.CDK.AWS.DynamoDB.Attribute\n {\n Name = \"Name\",\n Type = AttributeType.STRING\n },\n ProjectionType = ProjectionType.ALL\n });\n\n var generatedRecipe = new Recipe(this, props.RecipeProps);\n}\n```\n\nWhen I now deploy the application with this deployment project I will have my table created as part of the deployment.\n\n### **Customizing recipe resources**\n\nIn the previous section we saw how to add a new DynamoDB table to my deployment. Now that we have our table we need to inform our deployed application what table to use. This is where the ```CustomizeCDKProps``` callback method comes into play.\n\nWhen a CDK construct is created it accepts a ```props``` object containing all of the settings for the construct, just like we saw above for the DynamoDB table. The ```Recipe``` class in the deployment project creates many props objects and constructs. Once the props object is fully created, but before the construct is created, the ```CustomizeCDKProps``` callback is invoked. This allows our customization a chance to alter the properties for the construct before it is created.\n\nThe callback event contains the resource’s logical name, used inside the CDK code. You inspect the name to see if this is the resource you want to customize. The pattern we use when writing the recipe is to make the resource’s logical name the same as the public property on the recipe construct. So you can use the ```nameof``` operator to do the comparison.\n\nFor this example I want to customize creation of the application container definition to set an environment variable to the name of my table.\n\nC#\n\n```\nprivate void CustomizeCDKProps(CustomizePropsEventArgs<Recipe> evnt)\n{\n if (string.Equals(evnt.ResourceLogicalName, nameof(evnt.Construct.AppContainerDefinition)))\n {\n if (evnt.Props is ContainerDefinitionOptions props && _backendDataStore != null)\n {\n Console.WriteLine(\"Customizing AppContainerDefinition\");\n if (props.Environment == null)\n props.Environment = new Dictionary<string, string>();\n\n props.Environment[\"AwsAppResources__BackendTable\"] = _backendDataStore.TableName;\n }\n }\n}\n```\n\n***Note:** I use the [double underscores](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/#environment-variables-1) in the environment name to match the JSON nesting I used in appsettings.Development.json *\n\n\n### **Customizing recipe definitions**\n\nWith a deployment project you can also customize the experience of using the project inside the deploy tool CLI, and soon Visual Studio. This is done by editing the recipe definition file in the deployment project.\n\nCustomizing the recipe definition is really useful when you are sharing your deployment project across team members and other teams. This allows others to use your project but easily customize it for their specific environment.\n\n#### **Customizing name and description**\n\nLet’s start with giving the deployment project a more meaningful name and description. At the start of the file are the ```Name```, ```Description```, and ```ShortDescription``` fields. The tooling uses these to display the recipe.\n\nJSON\n\n```\n{\n \"Id\": \"c3835c75-41b6-455c-b77d-8a0c80585a01\",\n \"Version\": \"1.0.0\",\n \"Name\": \"Demo Application with DynamoDB Backend\",\n \"Description\": \"This application will be deployed to ECS with its DynamoDB table backend.\",\n \"ShortDescription\": \"This application will be deployed to ECS with its DynamoDB table backend.\",\n...\n```\n\nNow, when I run ```dotnet aws deploy```, the interface shows my customized name and description.\n\n![image.png](https://dev-media.amazoncloud.cn/86fad76dbd4f4fe381fb33a87324c600_image.png)\n\n#### **Customizing settings**\n\nDeployment projects enable you to change the interface beyond just name and description. You can also add new settings that will be presented to the user during deployment.\n\nFor example, when I added my DynamoDB table to the CDK project I set the ```RemovalPolicy``` to ```RemovalPolicy.RETAIN```. That way, if I delete my deployment, I retain any data that was added to the table. That is good practice for more production-like deployments. But for development I don’t care about the data, and want the table deleted when I delete the deployment.\n\nThe recipe definition file contains an array of settings in the ```OptionSettings``` section. I’m going to add a new setting called ```RetainTable```. The setting entry has the following properties.\n\n\n- Id – The unique id of the setting\n- Name – The name presented to the user when deploying the application\n- Description – The description presented to the user when deploying the application\n- Type – The data type of the setting. In this case```Bool```.\n- DefaultValue – The default value for new deployments.\n- AdvancedSetting – Controls whether the setting is shown to the user by default.\n- Updatable – Controls whether the setting can be updated during redeployments.\n\nJSON\n\n```\n\"OptionSettings\": [\n...\n {\n \"Id\": \"RetainTable\",\n \"Name\": \"Retain Backend Table\",\n \"Description\": \"If true the DynamoDB backend table will be preserved when the deployment is deleted.\",\n \"Type\": \"Bool\",\n \"DefaultValue\": true,\n \"AdvancedSetting\": false,\n \"Updatable\": true\n },\n...\n]\n```\nNow that I’ve added my setting I need the CDK code to honor it. The first thing I need to do is model the setting in the CDK project. Using .NET’s configuration framework all of the settings collected from the deploy tool are deserialized into the Configuration class inside the CDK project. The Configuration class is defined as a **partial** class to separate the recipe’s original settings from those added as part of customization.\n\nIn the **Configuration.cs** file in the **Configuration **folder I add a new property, using the same Id that I used in the recipe definition file.\n\nC#\n\n```\npublic partial class Configuration\n{\n public bool RetainTable { get; set; } = true;\n}\n```\n\nReturning to the code where the DynamoDB table is created, I can check the ```_configuration.RetainTable property``` for determining the ```RemovalPolicy```.\n\nC#\n\n```\nvar backendDataStoreProps = new TableProps\n{\n RemovalPolicy = _configuration.RetainTable ? RemovalPolicy.RETAIN : RemovalPolicy.DESTROY,\n\n PartitionKey = new Amazon.CDK.AWS.DynamoDB.Attribute\n {\n Name = \"Id\",\n Type = AttributeType.STRING\n },\n BillingMode = BillingMode.PAY_PER_REQUEST,\n};\n_backendDataStore = new Table(this, \"BackendDataStore\", backendDataStoreProps);\n```\n\nI have now defined a new setting to present to the user, and used that setting to control the logic of how to create the AWS resources. When anybody on my team runs the deployment project they will have the ability to configure the ```RemovalPolicy```.\n\n![image.png](https://dev-media.amazoncloud.cn/b053e0f56b9e4b8ca343d7a637a00036_image.png)\n\n\n### **Sharing Deployment Projects**\n\nThe intention of deployment projects is for them to be checked into source control and be shared with the rest of your team. You can even reuse a deployment project for multiple applications you want to deploy. By default, when you invoke the ```dotnet aws deploy``` command the tooling looks for all deployment projects under the directory where the solution file is at, or the root of the Git repository. If you have a deployment project you want to use but it’s in a separate workspace, possibly a separate repository, then when you invoke the ```dotnet aws deploy``` command use the ```--deployment-project``` switch to pass in the path of the shared deployment project.\n\n\n### **Wrap up**\n\nIn this post I demonstrated a very simple example of how to use the new deployment projects feature to customize deploying .NET applications with the new deployment tool. You can use this feature to make much more advanced customization to match your team or company requirement. For example, you could add side car containers, add DNS entries for [Amazon Route 53](https://aws.amazon.com/route53/), or standardize VPC settings across all deployments. Give it a try and let us know what you think on [GitHub](https://github.com/aws/aws-dotnet-deploy), where you can follow all the latest developments.","render":"<p>In the <a href=\"https://aws.amazon.com/blogs/developer/update-new-net-deployment-experience/\" target=\"_blank\">last post</a> about our new <a href=\"https://aws.amazon.com/blogs/developer/reimagining-the-aws-net-deployment-experience/\" target=\"_blank\">AWS .NET Deployment tooling</a> I talked about some of the recent updates we have made. I did skip a very important feature called deployment projects because I thought it deserved it’s own post.</p>\n<p>A major goal with the new deployment tooling is not to have unseen magic happening under the covers. We want the experience to be as simple as possible but easily allow users to see what is happening if they choose. This also allows users to customize the deployment to match their exact need.</p>\n<p>With deployment projects you can add additional AWS resources like <a href=\"https://aws.amazon.com/sqs/\" target=\"_blank\">Amazon SQS</a> queues, <a href=\"https://aws.amazon.com/dynamodb/\" target=\"_blank\">Amazon DynamoDB</a> tables, and more, as part of the deployment. You can also add your company’s requirements for deployments and share the project with other teams.</p>\n<h3><a id=\"What_is_a_deployment_project_6\"></a><strong>What is a deployment project?</strong></h3>\n<p>The deployment tool contains a collection of what we call recipes. The tool turns these recipes into recommendations for a given .NET project. A recipe contains a JSON file holding all of the metadata the tool uses to drive the experience. This includes rules used in the recommendation engine to determine if the recipe is compatible with a project. It also has all of the settings that the deploy tool CLI, and eventually Visual Studio, uses to allow users to customize the experience.</p>\n<p>In addition to the metadata file a recipe contains a .NET project template that uses the <a href=\"https://aws.amazon.com/cdk/\" target=\"_blank\">AWS Cloud Development Kit (CDK)</a>. The project takes the collected settings from the user and performs the deployment using the CDK. For simple deployments where you don’t want to further customize resources, you can feel free to ignore the CDK project.</p>\n<p>A deployment project is where you can take things to the next level and start adding additional resources or custom requirements. The tooling examines your project and generates a deployment project in your workspace. This deployment project will include the recipe’s JSON definition file and the related .NET CDK project. You can customize this project, or leave it as-is. When you want to deploy, instead of choosing one of the recipes supplied by AWS, you can choose your custom deployment project.</p>\n<h3><a id=\"Creating_a_deployment_project_14\"></a><strong>Creating a deployment project</strong></h3>\n<p>To demonstrate how deployment projects can be helpful I have a web application that uses an Amazon DynamoDB table for its datastore. The normal deployment, using built-in recipes from AWS, will take care of creating the infrastructure resources but here I also want my DynamoDB table to be created during deployment. Deployment projects to the rescue!</p>\n<p>To create a deployment project for the application, I run the following command in the web application’s project directory.</p>\n<p>Bash</p>\n<pre><code class=\"lang-\">dotnet aws deployment-project generate\n</code></pre>\n<p>The command will display a list of recommendations that are compatible with the project. This is very similar to what you would see when deploying but now, when select an option, the command generates a deployment project instead.</p>\n<p><img src=\"https://dev-media.amazoncloud.cn/be24b4d2d6464f9b9f9ca4cc62b4e1b6_image.png\" alt=\"image.png\" /></p>\n<p>I’m going to stay with the recommended option and choose option 1, to use <a href=\"https://aws.amazon.com/ecs/\" target=\"_blank\">Amazon Elastic Container Service (ECS)</a> for my application. By default the deployment project will be created in a sibling directory from the project directory, with the <code>.Deployment</code> suffix. If you want the deployment project to be created in a different location you can use the <code>--output</code> switch.</p>\n<p>Now that I have a deployment project, when I start a deployment by running <code>dotnet aws deploy</code> in the project directory, the recommended deployment option is the new deployment project. The original recommended option, ASP.NET Core App to Amazon ECS using Fargate, is now listed in additional options.</p>\n<p><img src=\"https://dev-media.amazoncloud.cn/62c3c45aa8524bed802ed78b3ed48e57_image.png\" alt=\"image.png\" /></p>\n<p>You can customize the name that shows up here by using the <code>--project-display-name</code> switch when creating the project. You can also edit the name in the deployment project, which I will show later.</p>\n<p>I want to customize the deployment project before deploying, to add my DynamoDB table, so I use Ctrl+C to exit out of the tool without deploying.</p>\n<h3><a id=\"Examine_the_deployment_project_39\"></a><strong>Examine the deployment project</strong></h3>\n<p>Let’s take a look at the deployment project, which is a .NET project that I added to my solution. It’s a standard C# console project that uses NuGet packages containing CDK construct types to define the AWS infrastructure needed by my application.</p>\n<p><img src=\"https://dev-media.amazoncloud.cn/1c3ae955f10943b2be4506b3744acdff_image.png\" alt=\"image.png\" /></p>\n<p>When you are working with a deployment project you are in charge of maintaining the project going forward, and are welcome to change it however you need to. Most of the meaningful code the deployment tool provides is in the generated folder. We don’t recommend you edit the files in there directly, and instead use it for reference. Then, if you want to take updates from the original recipe the deployment project was created from, you can just copy the code into the generated folder.</p>\n<p>The <code>AppStack</code> class is the recommended place to add new AWS resources or customize the resources created in the generated code.</p>\n<p>Also in the deployment project you’ll find the recipe definition file. This is the file with the <code>.recipe</code> extension. As I noted earlier, the recipe file contains the metadata that the deployment tooling uses to evaluate project compatibility, and the settings that are configurable in the tooling.</p>\n<h3><a id=\"Adding_a_DynamoDB_table_52\"></a><strong>Adding a DynamoDB table</strong></h3>\n<p>Before adding our table to the deployment project let’s take a look at the constructor of the <code>AppStack</code> class. There are 3 important things happening in this constructor.</p>\n<ol>\n<li>The <code>_configuration</code> field is set. This contains all of the settings the user made while configuring deployment in the CLI and eventually Visual Studio.</li>\n<li>A callback is added to the <code>CustomizeCDKProps</code> event. This callback allows you to customize the AWS resources created from the original recipe.</li>\n<li>The original recipe’s construct is created, containing all of AWS resources for deploying the application.</li>\n</ol>\n<p>C#</p>\n<pre><code class=\"lang-\">internal AppStack(Construct scope, IDeployToolStackProps&lt;Configuration&gt; props)\n : base(scope, props.StackName, props)\n{\n _configuration = props.RecipeProps.Settings;\n\n // Setup callback for generated construct to provide access\n // to customize CDK properties before creating constructs.\n CDKRecipeCustomizer&lt;Recipe&gt;.CustomizeCDKProps += CustomizeCDKProps;\n\n // Create custom CDK constructs here that might need to be referenced\n // in the CustomizeCDKProps. For example, if creating a DynamoDB table\n // construct and then later using the CDK construct reference in\n // CustomizeCDKProps to pass the table name as an environment variable\n // to the container image.\n\n // Create the recipe defined CDK construct with all of its sub constructs.\n var generatedRecipe = new Recipe(this, props.RecipeProps);\n\n // Create additional CDK constructs here. The recipe's constructs can be\n // accessed as properties on the generatedRecipe variable.\n}\n</code></pre>\n<p>To get started adding a DynamoDB table to the deployment project we first need to add the <code>Amazon.CDK.AWS.DynamoDB </code>NuGet package. When working with CDK NuGet packages it is important to keep the version number of all of the NuGet packages the same. So, before adding the package, check the project’s csproj file to see what version number is being referenced for the other CDK packages. You can also choose to update all of the references to the latest CDK version.</p>\n<p>*<strong>Note:</strong> V2 of the CDK, which contains simplified package management, is currently in development *</p>\n<p>With the package included in the project I can add the CDK code to create the table. When adding resources that need references to the resources that were created as part of the original recipe, add the code after the <code>new Recipe(..)</code> line. The resources created by the original recipe will be accessible as public properties on the <code>generatedRecipe</code> object. Since my table is not dependent on any of the resources created by the original recipe I’m going to add my code before calling <code>new Recipe(..)</code>.</p>\n<p>C#</p>\n<pre><code class=\"lang-\">private Table? _backendDataStore;\n\ninternal AppStack(Construct scope, IDeployToolStackProps&lt;Configuration&gt; props)\n : base(scope, props.StackName, props)\n{\n _configuration = props.RecipeProps.Settings;\n CDKRecipeCustomizer&lt;Recipe&gt;.CustomizeCDKProps += CustomizeCDKProps;\n\n var backendDataStoreProps = new TableProps\n {\n RemovalPolicy = RemovalPolicy.RETAIN,\n PartitionKey = new Amazon.CDK.AWS.DynamoDB.Attribute\n {\n Name = &quot;Id&quot;,\n Type = AttributeType.STRING\n },\n BillingMode = BillingMode.PAY_PER_REQUEST,\n };\n _backendDataStore = new Table(this, &quot;BackendDataStore&quot;, backendDataStoreProps);\n\n _backendDataStore.AddGlobalSecondaryIndex(new GlobalSecondaryIndexProps\n {\n IndexName = &quot;Name&quot;,\n PartitionKey = new Amazon.CDK.AWS.DynamoDB.Attribute\n {\n Name = &quot;Name&quot;,\n Type = AttributeType.STRING\n },\n ProjectionType = ProjectionType.ALL\n });\n\n var generatedRecipe = new Recipe(this, props.RecipeProps);\n}\n</code></pre>\n<p>When I now deploy the application with this deployment project I will have my table created as part of the deployment.</p>\n<h3><a id=\"Customizing_recipe_resources_132\"></a><strong>Customizing recipe resources</strong></h3>\n<p>In the previous section we saw how to add a new DynamoDB table to my deployment. Now that we have our table we need to inform our deployed application what table to use. This is where the <code>CustomizeCDKProps</code> callback method comes into play.</p>\n<p>When a CDK construct is created it accepts a <code>props</code> object containing all of the settings for the construct, just like we saw above for the DynamoDB table. The <code>Recipe</code> class in the deployment project creates many props objects and constructs. Once the props object is fully created, but before the construct is created, the <code>CustomizeCDKProps</code> callback is invoked. This allows our customization a chance to alter the properties for the construct before it is created.</p>\n<p>The callback event contains the resource’s logical name, used inside the CDK code. You inspect the name to see if this is the resource you want to customize. The pattern we use when writing the recipe is to make the resource’s logical name the same as the public property on the recipe construct. So you can use the <code>nameof</code> operator to do the comparison.</p>\n<p>For this example I want to customize creation of the application container definition to set an environment variable to the name of my table.</p>\n<p>C#</p>\n<pre><code class=\"lang-\">private void CustomizeCDKProps(CustomizePropsEventArgs&lt;Recipe&gt; evnt)\n{\n if (string.Equals(evnt.ResourceLogicalName, nameof(evnt.Construct.AppContainerDefinition)))\n {\n if (evnt.Props is ContainerDefinitionOptions props &amp;&amp; _backendDataStore != null)\n {\n Console.WriteLine(&quot;Customizing AppContainerDefinition&quot;);\n if (props.Environment == null)\n props.Environment = new Dictionary&lt;string, string&gt;();\n\n props.Environment[&quot;AwsAppResources__BackendTable&quot;] = _backendDataStore.TableName;\n }\n }\n}\n</code></pre>\n<p>*<strong>Note:</strong> I use the <a href=\"https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/#environment-variables-1\" target=\"_blank\">double underscores</a> in the environment name to match the JSON nesting I used in appsettings.Development.json *</p>\n<h3><a id=\"Customizing_recipe_definitions_164\"></a><strong>Customizing recipe definitions</strong></h3>\n<p>With a deployment project you can also customize the experience of using the project inside the deploy tool CLI, and soon Visual Studio. This is done by editing the recipe definition file in the deployment project.</p>\n<p>Customizing the recipe definition is really useful when you are sharing your deployment project across team members and other teams. This allows others to use your project but easily customize it for their specific environment.</p>\n<h4><a id=\"Customizing_name_and_description_170\"></a><strong>Customizing name and description</strong></h4>\n<p>Let’s start with giving the deployment project a more meaningful name and description. At the start of the file are the <code>Name</code>, <code>Description</code>, and <code>ShortDescription</code> fields. The tooling uses these to display the recipe.</p>\n<p>JSON</p>\n<pre><code class=\"lang-\">{\n &quot;Id&quot;: &quot;c3835c75-41b6-455c-b77d-8a0c80585a01&quot;,\n &quot;Version&quot;: &quot;1.0.0&quot;,\n &quot;Name&quot;: &quot;Demo Application with DynamoDB Backend&quot;,\n &quot;Description&quot;: &quot;This application will be deployed to ECS with its DynamoDB table backend.&quot;,\n &quot;ShortDescription&quot;: &quot;This application will be deployed to ECS with its DynamoDB table backend.&quot;,\n...\n</code></pre>\n<p>Now, when I run <code>dotnet aws deploy</code>, the interface shows my customized name and description.</p>\n<p><img src=\"https://dev-media.amazoncloud.cn/86fad76dbd4f4fe381fb33a87324c600_image.png\" alt=\"image.png\" /></p>\n<h4><a id=\"Customizing_settings_190\"></a><strong>Customizing settings</strong></h4>\n<p>Deployment projects enable you to change the interface beyond just name and description. You can also add new settings that will be presented to the user during deployment.</p>\n<p>For example, when I added my DynamoDB table to the CDK project I set the <code>RemovalPolicy</code> to <code>RemovalPolicy.RETAIN</code>. That way, if I delete my deployment, I retain any data that was added to the table. That is good practice for more production-like deployments. But for development I don’t care about the data, and want the table deleted when I delete the deployment.</p>\n<p>The recipe definition file contains an array of settings in the <code>OptionSettings</code> section. I’m going to add a new setting called <code>RetainTable</code>. The setting entry has the following properties.</p>\n<ul>\n<li>Id – The unique id of the setting</li>\n<li>Name – The name presented to the user when deploying the application</li>\n<li>Description – The description presented to the user when deploying the application</li>\n<li>Type – The data type of the setting. In this case<code>Bool</code>.</li>\n<li>DefaultValue – The default value for new deployments.</li>\n<li>AdvancedSetting – Controls whether the setting is shown to the user by default.</li>\n<li>Updatable – Controls whether the setting can be updated during redeployments.</li>\n</ul>\n<p>JSON</p>\n<pre><code class=\"lang-\">&quot;OptionSettings&quot;: [\n...\n {\n &quot;Id&quot;: &quot;RetainTable&quot;,\n &quot;Name&quot;: &quot;Retain Backend Table&quot;,\n &quot;Description&quot;: &quot;If true the DynamoDB backend table will be preserved when the deployment is deleted.&quot;,\n &quot;Type&quot;: &quot;Bool&quot;,\n &quot;DefaultValue&quot;: true,\n &quot;AdvancedSetting&quot;: false,\n &quot;Updatable&quot;: true\n },\n...\n]\n</code></pre>\n<p>Now that I’ve added my setting I need the CDK code to honor it. The first thing I need to do is model the setting in the CDK project. Using .NET’s configuration framework all of the settings collected from the deploy tool are deserialized into the Configuration class inside the CDK project. The Configuration class is defined as a <strong>partial</strong> class to separate the recipe’s original settings from those added as part of customization.</p>\n<p>In the <strong>Configuration.cs</strong> file in the **Configuration **folder I add a new property, using the same Id that I used in the recipe definition file.</p>\n<p>C#</p>\n<pre><code class=\"lang-\">public partial class Configuration\n{\n public bool RetainTable { get; set; } = true;\n}\n</code></pre>\n<p>Returning to the code where the DynamoDB table is created, I can check the <code>_configuration.RetainTable property</code> for determining the <code>RemovalPolicy</code>.</p>\n<p>C#</p>\n<pre><code class=\"lang-\">var backendDataStoreProps = new TableProps\n{\n RemovalPolicy = _configuration.RetainTable ? RemovalPolicy.RETAIN : RemovalPolicy.DESTROY,\n\n PartitionKey = new Amazon.CDK.AWS.DynamoDB.Attribute\n {\n Name = &quot;Id&quot;,\n Type = AttributeType.STRING\n },\n BillingMode = BillingMode.PAY_PER_REQUEST,\n};\n_backendDataStore = new Table(this, &quot;BackendDataStore&quot;, backendDataStoreProps);\n</code></pre>\n<p>I have now defined a new setting to present to the user, and used that setting to control the logic of how to create the AWS resources. When anybody on my team runs the deployment project they will have the ability to configure the <code>RemovalPolicy</code>.</p>\n<p><img src=\"https://dev-media.amazoncloud.cn/b053e0f56b9e4b8ca343d7a637a00036_image.png\" alt=\"image.png\" /></p>\n<h3><a id=\"Sharing_Deployment_Projects_261\"></a><strong>Sharing Deployment Projects</strong></h3>\n<p>The intention of deployment projects is for them to be checked into source control and be shared with the rest of your team. You can even reuse a deployment project for multiple applications you want to deploy. By default, when you invoke the <code>dotnet aws deploy</code> command the tooling looks for all deployment projects under the directory where the solution file is at, or the root of the Git repository. If you have a deployment project you want to use but it’s in a separate workspace, possibly a separate repository, then when you invoke the <code>dotnet aws deploy</code> command use the <code>--deployment-project</code> switch to pass in the path of the shared deployment project.</p>\n<h3><a id=\"Wrap_up_266\"></a><strong>Wrap up</strong></h3>\n<p>In this post I demonstrated a very simple example of how to use the new deployment projects feature to customize deploying .NET applications with the new deployment tool. You can use this feature to make much more advanced customization to match your team or company requirement. For example, you could add side car containers, add DNS entries for <a href=\"https://aws.amazon.com/route53/\" target=\"_blank\">Amazon Route 53</a>, or standardize VPC settings across all deployments. Give it a try and let us know what you think on <a href=\"https://github.com/aws/aws-dotnet-deploy\" target=\"_blank\">GitHub</a>, where you can follow all the latest developments.</p>\n"}
目录
亚马逊云科技解决方案 基于行业客户应用场景及技术领域的解决方案
联系亚马逊云科技专家
亚马逊云科技解决方案
基于行业客户应用场景及技术领域的解决方案
联系专家
0
目录
关闭