public async Task DeployCdkProject()

in src/AWS.Deploy.Orchestration/CdkProjectHandler.cs [110:183]


        public async Task DeployCdkProject(OrchestratorSession session, CloudApplication cloudApplication, string cdkProjectPath, Recommendation recommendation)
        {
            var recipeInfo = $"{recommendation.Recipe.Id}_{recommendation.Recipe.Version}";
            var environmentVariables = new Dictionary<string, string>
            {
                { EnvironmentVariableKeys.AWS_EXECUTION_ENV, recipeInfo }
            };

            var appSettingsFilePath = Path.Combine(cdkProjectPath, "appsettings.json");

            if (await DetermineIfCDKBootstrapShouldRun())
            {
                // Ensure region is bootstrapped
                var cdkBootstrap = await _commandLineWrapper.TryRunWithResult($"npx cdk bootstrap aws://{session.AWSAccountId}/{session.AWSRegion} --template \"{_workspaceMetadata.CDKBootstrapTemplatePath}\"",
                    workingDirectory: _workspaceMetadata.DeployToolWorkspaceDirectoryRoot,
                    needAwsCredentials: true,
                    redirectIO: true,
                    streamOutputToInteractiveService: true);

                if (cdkBootstrap.ExitCode != 0)
                    throw new FailedToDeployCDKAppException(DeployToolErrorCode.FailedToRunCDKBootstrap, "The AWS CDK Bootstrap, which is the process of provisioning initial resources for the deployment environment, has failed. Please review the output above for additional details [and check out our troubleshooting guide for the most common failure reasons]. You can learn more about CDK bootstrapping at https://docs.aws.amazon.com/cdk/v2/guide/bootstrapping.html.", cdkBootstrap.ExitCode);
            }
            else
            {
                _interactiveService.LogInfoMessage("Confirmed CDK Bootstrap CloudFormation stack already exists.");
            }


            _interactiveService.LogSectionStart("Deploying AWS CDK project",
                "Use the CDK project to create or update the AWS CloudFormation stack and deploy the project to the AWS resources in the stack.");

            // Handover to CDK command line tool
            // Use a CDK Context parameter to specify the settings file that has been serialized.
            var cdkDeployTask = _commandLineWrapper.TryRunWithResult( $"npx cdk deploy --require-approval never -c {Constants.CloudFormationIdentifier.SETTINGS_PATH_CDK_CONTEXT_PARAMETER}=\"{appSettingsFilePath}\"",
                workingDirectory: cdkProjectPath,
                environmentVariables: environmentVariables,
                needAwsCredentials: true,
                redirectIO: true,
                streamOutputToInteractiveService: true);

            var cancellationTokenSource = new CancellationTokenSource();
            var retrieveStackIdTask = RetrieveStackId(cloudApplication, cancellationTokenSource.Token);

            var deploymentStartDate = DateTime.UtcNow;
            var firstCompletedTask = await Task.WhenAny(cdkDeployTask, retrieveStackIdTask);
            // Deployment end date is captured at this point after 1 of the 2 running tasks yields.
            var deploymentEndDate = DateTime.UtcNow;

            TryRunResult? cdkDeploy = null;
            if (firstCompletedTask == retrieveStackIdTask)
            {
                // If retrieveStackIdTask completes first, that means a stack was created and exists in CloudFormation.
                // We can proceed with checking for deployment failures.
                var stackId = cloudApplication.Name;
                if (!retrieveStackIdTask.IsFaulted)
                    stackId = retrieveStackIdTask.Result;
                cdkDeploy = await cdkDeployTask;
                // We recapture the deployment end date at this point after the deployment task completes.
                deploymentEndDate = DateTime.UtcNow;
                await CheckCdkDeploymentFailure(stackId, deploymentStartDate, deploymentEndDate, cdkDeploy);
            }
            else
            {
                // If cdkDeployTask completes first, that means 'cdk deploy' failed before creating a stack in CloudFormation.
                // In this case, we skip checking for deployment failures since a stack does not exist.

                cdkDeploy = cdkDeployTask.Result;
                cancellationTokenSource.Cancel();
            }

            var deploymentTotalTime = Math.Round((deploymentEndDate - deploymentStartDate).TotalSeconds, 2);
            if (cdkDeploy.ExitCode != 0)
                throw new FailedToDeployCDKAppException(DeployToolErrorCode.FailedToDeployCdkApplication, $"We had an issue deploying your application to AWS. Check the deployment output for more details. Deployment took {deploymentTotalTime}s.", cdkDeploy.ExitCode);
        }