using System;
using System.Collections.Generic;
using System.IO;
using System.Text.Json;
using Microsoft.Extensions.Configuration;
using Amazon.CDK;
using System.Text.Json.Serialization;
namespace AWS.Deploy.Recipes.CDK.Common
{
///
/// This class contains methods for setting up a CDK stack to be managed by the AWS .NET deployment tool.
///
public static class CDKRecipeSetup
{
///
/// Tags the stack to identify it as an AWS .NET deployment tool Clould Application. Appropriate metadata as also applied to the generated
/// template to identify the recipe used as well as the last AWS .NET deployment tool settings. This is required to support the
/// AWS .NET deployment tool to be able to redeploy new versions of the application to AWS.
///
/// The configuration type defined as part of the recipe that contains all of the recipe specific settings.
///
///
public static void RegisterStack(Stack stack, IRecipeProps recipeConfiguration)
{
// Set the AWS .NET deployment tool tag which also identifies the recipe used.
stack.Tags.SetTag(Constants.CloudFormationIdentifier.STACK_TAG, $"{recipeConfiguration.RecipeId}");
// Serializes all AWS .NET deployment tool settings.
var recipeSettingsJson = JsonSerializer.Serialize(
recipeConfiguration.Settings,
new JsonSerializerOptions
{
WriteIndented = false,
Converters = { new JsonStringEnumConverter() }
});
Dictionary metadata;
if(stack.TemplateOptions.Metadata?.Count > 0)
{
metadata = new Dictionary(stack.TemplateOptions.Metadata);
}
else
{
metadata = new Dictionary();
}
// Save the settings, recipe id and version as metadata to the CloudFormation template.
metadata[Constants.CloudFormationIdentifier.STACK_METADATA_SETTINGS] = recipeSettingsJson;
metadata[Constants.CloudFormationIdentifier.STACK_METADATA_RECIPE_ID] = recipeConfiguration.RecipeId;
metadata[Constants.CloudFormationIdentifier.STACK_METADATA_RECIPE_VERSION] = recipeConfiguration.RecipeVersion;
// Save the deployment bundle settings.
if (!string.IsNullOrEmpty(recipeConfiguration.DeploymentBundleSettings))
{
metadata[Constants.CloudFormationIdentifier.STACK_METADATA_DEPLOYMENT_BUNDLE_SETTINGS] = recipeConfiguration.DeploymentBundleSettings;
}
// For the CDK to pick up the changes to the metadata .NET Dictionary you have to reassign the Metadata property.
stack.TemplateOptions.Metadata = metadata;
// CloudFormation tags are propagated to resources created by the stack. In case of Beanstalk deployment a second CloudFormation stack is
// launched which will also have the AWS .NET deployment tool tag. To differentiate these additional stacks a special AWS .NET deployment tool prefix
// is added to the description.
if (string.IsNullOrEmpty(stack.TemplateOptions.Description))
{
stack.TemplateOptions.Description = Constants.CloudFormationIdentifier.STACK_DESCRIPTION_PREFIX;
}
else
{
stack.TemplateOptions.Description = $"{Constants.CloudFormationIdentifier.STACK_DESCRIPTION_PREFIX}: {stack.TemplateOptions.Description}";
}
}
}
}