{
  "Description": "(SO0199) Landing Zone Accelerator on AWS. Version 1.6.2.",
  "Metadata": {
    "AWS::CloudFormation::Interface": {
      "ParameterGroups": [
        {
          "Label": {
            "default": "Git Repository Configuration"
          },
          "Parameters": [
            "RepositorySource",
            "RepositoryOwner",
            "RepositoryName",
            "RepositoryBranchName"
          ]
        },
        {
          "Label": {
            "default": "Pipeline Configuration"
          },
          "Parameters": [
            "EnableApprovalStage",
            "ApprovalStageNotifyEmailList"
          ]
        },
        {
          "Label": {
            "default": "Mandatory Accounts Configuration"
          },
          "Parameters": [
            "ManagementAccountEmail",
            "LogArchiveAccountEmail",
            "AuditAccountEmail"
          ]
        },
        {
          "Label": {
            "default": "Environment Configuration"
          },
          "Parameters": [
            "ControlTowerEnabled",
            "AcceleratorPrefix",
            "UseExistingConfigRepo",
            "ExistingConfigRepositoryName",
            "ExistingConfigRepositoryBranchName",
            "EnableDiagnosticsPack"
          ]
        }
      ],
      "ParameterLabels": {
        "RepositorySource": {
          "default": "Source"
        },
        "RepositoryOwner": {
          "default": "Repository Owner"
        },
        "RepositoryName": {
          "default": "Repository Name"
        },
        "RepositoryBranchName": {
          "default": "Branch Name"
        },
        "UseExistingConfigRepo": {
          "default": "Use Existing Config Repository"
        },
        "ExistingConfigRepositoryName": {
          "default": "Existing Config Repository Name"
        },
        "ExistingConfigRepositoryBranchName": {
          "default": "Existing Config Repository Branch Name"
        },
        "EnableDiagnosticsPack": {
          "default": "Enable Diagnostics Pack"
        },
        "EnableApprovalStage": {
          "default": "Enable Approval Stage"
        },
        "ApprovalStageNotifyEmailList": {
          "default": "Manual Approval Stage notification email list"
        },
        "ManagementAccountEmail": {
          "default": "Management Account Email"
        },
        "LogArchiveAccountEmail": {
          "default": "Log Archive Account Email"
        },
        "AuditAccountEmail": {
          "default": "Audit Account Email"
        },
        "ControlTowerEnabled": {
          "default": "Control Tower Environment"
        },
        "AcceleratorPrefix": {
          "default": "Accelerator Resource name prefix"
        }
      }
    }
  },
  "Parameters": {
    "RepositorySource": {
      "Type": "String",
      "Default": "github",
      "AllowedValues": [
        "github",
        "codecommit"
      ],
      "Description": "Specify the git host"
    },
    "RepositoryOwner": {
      "Type": "String",
      "Default": "awslabs",
      "Description": "The owner of the repository containing the accelerator code. (GitHub Only)"
    },
    "RepositoryName": {
      "Type": "String",
      "Default": "landing-zone-accelerator-on-aws",
      "Description": "The name of the git repository hosting the accelerator code"
    },
    "RepositoryBranchName": {
      "Type": "String",
      "Default": "release/v1.6.2",
      "AllowedPattern": ".+",
      "ConstraintDescription": "The repository branch name must not be empty",
      "Description": "The name of the git branch to use for installation. To determine the branch name, navigate to the Landing Zone Accelerator GitHub branches page and choose the release branch you would like to deploy. Release branch names will align with the semantic versioning of our GitHub releases. New release branches will be available as the open source project is updated with new features."
    },
    "EnableApprovalStage": {
      "Type": "String",
      "Default": "Yes",
      "AllowedValues": [
        "Yes",
        "No"
      ],
      "Description": "Select yes to add a Manual Approval stage to accelerator pipeline"
    },
    "ApprovalStageNotifyEmailList": {
      "Type": "CommaDelimitedList",
      "Description": "Provide comma(,) separated list of email ids to receive manual approval stage notification email"
    },
    "ManagementAccountEmail": {
      "Type": "String",
      "AllowedPattern": "[^\\s@]+@[^\\s@]+\\.[^\\s@]+",
      "ConstraintDescription": "Must be a valid email address matching \"[^\\s@]+@[^\\s@]+\\.[^\\s@]+\"",
      "Description": "The management (primary) account email"
    },
    "LogArchiveAccountEmail": {
      "Type": "String",
      "AllowedPattern": "[^\\s@]+@[^\\s@]+\\.[^\\s@]+",
      "ConstraintDescription": "Must be a valid email address matching \"[^\\s@]+@[^\\s@]+\\.[^\\s@]+\"",
      "Description": "The log archive account email"
    },
    "AuditAccountEmail": {
      "Type": "String",
      "AllowedPattern": "[^\\s@]+@[^\\s@]+\\.[^\\s@]+",
      "ConstraintDescription": "Must be a valid email address matching \"[^\\s@]+@[^\\s@]+\\.[^\\s@]+\"",
      "Description": "The security audit account (also referred to as the audit account)"
    },
    "ControlTowerEnabled": {
      "Type": "String",
      "Default": "Yes",
      "AllowedValues": [
        "Yes",
        "No"
      ],
      "Description": "Select yes if you deploying to a Control Tower environment.  Select no if using just Organizations"
    },
    "AcceleratorPrefix": {
      "Type": "String",
      "Default": "AWSAccelerator",
      "AllowedPattern": "[A-Za-z0-9-]+",
      "Description": "The prefix value for accelerator deployed resources. Leave the default value if using solution defined resource name prefix, the solution will use AWSAccelerator as resource name prefix. Note: Updating this value after initial installation will cause stack failure. Non-default value can not start with keyword \"aws\" or \"ssm\". Trailing dash (-) in non-default value will be ignored.",
      "MaxLength": 15
    },
    "UseExistingConfigRepo": {
      "Type": "String",
      "Default": "No",
      "AllowedValues": [
        "Yes",
        "No"
      ],
      "Description": "Select Yes if deploying the solution with an existing CodeCommit configuration repository. Leave the default value if using the solution-deployed repository. If the AcceleratorPrefix parameter is set to the default value, the solution will deploy a repository named \"aws-accelerator-config.\" Otherwise, the solution-deployed repository will be named \"AcceleratorPrefix-config.\" Note: Updating this value after initial installation may cause adverse affects."
    },
    "ExistingConfigRepositoryName": {
      "Type": "String",
      "Default": "",
      "Description": "The name of an existing CodeCommit repository hosting the accelerator configuration."
    },
    "ExistingConfigRepositoryBranchName": {
      "Type": "String",
      "Default": "",
      "Description": "Specify the branch name of existing CodeCommit repository to pull the accelerator configuration from."
    },
    "EnableDiagnosticsPack": {
      "Type": "String",
      "Default": "Yes",
      "AllowedValues": [
        "Yes",
        "No"
      ],
      "Description": "Select Yes if deploying the solution with diagnostics pack enabled. Diagnostics pack enables you to generate root cause reports to potentially diagnose pipeline failures."
    }
  },
  "Conditions": {
    "IsCommercialCondition": {
      "Fn::Equals": [
        {
          "Ref": "AWS::Partition"
        },
        "aws"
      ]
    },
    "SolutionHelperAnonymousDataToAWS62E4FDE2": {
      "Fn::Equals": [
        {
          "Fn::FindInMap": [
            "SolutionHelperAnonymousData14B64A81",
            "SendAnonymizedData",
            "Data"
          ]
        },
        "Yes"
      ]
    },
    "UseCodeCommitCondition": {
      "Fn::Equals": [
        {
          "Ref": "RepositorySource"
        },
        "codecommit"
      ]
    },
    "UseGitHubCondition": {
      "Fn::Equals": [
        {
          "Ref": "RepositorySource"
        },
        "github"
      ]
    }
  },
  "Mappings": {
    "GlobalRegionMap": {
      "aws": {
        "regionName": "us-east-1"
      },
      "aws-us-gov": {
        "regionName": "us-gov-west-1"
      },
      "aws-iso-b": {
        "regionName": "us-isob-east-1"
      },
      "aws-iso": {
        "regionName": "us-iso-east-1"
      },
      "aws-cn": {
        "regionName": "cn-northwest-1"
      }
    },
    "SolutionHelperAnonymousData14B64A81": {
      "SendAnonymizedData": {
        "Data": "Yes"
      }
    }
  },
  "Resources": {
    "ValidateInstallerValidationFunctionServiceRoleF5BE8F9B": {
      "Type": "AWS::IAM::Role",
      "Properties": {
        "AssumeRolePolicyDocument": {
          "Statement": [
            {
              "Action": "sts:AssumeRole",
              "Effect": "Allow",
              "Principal": {
                "Service": "lambda.amazonaws.com"
              }
            }
          ],
          "Version": "2012-10-17"
        },
        "ManagedPolicyArns": [
          {
            "Fn::Join": [
              "",
              [
                "arn:",
                {
                  "Ref": "AWS::Partition"
                },
                ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
              ]
            ]
          }
        ]
      },
      "Metadata": {
        "aws:cdk:path": "AWSAccelerator-InstallerStack/ValidateInstaller/ValidationFunction/ServiceRole/Resource",
        "cdk_nag": {
          "rules_to_suppress": [
            {
              "id": "AwsSolutions-IAM4",
              "reason": "Needed to write to CWL group"
            }
          ]
        }
      }
    },
    "ValidateInstallerValidationFunction21674768": {
      "Type": "AWS::Lambda::Function",
      "Properties": {
        "Code": {
          "ZipFile": "\n          const response = require('cfn-response'); \n          exports.handler = async function (event, context) { \n          console.log(JSON.stringify(event, null, 4)); \n\n          const useExistingConfigRepo=event.ResourceProperties.useExistingConfigRepo;\n          const existingConfigRepositoryName=event.ResourceProperties.existingConfigRepositoryName;\n          const existingConfigRepositoryBranchName=event.ResourceProperties.existingConfigRepositoryBranchName;\n\n          if (useExistingConfigRepo === 'Yes') {\n            if (existingConfigRepositoryName === '' || existingConfigRepositoryBranchName === ''){\n                await response.send(event, context, response.FAILED, {'FailureReason': 'UseExistingConfigRepo parameter set to Yes, but ExistingConfigRepositoryName or ExistingConfigRepositoryBranchName parameter value missing!!!'}, event.PhysicalResourceId);\n                return;\n            }\n          }\n\n          // End of Validation\n          await response.send(event, context, response.SUCCESS, {}, event.PhysicalResourceId);\n          return;\n      }"
        },
        "Description": "This function validates installer parameters",
        "Handler": "index.handler",
        "Role": {
          "Fn::GetAtt": [
            "ValidateInstallerValidationFunctionServiceRoleF5BE8F9B",
            "Arn"
          ]
        },
        "Runtime": "nodejs16.x"
      },
      "DependsOn": [
        "ValidateInstallerValidationFunctionServiceRoleF5BE8F9B"
      ],
      "Metadata": {
        "aws:cdk:path": "AWSAccelerator-InstallerStack/ValidateInstaller/ValidationFunction/Resource",
        "cdk_nag": {
          "rules_to_suppress": [
            {
              "id": "AwsSolutions-IAM4",
              "reason": "Needed to write to CWL group"
            }
          ]
        },
        "cfn_nag": {
          "rules_to_suppress": [
            {
              "id": "W58",
              "reason": "CloudWatch Logs are enabled in AWSLambdaBasicExecutionRole"
            },
            {
              "id": "W89",
              "reason": "This function supports infrastructure deployment and is not deployed inside a VPC."
            },
            {
              "id": "W92",
              "reason": "This function supports infrastructure deployment and does not require setting ReservedConcurrentExecutions."
            }
          ]
        }
      }
    },
    "ValidateInstallerValidateResource24181D5D": {
      "Type": "AWS::CloudFormation::CustomResource",
      "Properties": {
        "ServiceToken": {
          "Fn::GetAtt": [
            "ValidateInstallerValidationFunction21674768",
            "Arn"
          ]
        },
        "useExistingConfigRepo": {
          "Ref": "UseExistingConfigRepo"
        },
        "existingConfigRepositoryName": {
          "Ref": "ExistingConfigRepositoryName"
        },
        "existingConfigRepositoryBranchName": {
          "Ref": "ExistingConfigRepositoryBranchName"
        },
        "resourceType": "Custom::ValidateInstallerStack"
      },
      "UpdateReplacePolicy": "Delete",
      "DeletionPolicy": "Delete",
      "Metadata": {
        "aws:cdk:path": "AWSAccelerator-InstallerStack/ValidateInstaller/ValidateResource/Default"
      }
    },
    "ResourceNamePrefixesResourceNamePrefixesFunctionServiceRole17DDBBF2": {
      "Type": "AWS::IAM::Role",
      "Properties": {
        "AssumeRolePolicyDocument": {
          "Statement": [
            {
              "Action": "sts:AssumeRole",
              "Effect": "Allow",
              "Principal": {
                "Service": "lambda.amazonaws.com"
              }
            }
          ],
          "Version": "2012-10-17"
        },
        "ManagedPolicyArns": [
          {
            "Fn::Join": [
              "",
              [
                "arn:",
                {
                  "Ref": "AWS::Partition"
                },
                ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
              ]
            ]
          }
        ]
      },
      "Metadata": {
        "aws:cdk:path": "AWSAccelerator-InstallerStack/ResourceNamePrefixes/ResourceNamePrefixesFunction/ServiceRole/Resource",
        "cdk_nag": {
          "rules_to_suppress": [
            {
              "id": "AwsSolutions-IAM4",
              "reason": "Needed to write to CWL group"
            },
            {
              "id": "AwsSolutions-IAM5",
              "reason": "Needed to create SSM parameter for prefix"
            }
          ]
        }
      }
    },
    "ResourceNamePrefixesResourceNamePrefixesFunctionServiceRoleDefaultPolicyDC1CC159": {
      "Type": "AWS::IAM::Policy",
      "Properties": {
        "PolicyDocument": {
          "Statement": [
            {
              "Action": [
                "ssm:GetParameters",
                "ssm:GetParameter",
                "ssm:PutParameter",
                "ssm:DeleteParameter"
              ],
              "Condition": {
                "StringEquals": {
                  "aws:PrincipalAccount": {
                    "Ref": "AWS::AccountId"
                  }
                }
              },
              "Effect": "Allow",
              "Resource": [
                {
                  "Fn::Join": [
                    "",
                    [
                      "arn:",
                      {
                        "Ref": "AWS::Partition"
                      },
                      ":ssm:",
                      {
                        "Ref": "AWS::Region"
                      },
                      ":",
                      {
                        "Ref": "AWS::AccountId"
                      },
                      ":parameter/accelerator/lza-prefix"
                    ]
                  ]
                },
                {
                  "Fn::Join": [
                    "",
                    [
                      "arn:",
                      {
                        "Ref": "AWS::Partition"
                      },
                      ":ssm:",
                      {
                        "Ref": "AWS::Region"
                      },
                      ":",
                      {
                        "Ref": "AWS::AccountId"
                      },
                      ":parameter/accelerator/AWSAccelerator-PipelineStack-",
                      {
                        "Ref": "AWS::AccountId"
                      },
                      "-",
                      {
                        "Ref": "AWS::Region"
                      },
                      "/version"
                    ]
                  ]
                }
              ],
              "Sid": "SsmReadParameterAccess"
            }
          ],
          "Version": "2012-10-17"
        },
        "PolicyName": "ResourceNamePrefixesResourceNamePrefixesFunctionServiceRoleDefaultPolicyDC1CC159",
        "Roles": [
          {
            "Ref": "ResourceNamePrefixesResourceNamePrefixesFunctionServiceRole17DDBBF2"
          }
        ]
      },
      "Metadata": {
        "aws:cdk:path": "AWSAccelerator-InstallerStack/ResourceNamePrefixes/ResourceNamePrefixesFunction/ServiceRole/DefaultPolicy/Resource",
        "cdk_nag": {
          "rules_to_suppress": [
            {
              "id": "AwsSolutions-IAM4",
              "reason": "Needed to write to CWL group"
            },
            {
              "id": "AwsSolutions-IAM5",
              "reason": "Needed to create SSM parameter for prefix"
            }
          ]
        }
      }
    },
    "ResourceNamePrefixesResourceNamePrefixesFunction138C66F1": {
      "Type": "AWS::Lambda::Function",
      "Properties": {
        "Code": {
          "ZipFile": "\n          const response = require('cfn-response'); \n          const AWS = require('aws-sdk');\n          exports.handler = async function (event, context) { \n          console.log(JSON.stringify(event, null, 4)); \n          const prefix=event.ResourceProperties.prefix;\n          const pipelineStackVersionSsmParamName=event.ResourceProperties.pipelineStackVersionSsmParamName;\n          const lowerCasePrefix=prefix.toLowerCase();\n          \n          const ssm = new AWS.SSM({});\n          \n          let data = {};\n          \n          let paramName = event.ResourceProperties.prefixParameterName;\n          \n          if (lowerCasePrefix === 'awsaccelerator') {\n              data['acceleratorPrefix'] = 'AWSAccelerator';\n              data['lowerCasePrefix'] = 'aws-accelerator'; \n              data['oneWordPrefix'] = 'accelerator';               \n          } else {\n              data['acceleratorPrefix'] = prefix;\n              data['lowerCasePrefix'] = lowerCasePrefix; \n              data['oneWordPrefix'] = prefix; \n          }\n                  \n\n          if (event.RequestType === 'Update'){\n\n              var params = {\n                Name: paramName,\n              };\n              try {\n                  const ssmResponse = await ssm.getParameter(params).promise();\n                  // Fail stack if prefix was changed during update\n                  if (ssmResponse.Parameter.Value !== prefix) {\n                      await response.send(event, context, response.FAILED, {'FailureReason': 'LZA does not allow changing AcceleratorPrefix parameter value after initial deploy !!! Existing prefix: ' + event.OldResourceProperties.prefix + ' New prefix: ' + prefix + '.' }, event.PhysicalResourceId);\n                      return;\n                  }\n                  await response.send(event, context, response.SUCCESS, data, event.PhysicalResourceId);\n              } catch (error) {\n                  console.log(error);\n                  if (error.code === 'ParameterNotFound'){\n                      await response.send(event, context, response.FAILED, {'FailureReason': 'LZA prefix ssm parameter ' + paramName + ' not found!!! Recreate the parameter with existing AcceleratorPrefix parameter value to fix the issue'}, event.PhysicalResourceId);\n                      return;\n                  }\n                  else {\n                      await response.send(event, context, response.FAILED, {'FailureReason': error.code + ' error occurred while accessing LZA prefix ssm parameter ' + paramName }, event.PhysicalResourceId);\n                      return;\n                  }\n              }          \n          } \n          \n          if (event.RequestType === 'Create') {\n          \n              if (lowerCasePrefix !== 'awsaccelerator') {\n                  // Fail stack if prefix starts with aws or ssm\n                  if (lowerCasePrefix.startsWith('aws') || lowerCasePrefix.startsWith('ssm')) { \n                      await response.send(event, context, response.FAILED, {'FailureReason': 'Accelerator prefix ' + prefix + ' can not be started with aws or ssm !!!'}, event.PhysicalResourceId);\n                      return;\n                  }\n\n                  // Check if this is an existing deployment and prefix changed with initial deployment of custom resource\n                  var versionParams = {\n                    Name: pipelineStackVersionSsmParamName,\n                  };\n                  try {\n                    await ssm.getParameter(versionParams).promise();\n                    await response.send(event, context, response.FAILED, {'FailureReason': 'Can not change AcceleratorPrefix parameter for existing deployment, existing prefix value is AWSAccelerator, keep AcceleratorPrefix parameter value to default value for successfully stack update !!!'}, event.PhysicalResourceId);\n                    return;\n                  }\n                  catch (error) {\n                    console.log(error);\n                    if (error.code !== 'ParameterNotFound'){\n                      await response.send(event, context, response.FAILED, {'FailureReason': error.code + ' error occurred while accessing LZA ssm parameter ' + pipelineStackVersionSsmParamName }, event.PhysicalResourceId);\n                      return;\n                    }\n                  }\n              }\n          \n              // Create /accelerator/lza-prefix SSM parameter to store prefix value to protect updating prefix\n              try {\n                  var newParams = {\n                        Name: paramName,\n                        Value: prefix,\n                        Description: 'LZA created SSM parameter for Accelerator prefix value, DO NOT MODIFY/DELETE this parameter',\n                        Type: 'String',\n                      };\n                  await ssm.putParameter(newParams).promise();\n                  console.log('LZA prefix parameter ' + paramName  + ' created successfully.');\n                  await response.send(event, context, response.SUCCESS, data, event.PhysicalResourceId);\n              }\n              catch (error) {\n                  console.log(error);\n                  await response.send(event, context, response.FAILED, {'FailureReason': error.code + ' error occurred while creating LZA prefix ssm parameter ' + paramName }, event.PhysicalResourceId);\n                  return;\n              }\n          }\n          if (event.RequestType === 'Delete') {\n\n            var deleteParams = {\n              Name: paramName,\n            };\n            try {\n              await ssm.deleteParameter(deleteParams).promise();\n              console.log('LZA prefix parameter ' + paramName  + ' deleted successfully.');\n            }\n            catch (error) {\n              console.log(error);\n              if (error.code !== 'ParameterNotFound'){\n                await response.send(event, context, response.FAILED, {'FailureReason': error.code + ' error occurred while deleting LZA ssm parameter ' + paramName }, event.PhysicalResourceId);\n                return;\n              }\n            }\n            await response.send(event, context, response.SUCCESS, {'Status': 'Custom resource deleted successfully' }, event.PhysicalResourceId);\n          }\n          \n          return;\n      }"
        },
        "Description": "This function converts accelerator prefix parameter to lower case to name s3 buckets in installer stack",
        "Handler": "index.handler",
        "Role": {
          "Fn::GetAtt": [
            "ResourceNamePrefixesResourceNamePrefixesFunctionServiceRole17DDBBF2",
            "Arn"
          ]
        },
        "Runtime": "nodejs16.x"
      },
      "DependsOn": [
        "ResourceNamePrefixesResourceNamePrefixesFunctionServiceRoleDefaultPolicyDC1CC159",
        "ResourceNamePrefixesResourceNamePrefixesFunctionServiceRole17DDBBF2"
      ],
      "Metadata": {
        "aws:cdk:path": "AWSAccelerator-InstallerStack/ResourceNamePrefixes/ResourceNamePrefixesFunction/Resource",
        "cdk_nag": {
          "rules_to_suppress": [
            {
              "id": "AwsSolutions-IAM4",
              "reason": "Needed to write to CWL group"
            },
            {
              "id": "AwsSolutions-IAM5",
              "reason": "Needed to create SSM parameter for prefix"
            }
          ]
        },
        "cfn_nag": {
          "rules_to_suppress": [
            {
              "id": "W58",
              "reason": "CloudWatch Logs are enabled in AWSLambdaBasicExecutionRole"
            },
            {
              "id": "W89",
              "reason": "This function supports infrastructure deployment and is not deployed inside a VPC."
            },
            {
              "id": "W92",
              "reason": "This function supports infrastructure deployment and does not require setting ReservedConcurrentExecutions."
            }
          ]
        }
      }
    },
    "ResourceNamePrefixesGetPrefixResource96A10E6E": {
      "Type": "Custom::GetPrefixes",
      "Properties": {
        "ServiceToken": {
          "Fn::GetAtt": [
            "ResourceNamePrefixesResourceNamePrefixesFunction138C66F1",
            "Arn"
          ]
        },
        "prefix": {
          "Ref": "AcceleratorPrefix"
        },
        "pipelineStackVersionSsmParamName": {
          "Fn::Join": [
            "",
            [
              "/accelerator/AWSAccelerator-PipelineStack-",
              {
                "Ref": "AWS::AccountId"
              },
              "-",
              {
                "Ref": "AWS::Region"
              },
              "/version"
            ]
          ]
        },
        "prefixParameterName": "/accelerator/lza-prefix"
      },
      "UpdateReplacePolicy": "Delete",
      "DeletionPolicy": "Delete",
      "Metadata": {
        "aws:cdk:path": "AWSAccelerator-InstallerStack/ResourceNamePrefixes/GetPrefixResource/Default"
      }
    },
    "SsmParamStackId521A78D3": {
      "Type": "AWS::SSM::Parameter",
      "Properties": {
        "Name": {
          "Fn::Join": [
            "",
            [
              "/",
              {
                "Fn::GetAtt": [
                  "ResourceNamePrefixesGetPrefixResource96A10E6E",
                  "oneWordPrefix"
                ]
              },
              "/AWSAccelerator-InstallerStack/stack-id"
            ]
          ]
        },
        "Type": "String",
        "Value": {
          "Ref": "AWS::StackId"
        }
      },
      "Metadata": {
        "aws:cdk:path": "AWSAccelerator-InstallerStack/SsmParamStackId/Resource"
      }
    },
    "SsmParamAcceleratorVersionFF83282D": {
      "Type": "AWS::SSM::Parameter",
      "Properties": {
        "Name": {
          "Fn::Join": [
            "",
            [
              "/",
              {
                "Fn::GetAtt": [
                  "ResourceNamePrefixesGetPrefixResource96A10E6E",
                  "oneWordPrefix"
                ]
              },
              "/AWSAccelerator-InstallerStack/version"
            ]
          ]
        },
        "Type": "String",
        "Value": "1.6.2"
      },
      "Metadata": {
        "aws:cdk:path": "AWSAccelerator-InstallerStack/SsmParamAcceleratorVersion/Resource"
      }
    },
    "SolutionHelperServiceRoleF70C0E2A": {
      "Type": "AWS::IAM::Role",
      "Properties": {
        "AssumeRolePolicyDocument": {
          "Statement": [
            {
              "Action": "sts:AssumeRole",
              "Effect": "Allow",
              "Principal": {
                "Service": "lambda.amazonaws.com"
              }
            }
          ],
          "Version": "2012-10-17"
        },
        "ManagedPolicyArns": [
          {
            "Fn::Join": [
              "",
              [
                "arn:",
                {
                  "Ref": "AWS::Partition"
                },
                ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
              ]
            ]
          }
        ]
      },
      "Metadata": {
        "aws:cdk:path": "AWSAccelerator-InstallerStack/SolutionHelper/SolutionHelper/ServiceRole/Resource",
        "cdk_nag": {
          "rules_to_suppress": [
            {
              "id": "AwsSolutions-IAM4",
              "reason": "Needed to write to CWL group"
            }
          ]
        }
      }
    },
    "SolutionHelper4825923B": {
      "Type": "AWS::Lambda::Function",
      "Properties": {
        "Code": {
          "ZipFile": "\n        const AWS = require('aws-sdk');\n        const response = require('cfn-response');\n        const https = require('https');\n\n        async function post(url, data) {\n          const dataString = JSON.stringify(data)\n          const options = {\n              method: 'POST',\n              headers: {\n                  'Content-Type': 'application/json'\n              },\n              timeout: 1000, // in ms\n          }\n          \n          return new Promise((resolve, reject) => {\n              const req = https.request(url, options, (res) => {\n                  if (res.statusCode < 200 || res.statusCode > 299) {\n                      return reject(new Error('HTTP status code: ', res.statusCode))\n                  }\n                  const body = []\n                  res.on('data', (chunk) => body.push(chunk))\n                  res.on('end', () => {\n                      const resString = Buffer.concat(body).toString()\n                      resolve(resString)\n                  })\n              })\n              req.on('error', (err) => {\n                  reject(err)\n              })\n              req.on('timeout', () => {\n                  req.destroy()\n                  reject(new Error('Request time out'))\n              })\n              req.write(dataString)\n              req.end()\n          })\n        }\n\n        function uuidv4() {\n          return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {\n              var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);\n              return v.toString(16);\n          });\n        }\n\n\n        function sanitizeData(resourceProperties) {\n          const keysToExclude = ['ServiceToken', 'Resource', 'SolutionId', 'UUID'];\n          return Object.keys(resourceProperties).reduce((sanitizedData, key) => {\n              if (!keysToExclude.includes(key)) {\n                  sanitizedData[key] = resourceProperties[key];\n              }\n              return sanitizedData;\n          }, {})\n        }\n\n        exports.handler = async function (event, context) {\n          console.log(JSON.stringify(event, null, 4));\n          const requestType = event.RequestType;\n          const resourceProperties = event.ResourceProperties;\n          const resource = resourceProperties.Resource;\n          let data = {};\n          try {\n              if (resource === 'UUID' && requestType === 'Create') {\n                  data['UUID'] = uuidv4();\n              }\n              if (resource === 'AnonymousMetric') {\n                  const currentDate = new Date()\n                  data = sanitizeData(resourceProperties);\n                  data['RequestType'] = requestType;\n                  const payload = {\n                      Solution: resourceProperties.SolutionId,\n                      UUID: resourceProperties.UUID,\n                      TimeStamp: currentDate.toISOString(),\n                      Data: data\n                  }\n\n                  console.log('Sending metrics data: ', JSON.stringify(payload, null, 2));\n                  await post('https://metrics.awssolutionsbuilder.com/generic', payload);\n                  console.log('Sent Data');\n              }\n          } catch (error) {\n              console.log(error);\n          }\n      \n          if (requestType === 'Create') {\n            await response.send(event, context, response.SUCCESS, data);\n          }\n          else {\n            await response.send(event, context, response.SUCCESS, data, event.PhysicalResourceId);\n          }\n          return;\n        } \n      "
        },
        "Description": "This function generates UUID for each deployment and sends anonymous data to the AWS Solutions team",
        "Handler": "index.handler",
        "Role": {
          "Fn::GetAtt": [
            "SolutionHelperServiceRoleF70C0E2A",
            "Arn"
          ]
        },
        "Runtime": "nodejs16.x",
        "Timeout": 30
      },
      "DependsOn": [
        "SolutionHelperServiceRoleF70C0E2A"
      ],
      "Metadata": {
        "cfn_nag": {
          "rules_to_suppress": [
            {
              "id": "W58",
              "reason": "CloudWatch Logs are enabled in AWSLambdaBasicExecutionRole"
            },
            {
              "id": "W89",
              "reason": "This function supports infrastructure deployment and is not deployed inside a VPC."
            },
            {
              "id": "W92",
              "reason": "This function supports infrastructure deployment and does not require setting ReservedConcurrentExecutions."
            }
          ]
        }
      },
      "Condition": "SolutionHelperAnonymousDataToAWS62E4FDE2"
    },
    "SolutionHelperSolutionCreateUniqueID070ED802": {
      "Type": "Custom::CreateUUID",
      "Properties": {
        "ServiceToken": {
          "Fn::GetAtt": [
            "SolutionHelper4825923B",
            "Arn"
          ]
        },
        "Resource": "UUID"
      },
      "UpdateReplacePolicy": "Delete",
      "DeletionPolicy": "Delete",
      "Metadata": {
        "aws:cdk:path": "AWSAccelerator-InstallerStack/SolutionHelper/SolutionCreateUniqueID/Default"
      },
      "Condition": "SolutionHelperAnonymousDataToAWS62E4FDE2"
    },
    "SolutionHelperSolutionSendAnonymousData271B3D26": {
      "Type": "Custom::AnonymousData",
      "Properties": {
        "ServiceToken": {
          "Fn::GetAtt": [
            "SolutionHelper4825923B",
            "Arn"
          ]
        },
        "Resource": "AnonymousMetric",
        "SolutionId": "SO0199",
        "UUID": {
          "Fn::GetAtt": [
            "SolutionHelperSolutionCreateUniqueID070ED802",
            "UUID"
          ]
        },
        "Region": {
          "Ref": "AWS::Region"
        },
        "BranchName": {
          "Ref": "RepositoryBranchName"
        },
        "RepositoryName": {
          "Ref": "RepositoryName"
        },
        "RepositoryOwner": {
          "Ref": "RepositoryOwner"
        },
        "RepositorySource": {
          "Ref": "RepositorySource"
        }
      },
      "UpdateReplacePolicy": "Delete",
      "DeletionPolicy": "Delete",
      "Metadata": {
        "aws:cdk:path": "AWSAccelerator-InstallerStack/SolutionHelper/SolutionSendAnonymousData/Default"
      },
      "Condition": "SolutionHelperAnonymousDataToAWS62E4FDE2"
    },
    "InstallerKey2A6A8C6D": {
      "Type": "AWS::KMS::Key",
      "Properties": {
        "Description": "AWS Accelerator Management Account Kms Key",
        "EnableKeyRotation": true,
        "KeyPolicy": {
          "Statement": [
            {
              "Effect": "Allow",
              "Principal": {
                "AWS": {
                  "Fn::Join": [
                    "",
                    [
                      "arn:",
                      {
                        "Ref": "AWS::Partition"
                      },
                      ":iam::",
                      {
                        "Ref": "AWS::AccountId"
                      },
                      ":root"
                    ]
                  ]
                }
              },
              "Action": "kms:*",
              "Resource": "*"
            },
            {
              "Sid": "Allow Accelerator Role to use the encryption key",
              "Effect": "Allow",
              "Principal": {
                "AWS": "*"
              },
              "Action": [
                "kms:Encrypt",
                "kms:Decrypt",
                "kms:ReEncrypt*",
                "kms:GenerateDataKey*",
                "kms:DescribeKey"
              ],
              "Resource": "*",
              "Condition": {
                "ArnLike": {
                  "aws:PrincipalARN": {
                    "Fn::Join": [
                      "",
                      [
                        "arn:",
                        {
                          "Ref": "AWS::Partition"
                        },
                        ":iam::",
                        {
                          "Ref": "AWS::AccountId"
                        },
                        ":role/",
                        {
                          "Fn::GetAtt": [
                            "ResourceNamePrefixesGetPrefixResource96A10E6E",
                            "acceleratorPrefix"
                          ]
                        },
                        "-*"
                      ]
                    ]
                  }
                }
              }
            },
            {
              "Sid": "Allow SNS service to use the encryption key",
              "Effect": "Allow",
              "Principal": {
                "Service": "sns.amazonaws.com"
              },
              "Action": [
                "kms:Encrypt",
                "kms:Decrypt",
                "kms:ReEncrypt*",
                "kms:GenerateDataKey*",
                "kms:DescribeKey"
              ],
              "Resource": "*"
            },
            {
              "Sid": "Allow Cloudwatch Logs service to use the encryption key",
              "Effect": "Allow",
              "Principal": {
                "Service": {
                  "Fn::Join": [
                    "",
                    [
                      "logs.",
                      {
                        "Ref": "AWS::Region"
                      },
                      ".",
                      {
                        "Ref": "AWS::URLSuffix"
                      }
                    ]
                  ]
                }
              },
              "Action": [
                "kms:Encrypt",
                "kms:Decrypt",
                "kms:ReEncrypt*",
                "kms:GenerateDataKey*",
                "kms:DescribeKey"
              ],
              "Resource": "*",
              "Condition": {
                "ArnLike": {
                  "kms:EncryptionContext:aws:logs:arn": {
                    "Fn::Join": [
                      "",
                      [
                        "arn:",
                        {
                          "Ref": "AWS::Partition"
                        },
                        ":logs:",
                        {
                          "Ref": "AWS::Region"
                        },
                        ":",
                        {
                          "Ref": "AWS::AccountId"
                        },
                        ":log-group:*"
                      ]
                    ]
                  }
                }
              }
            },
            {
              "Fn::If": [
                "IsCommercialCondition",
                {
                  "Sid": "KMS key access to codestar-notifications",
                  "Effect": "Allow",
                  "Principal": {
                    "Service": "codestar-notifications.amazonaws.com"
                  },
                  "Action": [
                    "kms:GenerateDataKey*",
                    "kms:Decrypt"
                  ],
                  "Resource": "*",
                  "Condition": {
                    "StringEquals": {
                      "kms:ViaService": {
                        "Fn::Join": [
                          "",
                          [
                            "sns.",
                            {
                              "Ref": "AWS::Region"
                            },
                            ".amazonaws.com"
                          ]
                        ]
                      }
                    }
                  }
                },
                {
                  "Ref": "AWS::NoValue"
                }
              ]
            }
          ]
        }
      },
      "UpdateReplacePolicy": "Retain",
      "DeletionPolicy": "Retain",
      "Metadata": {
        "cfn_nag": {
          "rules_to_suppress": [
            {
              "id": "F76",
              "reason": "KMS key using * principal with added arn condition"
            }
          ]
        }
      }
    },
    "InstallerKeyAliasD5C174F0": {
      "Type": "AWS::KMS::Alias",
      "Properties": {
        "AliasName": {
          "Fn::Join": [
            "",
            [
              "alias/",
              {
                "Fn::GetAtt": [
                  "ResourceNamePrefixesGetPrefixResource96A10E6E",
                  "oneWordPrefix"
                ]
              },
              "/installer/kms/key"
            ]
          ]
        },
        "TargetKeyId": {
          "Fn::GetAtt": [
            "InstallerKey2A6A8C6D",
            "Arn"
          ]
        }
      },
      "Metadata": {
        "aws:cdk:path": "AWSAccelerator-InstallerStack/InstallerKey/Alias/Resource"
      }
    },
    "AcceleratorManagementKmsArnParameter1E6975BF": {
      "Type": "AWS::SSM::Parameter",
      "Properties": {
        "Name": {
          "Fn::Join": [
            "",
            [
              "/",
              {
                "Fn::GetAtt": [
                  "ResourceNamePrefixesGetPrefixResource96A10E6E",
                  "oneWordPrefix"
                ]
              },
              "/installer/kms/key-arn"
            ]
          ]
        },
        "Type": "String",
        "Value": {
          "Fn::GetAtt": [
            "InstallerKey2A6A8C6D",
            "Arn"
          ]
        }
      },
      "Metadata": {
        "aws:cdk:path": "AWSAccelerator-InstallerStack/AcceleratorManagementKmsArnParameter/Resource"
      }
    },
    "InstallerAccessLogsBucket647700E9": {
      "Type": "AWS::S3::Bucket",
      "Properties": {
        "AccessControl": "LogDeliveryWrite",
        "BucketEncryption": {
          "ServerSideEncryptionConfiguration": [
            {
              "ServerSideEncryptionByDefault": {
                "SSEAlgorithm": "AES256"
              }
            }
          ]
        },
        "BucketName": {
          "Fn::Join": [
            "",
            [
              {
                "Fn::GetAtt": [
                  "ResourceNamePrefixesGetPrefixResource96A10E6E",
                  "lowerCasePrefix"
                ]
              },
              "-s3-logs-",
              {
                "Ref": "AWS::AccountId"
              },
              "-",
              {
                "Ref": "AWS::Region"
              }
            ]
          ]
        },
        "LifecycleConfiguration": {
          "Rules": [
            {
              "AbortIncompleteMultipartUpload": {
                "DaysAfterInitiation": 1
              },
              "ExpirationInDays": 1825,
              "ExpiredObjectDeleteMarker": false,
              "Id": {
                "Fn::Join": [
                  "",
                  [
                    "LifecycleRule",
                    {
                      "Fn::GetAtt": [
                        "ResourceNamePrefixesGetPrefixResource96A10E6E",
                        "lowerCasePrefix"
                      ]
                    },
                    "-s3-logs-",
                    {
                      "Ref": "AWS::AccountId"
                    },
                    "-",
                    {
                      "Ref": "AWS::Region"
                    }
                  ]
                ]
              },
              "NoncurrentVersionExpiration": {
                "NoncurrentDays": 1825
              },
              "NoncurrentVersionTransitions": [
                {
                  "StorageClass": "DEEP_ARCHIVE",
                  "TransitionInDays": 366
                }
              ],
              "Status": "Enabled",
              "Transitions": [
                {
                  "StorageClass": "DEEP_ARCHIVE",
                  "TransitionInDays": 365
                }
              ]
            }
          ]
        },
        "OwnershipControls": {
          "Rules": [
            {
              "ObjectOwnership": "BucketOwnerPreferred"
            }
          ]
        },
        "PublicAccessBlockConfiguration": {
          "BlockPublicAcls": true,
          "BlockPublicPolicy": true,
          "IgnorePublicAcls": true,
          "RestrictPublicBuckets": true
        },
        "VersioningConfiguration": {
          "Status": "Enabled"
        }
      },
      "UpdateReplacePolicy": "Retain",
      "DeletionPolicy": "Retain",
      "Metadata": {
        "cfn_nag": {
          "rules_to_suppress": [
            {
              "id": "W35",
              "reason": "This is an access logging bucket."
            }
          ]
        },
        "cdk_nag": {
          "rules_to_suppress": [
            {
              "id": "AwsSolutions-S1",
              "reason": "AccessLogsBucket has server access logs disabled till the task for access logging completed."
            }
          ]
        }
      }
    },
    "InstallerAccessLogsBucketPolicy20D4E285": {
      "Type": "AWS::S3::BucketPolicy",
      "Properties": {
        "Bucket": {
          "Ref": "InstallerAccessLogsBucket647700E9"
        },
        "PolicyDocument": {
          "Statement": [
            {
              "Action": "s3:*",
              "Condition": {
                "Bool": {
                  "aws:SecureTransport": "false"
                }
              },
              "Effect": "Deny",
              "Principal": {
                "AWS": "*"
              },
              "Resource": [
                {
                  "Fn::GetAtt": [
                    "InstallerAccessLogsBucket647700E9",
                    "Arn"
                  ]
                },
                {
                  "Fn::Join": [
                    "",
                    [
                      {
                        "Fn::GetAtt": [
                          "InstallerAccessLogsBucket647700E9",
                          "Arn"
                        ]
                      },
                      "/*"
                    ]
                  ]
                }
              ],
              "Sid": "deny-insecure-connections"
            }
          ],
          "Version": "2012-10-17"
        }
      },
      "Metadata": {
        "aws:cdk:path": "AWSAccelerator-InstallerStack/InstallerAccessLogsBucket/Resource/Policy/Resource"
      }
    },
    "InstallerAccessLogsBucketName4F700F48": {
      "Type": "AWS::SSM::Parameter",
      "Properties": {
        "Name": {
          "Fn::Join": [
            "",
            [
              "/",
              {
                "Fn::GetAtt": [
                  "ResourceNamePrefixesGetPrefixResource96A10E6E",
                  "oneWordPrefix"
                ]
              },
              "/installer-access-logs-bucket-name"
            ]
          ]
        },
        "Type": "String",
        "Value": {
          "Ref": "InstallerAccessLogsBucket647700E9"
        }
      },
      "Metadata": {
        "aws:cdk:path": "AWSAccelerator-InstallerStack/InstallerAccessLogsBucketName/Resource"
      }
    },
    "SecureBucket747CD8C0": {
      "Type": "AWS::S3::Bucket",
      "Properties": {
        "BucketEncryption": {
          "ServerSideEncryptionConfiguration": [
            {
              "ServerSideEncryptionByDefault": {
                "KMSMasterKeyID": {
                  "Fn::GetAtt": [
                    "InstallerKey2A6A8C6D",
                    "Arn"
                  ]
                },
                "SSEAlgorithm": "aws:kms"
              }
            }
          ]
        },
        "BucketName": {
          "Fn::Join": [
            "",
            [
              {
                "Fn::GetAtt": [
                  "ResourceNamePrefixesGetPrefixResource96A10E6E",
                  "lowerCasePrefix"
                ]
              },
              "-installer-",
              {
                "Ref": "AWS::AccountId"
              },
              "-",
              {
                "Ref": "AWS::Region"
              }
            ]
          ]
        },
        "LifecycleConfiguration": {
          "Rules": [
            {
              "AbortIncompleteMultipartUpload": {
                "DaysAfterInitiation": 1
              },
              "ExpirationInDays": 1825,
              "ExpiredObjectDeleteMarker": false,
              "Id": {
                "Fn::Join": [
                  "",
                  [
                    "LifecycleRule",
                    {
                      "Fn::GetAtt": [
                        "ResourceNamePrefixesGetPrefixResource96A10E6E",
                        "lowerCasePrefix"
                      ]
                    },
                    "-installer-",
                    {
                      "Ref": "AWS::AccountId"
                    },
                    "-",
                    {
                      "Ref": "AWS::Region"
                    }
                  ]
                ]
              },
              "NoncurrentVersionExpiration": {
                "NoncurrentDays": 1825
              },
              "NoncurrentVersionTransitions": [
                {
                  "StorageClass": "DEEP_ARCHIVE",
                  "TransitionInDays": 366
                }
              ],
              "Status": "Enabled",
              "Transitions": [
                {
                  "StorageClass": "DEEP_ARCHIVE",
                  "TransitionInDays": 365
                }
              ]
            }
          ]
        },
        "LoggingConfiguration": {
          "DestinationBucketName": {
            "Ref": "InstallerAccessLogsBucket647700E9"
          },
          "LogFilePrefix": {
            "Fn::Join": [
              "",
              [
                {
                  "Fn::GetAtt": [
                    "ResourceNamePrefixesGetPrefixResource96A10E6E",
                    "lowerCasePrefix"
                  ]
                },
                "-installer-",
                {
                  "Ref": "AWS::AccountId"
                },
                "-",
                {
                  "Ref": "AWS::Region"
                },
                "/"
              ]
            ]
          }
        },
        "OwnershipControls": {
          "Rules": [
            {
              "ObjectOwnership": "BucketOwnerPreferred"
            }
          ]
        },
        "PublicAccessBlockConfiguration": {
          "BlockPublicAcls": true,
          "BlockPublicPolicy": true,
          "IgnorePublicAcls": true,
          "RestrictPublicBuckets": true
        },
        "VersioningConfiguration": {
          "Status": "Enabled"
        }
      },
      "UpdateReplacePolicy": "Retain",
      "DeletionPolicy": "Retain",
      "Metadata": {
        "aws:cdk:path": "AWSAccelerator-InstallerStack/SecureBucket/Resource/Resource"
      }
    },
    "SecureBucketPolicy6374AC61": {
      "Type": "AWS::S3::BucketPolicy",
      "Properties": {
        "Bucket": {
          "Ref": "SecureBucket747CD8C0"
        },
        "PolicyDocument": {
          "Statement": [
            {
              "Action": "s3:*",
              "Condition": {
                "Bool": {
                  "aws:SecureTransport": "false"
                }
              },
              "Effect": "Deny",
              "Principal": {
                "AWS": "*"
              },
              "Resource": [
                {
                  "Fn::GetAtt": [
                    "SecureBucket747CD8C0",
                    "Arn"
                  ]
                },
                {
                  "Fn::Join": [
                    "",
                    [
                      {
                        "Fn::GetAtt": [
                          "SecureBucket747CD8C0",
                          "Arn"
                        ]
                      },
                      "/*"
                    ]
                  ]
                }
              ],
              "Sid": "deny-insecure-connections"
            }
          ],
          "Version": "2012-10-17"
        }
      },
      "Metadata": {
        "aws:cdk:path": "AWSAccelerator-InstallerStack/SecureBucket/Resource/Policy/Resource"
      }
    },
    "InstallerAdminRole7DEE4AC8": {
      "Type": "AWS::IAM::Role",
      "Properties": {
        "AssumeRolePolicyDocument": {
          "Statement": [
            {
              "Action": "sts:AssumeRole",
              "Effect": "Allow",
              "Principal": {
                "Service": "codebuild.amazonaws.com"
              }
            }
          ],
          "Version": "2012-10-17"
        },
        "ManagedPolicyArns": [
          {
            "Fn::Join": [
              "",
              [
                "arn:",
                {
                  "Ref": "AWS::Partition"
                },
                ":iam::aws:policy/AdministratorAccess"
              ]
            ]
          }
        ]
      },
      "Metadata": {
        "aws:cdk:path": "AWSAccelerator-InstallerStack/InstallerAdminRole/Resource",
        "cdk_nag": {
          "rules_to_suppress": [
            {
              "id": "AwsSolutions-IAM4",
              "reason": "Managed policies required for IAM role."
            }
          ]
        }
      }
    },
    "InstallerAdminRoleDefaultPolicy7EEE1AAB": {
      "Type": "AWS::IAM::Policy",
      "Properties": {
        "PolicyDocument": {
          "Statement": [
            {
              "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
              ],
              "Effect": "Allow",
              "Resource": [
                {
                  "Fn::Join": [
                    "",
                    [
                      "arn:",
                      {
                        "Ref": "AWS::Partition"
                      },
                      ":logs:",
                      {
                        "Ref": "AWS::Region"
                      },
                      ":",
                      {
                        "Ref": "AWS::AccountId"
                      },
                      ":log-group:/aws/codebuild/",
                      {
                        "Ref": "InstallerProject879FF821"
                      }
                    ]
                  ]
                },
                {
                  "Fn::Join": [
                    "",
                    [
                      "arn:",
                      {
                        "Ref": "AWS::Partition"
                      },
                      ":logs:",
                      {
                        "Ref": "AWS::Region"
                      },
                      ":",
                      {
                        "Ref": "AWS::AccountId"
                      },
                      ":log-group:/aws/codebuild/",
                      {
                        "Ref": "InstallerProject879FF821"
                      },
                      ":*"
                    ]
                  ]
                }
              ]
            },
            {
              "Action": [
                "codebuild:CreateReportGroup",
                "codebuild:CreateReport",
                "codebuild:UpdateReport",
                "codebuild:BatchPutTestCases",
                "codebuild:BatchPutCodeCoverages"
              ],
              "Effect": "Allow",
              "Resource": {
                "Fn::Join": [
                  "",
                  [
                    "arn:",
                    {
                      "Ref": "AWS::Partition"
                    },
                    ":codebuild:",
                    {
                      "Ref": "AWS::Region"
                    },
                    ":",
                    {
                      "Ref": "AWS::AccountId"
                    },
                    ":report-group/",
                    {
                      "Ref": "InstallerProject879FF821"
                    },
                    "-*"
                  ]
                ]
              }
            },
            {
              "Action": [
                "kms:Decrypt",
                "kms:Encrypt",
                "kms:ReEncrypt*",
                "kms:GenerateDataKey*"
              ],
              "Effect": "Allow",
              "Resource": {
                "Fn::GetAtt": [
                  "InstallerKey2A6A8C6D",
                  "Arn"
                ]
              }
            },
            {
              "Action": [
                "s3:GetObject*",
                "s3:GetBucket*",
                "s3:List*"
              ],
              "Effect": "Allow",
              "Resource": [
                {
                  "Fn::GetAtt": [
                    "SecureBucket747CD8C0",
                    "Arn"
                  ]
                },
                {
                  "Fn::Join": [
                    "",
                    [
                      {
                        "Fn::GetAtt": [
                          "SecureBucket747CD8C0",
                          "Arn"
                        ]
                      },
                      "/*"
                    ]
                  ]
                }
              ]
            },
            {
              "Action": [
                "kms:Decrypt",
                "kms:DescribeKey"
              ],
              "Effect": "Allow",
              "Resource": {
                "Fn::GetAtt": [
                  "InstallerKey2A6A8C6D",
                  "Arn"
                ]
              }
            }
          ],
          "Version": "2012-10-17"
        },
        "PolicyName": "InstallerAdminRoleDefaultPolicy7EEE1AAB",
        "Roles": [
          {
            "Ref": "InstallerAdminRole7DEE4AC8"
          }
        ]
      },
      "Metadata": {
        "aws:cdk:path": "AWSAccelerator-InstallerStack/InstallerAdminRole/DefaultPolicy/Resource",
        "cdk_nag": {
          "rules_to_suppress": [
            {
              "id": "AwsSolutions-IAM4",
              "reason": "Managed policies required for IAM role."
            },
            {
              "id": "AwsSolutions-IAM5",
              "reason": "IAM role requires wildcard permissions."
            }
          ]
        }
      }
    },
    "InstallerProject879FF821": {
      "Type": "AWS::CodeBuild::Project",
      "Properties": {
        "Artifacts": {
          "Type": "CODEPIPELINE"
        },
        "Cache": {
          "Type": "NO_CACHE"
        },
        "EncryptionKey": {
          "Fn::GetAtt": [
            "InstallerKey2A6A8C6D",
            "Arn"
          ]
        },
        "Environment": {
          "ComputeType": "BUILD_GENERAL1_MEDIUM",
          "EnvironmentVariables": [
            {
              "Name": "NODE_OPTIONS",
              "Type": "PLAINTEXT",
              "Value": "--max_old_space_size=4096"
            },
            {
              "Name": "CDK_NEW_BOOTSTRAP",
              "Type": "PLAINTEXT",
              "Value": "1"
            },
            {
              "Name": "ACCELERATOR_REPOSITORY_SOURCE",
              "Type": "PLAINTEXT",
              "Value": {
                "Ref": "RepositorySource"
              }
            },
            {
              "Name": "ACCELERATOR_REPOSITORY_OWNER",
              "Type": "PLAINTEXT",
              "Value": {
                "Ref": "RepositoryOwner"
              }
            },
            {
              "Name": "ACCELERATOR_REPOSITORY_NAME",
              "Type": "PLAINTEXT",
              "Value": {
                "Ref": "RepositoryName"
              }
            },
            {
              "Name": "ACCELERATOR_REPOSITORY_BRANCH_NAME",
              "Type": "PLAINTEXT",
              "Value": {
                "Ref": "RepositoryBranchName"
              }
            },
            {
              "Name": "USE_EXISTING_CONFIG_REPO",
              "Type": "PLAINTEXT",
              "Value": {
                "Ref": "UseExistingConfigRepo"
              }
            },
            {
              "Name": "EXISTING_CONFIG_REPOSITORY_NAME",
              "Type": "PLAINTEXT",
              "Value": {
                "Ref": "ExistingConfigRepositoryName"
              }
            },
            {
              "Name": "EXISTING_CONFIG_REPOSITORY_BRANCH_NAME",
              "Type": "PLAINTEXT",
              "Value": {
                "Ref": "ExistingConfigRepositoryBranchName"
              }
            },
            {
              "Name": "ACCELERATOR_ENABLE_APPROVAL_STAGE",
              "Type": "PLAINTEXT",
              "Value": {
                "Ref": "EnableApprovalStage"
              }
            },
            {
              "Name": "APPROVAL_STAGE_NOTIFY_EMAIL_LIST",
              "Type": "PLAINTEXT",
              "Value": {
                "Fn::Join": [
                  ",",
                  {
                    "Ref": "ApprovalStageNotifyEmailList"
                  }
                ]
              }
            },
            {
              "Name": "MANAGEMENT_ACCOUNT_EMAIL",
              "Type": "PLAINTEXT",
              "Value": {
                "Ref": "ManagementAccountEmail"
              }
            },
            {
              "Name": "LOG_ARCHIVE_ACCOUNT_EMAIL",
              "Type": "PLAINTEXT",
              "Value": {
                "Ref": "LogArchiveAccountEmail"
              }
            },
            {
              "Name": "AUDIT_ACCOUNT_EMAIL",
              "Type": "PLAINTEXT",
              "Value": {
                "Ref": "AuditAccountEmail"
              }
            },
            {
              "Name": "CONTROL_TOWER_ENABLED",
              "Type": "PLAINTEXT",
              "Value": {
                "Ref": "ControlTowerEnabled"
              }
            },
            {
              "Name": "ACCELERATOR_PREFIX",
              "Type": "PLAINTEXT",
              "Value": {
                "Fn::GetAtt": [
                  "ResourceNamePrefixesGetPrefixResource96A10E6E",
                  "acceleratorPrefix"
                ]
              }
            },
            {
              "Name": "INSTALLER_STACK_NAME",
              "Type": "PLAINTEXT",
              "Value": "AWSAccelerator-InstallerStack"
            },
            {
              "Name": "ENABLE_DIAGNOSTICS_PACK",
              "Type": "PLAINTEXT",
              "Value": {
                "Ref": "EnableDiagnosticsPack"
              }
            },
            {
              "Name": "PIPELINE_ACCOUNT_ID",
              "Type": "PLAINTEXT",
              "Value": {
                "Ref": "AWS::AccountId"
              }
            }
          ],
          "Image": "aws/codebuild/standard:6.0",
          "ImagePullCredentialsType": "CODEBUILD",
          "PrivilegedMode": false,
          "Type": "LINUX_CONTAINER"
        },
        "Name": {
          "Fn::Join": [
            "",
            [
              {
                "Fn::GetAtt": [
                  "ResourceNamePrefixesGetPrefixResource96A10E6E",
                  "acceleratorPrefix"
                ]
              },
              "-InstallerProject"
            ]
          ]
        },
        "ServiceRole": {
          "Fn::GetAtt": [
            "InstallerAdminRole7DEE4AC8",
            "Arn"
          ]
        },
        "Source": {
          "BuildSpec": {
            "Fn::Join": [
              "",
              [
                "version: \"0.2\"\nphases:\n  install:\n    runtime-versions:\n      nodejs: 16\n  pre_build:\n    commands:\n      - ENABLE_EXTERNAL_PIPELINE_ACCOUNT=\"no\"\n      - if [ ! -z \"$MANAGEMENT_ACCOUNT_ID\" ] && [ ! -z \"$MANAGEMENT_ACCOUNT_ROLE_NAME\" ]; then ENABLE_EXTERNAL_PIPELINE_ACCOUNT=\"yes\"; fi\n      - set -e && if ! aws cloudformation describe-stacks --stack-name ",
                {
                  "Fn::GetAtt": [
                    "ResourceNamePrefixesGetPrefixResource96A10E6E",
                    "acceleratorPrefix"
                  ]
                },
                "-CDKToolkit --region ",
                {
                  "Ref": "AWS::Region"
                },
                "; then BOOTSTRAPPED_HOME=\"no\"; fi\n      - set -e && if ! aws cloudformation describe-stacks --stack-name ",
                {
                  "Fn::GetAtt": [
                    "ResourceNamePrefixesGetPrefixResource96A10E6E",
                    "acceleratorPrefix"
                  ]
                },
                "-CDKToolkit --region ",
                {
                  "Fn::FindInMap": [
                    "GlobalRegionMap",
                    {
                      "Ref": "AWS::Partition"
                    },
                    "regionName"
                  ]
                },
                "; then BOOTSTRAPPED_GLOBAL=\"no\"; fi\n      - ENABLE_DIAGNOSTICS_PACK=",
                {
                  "Ref": "EnableDiagnosticsPack"
                },
                "\n  build:\n    commands:\n      - cd source\n      - |-\n        if [ \"",
                {
                  "Ref": "AWS::Partition"
                },
                "\" = \"aws-cn\" ]; then\n                          sed -i \"s#registry.yarnpkg.com#registry.npmmirror.com#g\" yarn.lock;\n                          set -e && yarn config set registry https://registry.npmmirror.com\n                       fi\n      - yarn install\n      - yarn build\n      - cd packages/@aws-accelerator/installer\n      - set -e && if [ \"$BOOTSTRAPPED_HOME\" = \"no\" ]; then yarn run cdk bootstrap --toolkitStackName ",
                {
                  "Fn::GetAtt": [
                    "ResourceNamePrefixesGetPrefixResource96A10E6E",
                    "acceleratorPrefix"
                  ]
                },
                "-CDKToolkit aws://",
                {
                  "Ref": "AWS::AccountId"
                },
                "/",
                {
                  "Ref": "AWS::Region"
                },
                " --qualifier accel; fi\n      - set -e &&  if [ \"$BOOTSTRAPPED_GLOBAL\" = \"no\" ]; then yarn run cdk bootstrap --toolkitStackName ",
                {
                  "Fn::GetAtt": [
                    "ResourceNamePrefixesGetPrefixResource96A10E6E",
                    "acceleratorPrefix"
                  ]
                },
                "-CDKToolkit aws://",
                {
                  "Ref": "AWS::AccountId"
                },
                "/",
                {
                  "Fn::FindInMap": [
                    "GlobalRegionMap",
                    {
                      "Ref": "AWS::Partition"
                    },
                    "regionName"
                  ]
                },
                " --qualifier accel; fi\n      - |-\n        set -e && if [ $ENABLE_EXTERNAL_PIPELINE_ACCOUNT = \"yes\" ]; then\n                          export $(printf \"AWS_ACCESS_KEY_ID=%s AWS_SECRET_ACCESS_KEY=%s AWS_SESSION_TOKEN=%s\" $(aws sts assume-role --role-arn arn:",
                {
                  "Ref": "AWS::Partition"
                },
                ":iam::\"$MANAGEMENT_ACCOUNT_ID\":role/\"$MANAGEMENT_ACCOUNT_ROLE_NAME\" --role-session-name acceleratorAssumeRoleSession --query \"Credentials.[AccessKeyId,SecretAccessKey,SessionToken]\" --output text));\n                          if ! aws cloudformation describe-stacks --stack-name ",
                {
                  "Fn::GetAtt": [
                    "ResourceNamePrefixesGetPrefixResource96A10E6E",
                    "acceleratorPrefix"
                  ]
                },
                "-CDKToolkit --region ",
                {
                  "Ref": "AWS::Region"
                },
                "; then MGMT_BOOTSTRAPPED_HOME=\"no\"; fi;\n                          if ! aws cloudformation describe-stacks --stack-name ",
                {
                  "Fn::GetAtt": [
                    "ResourceNamePrefixesGetPrefixResource96A10E6E",
                    "acceleratorPrefix"
                  ]
                },
                "-CDKToolkit --region ",
                {
                  "Fn::FindInMap": [
                    "GlobalRegionMap",
                    {
                      "Ref": "AWS::Partition"
                    },
                    "regionName"
                  ]
                },
                "; then MGMT_BOOTSTRAPPED_GLOBAL=\"no\"; fi;\n                          if [ \"$MGMT_BOOTSTRAPPED_HOME\" = \"no\" ]; then yarn run cdk bootstrap --toolkitStackName ",
                {
                  "Fn::GetAtt": [
                    "ResourceNamePrefixesGetPrefixResource96A10E6E",
                    "acceleratorPrefix"
                  ]
                },
                "-CDKToolkit aws://$MANAGEMENT_ACCOUNT_ID/",
                {
                  "Ref": "AWS::Region"
                },
                " --qualifier accel; fi;\n                          if [ \"$MGMT_BOOTSTRAPPED_GLOBAL\" = \"no\" ]; then yarn run cdk bootstrap --toolkitStackName ",
                {
                  "Fn::GetAtt": [
                    "ResourceNamePrefixesGetPrefixResource96A10E6E",
                    "acceleratorPrefix"
                  ]
                },
                "-CDKToolkit aws://$MANAGEMENT_ACCOUNT_ID/",
                {
                  "Fn::FindInMap": [
                    "GlobalRegionMap",
                    {
                      "Ref": "AWS::Partition"
                    },
                    "regionName"
                  ]
                },
                " --qualifier accel; fi;\n                          unset AWS_ACCESS_KEY_ID;\n                          unset AWS_SECRET_ACCESS_KEY;\n                          unset AWS_SESSION_TOKEN;\n                       fi\n      - cd ../accelerator\n      - |-\n        aws ssm get-parameter --name /accelerator/migration --query \"Parameter.Value\" 2> /dev/null\n                          status=$?\n                          if [ $status -ne 0 ]; then\n                            echo \"No SSM Parameter found, setting ENABLE_ASEA_MIGRATION to false\";\n                            export ENABLE_ASEA_MIGRATION=false\n                          else\n                            echo \"SSM Parameter Found, setting ENABLE_ASEA_MIGRATION to true\"\n                            export ENABLE_ASEA_MIGRATION=true\n                          fi;\n      - |-\n        set -e && if [ $ENABLE_DIAGNOSTICS_PACK = \"Yes\" ]; then\n                        yarn run ts-node --transpile-only cdk.ts deploy --require-approval never --stage diagnostics-pack --account ",
                {
                  "Ref": "AWS::AccountId"
                },
                " --region ",
                {
                  "Ref": "AWS::Region"
                },
                " --partition ",
                {
                  "Ref": "AWS::Partition"
                },
                "\n                      fi\n      - set -e && yarn run ts-node --transpile-only cdk.ts deploy --require-approval never --stage pipeline --account ",
                {
                  "Ref": "AWS::AccountId"
                },
                " --region ",
                {
                  "Ref": "AWS::Region"
                },
                " --partition ",
                {
                  "Ref": "AWS::Partition"
                },
                "\n      - set -e && if [ \"$ENABLE_TESTER\" = \"true\" ]; then yarn run ts-node --transpile-only cdk.ts deploy --require-approval never --stage tester-pipeline --account ",
                {
                  "Ref": "AWS::AccountId"
                },
                " --region ",
                {
                  "Ref": "AWS::Region"
                },
                "; fi\n  post_build:\n    commands:\n      - |-\n        if [ $CODEBUILD_BUILD_SUCCEEDING -eq 1 ]; then\n                        inprogress_status_count=$(aws codepipeline get-pipeline-state --name \"",
                {
                  "Fn::GetAtt": [
                    "ResourceNamePrefixesGetPrefixResource96A10E6E",
                    "acceleratorPrefix"
                  ]
                },
                "-Pipeline\" | grep '\"status\": \"InProgress\"' | grep -v grep | wc -l) && \n                        if [ $inprogress_status_count -eq 0 ]; then\n                        set -e && aws codepipeline start-pipeline-execution --name \"",
                {
                  "Fn::GetAtt": [
                    "ResourceNamePrefixesGetPrefixResource96A10E6E",
                    "acceleratorPrefix"
                  ]
                },
                "-Pipeline\";\n                          fi\n                       fi\n"
              ]
            ]
          },
          "Type": "CODEPIPELINE"
        }
      },
      "Metadata": {
        "aws:cdk:path": "AWSAccelerator-InstallerStack/InstallerProject/Resource",
        "cdk_nag": {
          "rules_to_suppress": [
            {
              "id": "AwsSolutions-CB3",
              "reason": "Project requires access to the Docker daemon."
            }
          ]
        }
      }
    },
    "CodeCommitPipelineRole5C35E76C": {
      "Type": "AWS::IAM::Role",
      "Properties": {
        "AssumeRolePolicyDocument": {
          "Statement": [
            {
              "Action": "sts:AssumeRole",
              "Effect": "Allow",
              "Principal": {
                "Service": "codepipeline.amazonaws.com"
              }
            }
          ],
          "Version": "2012-10-17"
        }
      },
      "Metadata": {
        "aws:cdk:path": "AWSAccelerator-InstallerStack/CodeCommitPipelineRole/Resource"
      },
      "Condition": "UseCodeCommitCondition"
    },
    "CodeCommitPipelineRoleDefaultPolicyDE8B332B": {
      "Type": "AWS::IAM::Policy",
      "Properties": {
        "PolicyDocument": {
          "Statement": [
            {
              "Action": [
                "s3:GetObject*",
                "s3:GetBucket*",
                "s3:List*",
                "s3:DeleteObject*",
                "s3:PutObject",
                "s3:PutObjectLegalHold",
                "s3:PutObjectRetention",
                "s3:PutObjectTagging",
                "s3:PutObjectVersionTagging",
                "s3:Abort*"
              ],
              "Effect": "Allow",
              "Resource": [
                {
                  "Fn::GetAtt": [
                    "SecureBucket747CD8C0",
                    "Arn"
                  ]
                },
                {
                  "Fn::Join": [
                    "",
                    [
                      {
                        "Fn::GetAtt": [
                          "SecureBucket747CD8C0",
                          "Arn"
                        ]
                      },
                      "/*"
                    ]
                  ]
                }
              ]
            },
            {
              "Action": [
                "kms:Decrypt",
                "kms:DescribeKey",
                "kms:Encrypt",
                "kms:ReEncrypt*",
                "kms:GenerateDataKey*"
              ],
              "Effect": "Allow",
              "Resource": {
                "Fn::GetAtt": [
                  "InstallerKey2A6A8C6D",
                  "Arn"
                ]
              }
            },
            {
              "Action": "sts:AssumeRole",
              "Effect": "Allow",
              "Resource": {
                "Fn::GetAtt": [
                  "CodeCommitPipelineSourceCodePipelineActionRoleFB176191",
                  "Arn"
                ]
              }
            },
            {
              "Action": "sts:AssumeRole",
              "Effect": "Allow",
              "Resource": {
                "Fn::GetAtt": [
                  "CodeCommitPipelineRole5C35E76C",
                  "Arn"
                ]
              }
            },
            {
              "Action": [
                "codebuild:BatchGetBuilds",
                "codebuild:StartBuild",
                "codebuild:StopBuild"
              ],
              "Effect": "Allow",
              "Resource": {
                "Fn::GetAtt": [
                  "InstallerProject879FF821",
                  "Arn"
                ]
              }
            }
          ],
          "Version": "2012-10-17"
        },
        "PolicyName": "CodeCommitPipelineRoleDefaultPolicyDE8B332B",
        "Roles": [
          {
            "Ref": "CodeCommitPipelineRole5C35E76C"
          }
        ]
      },
      "Metadata": {
        "aws:cdk:path": "AWSAccelerator-InstallerStack/CodeCommitPipelineRole/DefaultPolicy/Resource",
        "cdk_nag": {
          "rules_to_suppress": [
            {
              "id": "AwsSolutions-IAM5",
              "reason": "IAM role requires wildcard permissions."
            }
          ]
        }
      },
      "Condition": "UseCodeCommitCondition"
    },
    "CodeCommitPipeline2208527B": {
      "Type": "AWS::CodePipeline::Pipeline",
      "Properties": {
        "ArtifactStore": {
          "EncryptionKey": {
            "Id": {
              "Fn::GetAtt": [
                "InstallerKey2A6A8C6D",
                "Arn"
              ]
            },
            "Type": "KMS"
          },
          "Location": {
            "Ref": "SecureBucket747CD8C0"
          },
          "Type": "S3"
        },
        "Name": {
          "Fn::Join": [
            "",
            [
              {
                "Fn::GetAtt": [
                  "ResourceNamePrefixesGetPrefixResource96A10E6E",
                  "acceleratorPrefix"
                ]
              },
              "-Installer"
            ]
          ]
        },
        "RestartExecutionOnUpdate": true,
        "RoleArn": {
          "Fn::GetAtt": [
            "CodeCommitPipelineRole5C35E76C",
            "Arn"
          ]
        },
        "Stages": [
          {
            "Actions": [
              {
                "ActionTypeId": {
                  "Category": "Source",
                  "Owner": "AWS",
                  "Provider": "CodeCommit",
                  "Version": "1"
                },
                "Configuration": {
                  "RepositoryName": {
                    "Ref": "RepositoryName"
                  },
                  "BranchName": {
                    "Ref": "RepositoryBranchName"
                  },
                  "PollForSourceChanges": false
                },
                "Name": "Source",
                "OutputArtifacts": [
                  {
                    "Name": "Source"
                  }
                ],
                "RoleArn": {
                  "Fn::GetAtt": [
                    "CodeCommitPipelineSourceCodePipelineActionRoleFB176191",
                    "Arn"
                  ]
                },
                "RunOrder": 1
              }
            ],
            "Name": "Source"
          },
          {
            "Actions": [
              {
                "ActionTypeId": {
                  "Category": "Build",
                  "Owner": "AWS",
                  "Provider": "CodeBuild",
                  "Version": "1"
                },
                "Configuration": {
                  "ProjectName": {
                    "Ref": "InstallerProject879FF821"
                  }
                },
                "InputArtifacts": [
                  {
                    "Name": "Source"
                  }
                ],
                "Name": "Install",
                "RoleArn": {
                  "Fn::GetAtt": [
                    "CodeCommitPipelineRole5C35E76C",
                    "Arn"
                  ]
                },
                "RunOrder": 1
              }
            ],
            "Name": "Install"
          }
        ]
      },
      "DependsOn": [
        "CodeCommitPipelineRoleDefaultPolicyDE8B332B",
        "CodeCommitPipelineRole5C35E76C"
      ],
      "Metadata": {
        "aws:cdk:path": "AWSAccelerator-InstallerStack/CodeCommitPipeline/Resource"
      },
      "Condition": "UseCodeCommitCondition"
    },
    "CodeCommitPipelineSourceCodePipelineActionRoleFB176191": {
      "Type": "AWS::IAM::Role",
      "Properties": {
        "AssumeRolePolicyDocument": {
          "Statement": [
            {
              "Action": "sts:AssumeRole",
              "Effect": "Allow",
              "Principal": {
                "AWS": {
                  "Fn::Join": [
                    "",
                    [
                      "arn:",
                      {
                        "Ref": "AWS::Partition"
                      },
                      ":iam::",
                      {
                        "Ref": "AWS::AccountId"
                      },
                      ":root"
                    ]
                  ]
                }
              }
            }
          ],
          "Version": "2012-10-17"
        }
      },
      "Metadata": {
        "aws:cdk:path": "AWSAccelerator-InstallerStack/CodeCommitPipeline/Source/Source/CodePipelineActionRole/Resource"
      },
      "Condition": "UseCodeCommitCondition"
    },
    "CodeCommitPipelineSourceCodePipelineActionRoleDefaultPolicyF71E0C0D": {
      "Type": "AWS::IAM::Policy",
      "Properties": {
        "PolicyDocument": {
          "Statement": [
            {
              "Action": [
                "s3:GetObject*",
                "s3:GetBucket*",
                "s3:List*",
                "s3:DeleteObject*",
                "s3:PutObject",
                "s3:PutObjectLegalHold",
                "s3:PutObjectRetention",
                "s3:PutObjectTagging",
                "s3:PutObjectVersionTagging",
                "s3:Abort*"
              ],
              "Effect": "Allow",
              "Resource": [
                {
                  "Fn::GetAtt": [
                    "SecureBucket747CD8C0",
                    "Arn"
                  ]
                },
                {
                  "Fn::Join": [
                    "",
                    [
                      {
                        "Fn::GetAtt": [
                          "SecureBucket747CD8C0",
                          "Arn"
                        ]
                      },
                      "/*"
                    ]
                  ]
                }
              ]
            },
            {
              "Action": [
                "kms:Decrypt",
                "kms:DescribeKey",
                "kms:Encrypt",
                "kms:ReEncrypt*",
                "kms:GenerateDataKey*"
              ],
              "Effect": "Allow",
              "Resource": {
                "Fn::GetAtt": [
                  "InstallerKey2A6A8C6D",
                  "Arn"
                ]
              }
            },
            {
              "Action": [
                "codecommit:GetBranch",
                "codecommit:GetCommit",
                "codecommit:UploadArchive",
                "codecommit:GetUploadArchiveStatus",
                "codecommit:CancelUploadArchive"
              ],
              "Effect": "Allow",
              "Resource": {
                "Fn::Join": [
                  "",
                  [
                    "arn:",
                    {
                      "Ref": "AWS::Partition"
                    },
                    ":codecommit:",
                    {
                      "Ref": "AWS::Region"
                    },
                    ":",
                    {
                      "Ref": "AWS::AccountId"
                    },
                    ":",
                    {
                      "Ref": "RepositoryName"
                    }
                  ]
                ]
              }
            }
          ],
          "Version": "2012-10-17"
        },
        "PolicyName": "CodeCommitPipelineSourceCodePipelineActionRoleDefaultPolicyF71E0C0D",
        "Roles": [
          {
            "Ref": "CodeCommitPipelineSourceCodePipelineActionRoleFB176191"
          }
        ]
      },
      "Metadata": {
        "aws:cdk:path": "AWSAccelerator-InstallerStack/CodeCommitPipeline/Source/Source/CodePipelineActionRole/DefaultPolicy/Resource",
        "cdk_nag": {
          "rules_to_suppress": [
            {
              "id": "AwsSolutions-IAM5",
              "reason": "IAM role requires wildcard permissions."
            }
          ]
        }
      },
      "Condition": "UseCodeCommitCondition"
    },
    "GitHubPipelineRole6F4DEF1B": {
      "Type": "AWS::IAM::Role",
      "Properties": {
        "AssumeRolePolicyDocument": {
          "Statement": [
            {
              "Action": "sts:AssumeRole",
              "Effect": "Allow",
              "Principal": {
                "Service": "codepipeline.amazonaws.com"
              }
            }
          ],
          "Version": "2012-10-17"
        }
      },
      "Metadata": {
        "aws:cdk:path": "AWSAccelerator-InstallerStack/GitHubPipelineRole/Resource"
      },
      "Condition": "UseGitHubCondition"
    },
    "GitHubPipelineRoleDefaultPolicyD82457D6": {
      "Type": "AWS::IAM::Policy",
      "Properties": {
        "PolicyDocument": {
          "Statement": [
            {
              "Action": [
                "s3:GetObject*",
                "s3:GetBucket*",
                "s3:List*",
                "s3:DeleteObject*",
                "s3:PutObject",
                "s3:PutObjectLegalHold",
                "s3:PutObjectRetention",
                "s3:PutObjectTagging",
                "s3:PutObjectVersionTagging",
                "s3:Abort*"
              ],
              "Effect": "Allow",
              "Resource": [
                {
                  "Fn::GetAtt": [
                    "SecureBucket747CD8C0",
                    "Arn"
                  ]
                },
                {
                  "Fn::Join": [
                    "",
                    [
                      {
                        "Fn::GetAtt": [
                          "SecureBucket747CD8C0",
                          "Arn"
                        ]
                      },
                      "/*"
                    ]
                  ]
                }
              ]
            },
            {
              "Action": [
                "kms:Decrypt",
                "kms:DescribeKey",
                "kms:Encrypt",
                "kms:ReEncrypt*",
                "kms:GenerateDataKey*"
              ],
              "Effect": "Allow",
              "Resource": {
                "Fn::GetAtt": [
                  "InstallerKey2A6A8C6D",
                  "Arn"
                ]
              }
            },
            {
              "Action": "sts:AssumeRole",
              "Effect": "Allow",
              "Resource": {
                "Fn::GetAtt": [
                  "GitHubPipelineRole6F4DEF1B",
                  "Arn"
                ]
              }
            },
            {
              "Action": [
                "codebuild:BatchGetBuilds",
                "codebuild:StartBuild",
                "codebuild:StopBuild"
              ],
              "Effect": "Allow",
              "Resource": {
                "Fn::GetAtt": [
                  "InstallerProject879FF821",
                  "Arn"
                ]
              }
            }
          ],
          "Version": "2012-10-17"
        },
        "PolicyName": "GitHubPipelineRoleDefaultPolicyD82457D6",
        "Roles": [
          {
            "Ref": "GitHubPipelineRole6F4DEF1B"
          }
        ]
      },
      "Metadata": {
        "aws:cdk:path": "AWSAccelerator-InstallerStack/GitHubPipelineRole/DefaultPolicy/Resource",
        "cdk_nag": {
          "rules_to_suppress": [
            {
              "id": "AwsSolutions-IAM5",
              "reason": "IAM role requires wildcard permissions."
            }
          ]
        }
      },
      "Condition": "UseGitHubCondition"
    },
    "GitHubPipeline7B79E906": {
      "Type": "AWS::CodePipeline::Pipeline",
      "Properties": {
        "ArtifactStore": {
          "EncryptionKey": {
            "Id": {
              "Fn::GetAtt": [
                "InstallerKey2A6A8C6D",
                "Arn"
              ]
            },
            "Type": "KMS"
          },
          "Location": {
            "Ref": "SecureBucket747CD8C0"
          },
          "Type": "S3"
        },
        "Name": {
          "Fn::Join": [
            "",
            [
              {
                "Fn::GetAtt": [
                  "ResourceNamePrefixesGetPrefixResource96A10E6E",
                  "acceleratorPrefix"
                ]
              },
              "-Installer"
            ]
          ]
        },
        "RestartExecutionOnUpdate": true,
        "RoleArn": {
          "Fn::GetAtt": [
            "GitHubPipelineRole6F4DEF1B",
            "Arn"
          ]
        },
        "Stages": [
          {
            "Actions": [
              {
                "ActionTypeId": {
                  "Category": "Source",
                  "Owner": "ThirdParty",
                  "Provider": "GitHub",
                  "Version": "1"
                },
                "Configuration": {
                  "Owner": {
                    "Ref": "RepositoryOwner"
                  },
                  "Repo": {
                    "Ref": "RepositoryName"
                  },
                  "Branch": {
                    "Ref": "RepositoryBranchName"
                  },
                  "OAuthToken": "{{resolve:secretsmanager:accelerator/github-token:SecretString:::}}",
                  "PollForSourceChanges": false
                },
                "Name": "Source",
                "OutputArtifacts": [
                  {
                    "Name": "Source"
                  }
                ],
                "RunOrder": 1
              }
            ],
            "Name": "Source"
          },
          {
            "Actions": [
              {
                "ActionTypeId": {
                  "Category": "Build",
                  "Owner": "AWS",
                  "Provider": "CodeBuild",
                  "Version": "1"
                },
                "Configuration": {
                  "ProjectName": {
                    "Ref": "InstallerProject879FF821"
                  }
                },
                "InputArtifacts": [
                  {
                    "Name": "Source"
                  }
                ],
                "Name": "Install",
                "RoleArn": {
                  "Fn::GetAtt": [
                    "GitHubPipelineRole6F4DEF1B",
                    "Arn"
                  ]
                },
                "RunOrder": 1
              }
            ],
            "Name": "Install"
          }
        ]
      },
      "DependsOn": [
        "GitHubPipelineRoleDefaultPolicyD82457D6",
        "GitHubPipelineRole6F4DEF1B"
      ],
      "Metadata": {
        "aws:cdk:path": "AWSAccelerator-InstallerStack/GitHubPipeline/Resource"
      },
      "Condition": "UseGitHubCondition"
    },
    "UpdatePipelineLambdaRole88CE0535": {
      "Type": "AWS::IAM::Role",
      "Properties": {
        "AssumeRolePolicyDocument": {
          "Statement": [
            {
              "Action": "sts:AssumeRole",
              "Effect": "Allow",
              "Principal": {
                "Service": "lambda.amazonaws.com"
              }
            }
          ],
          "Version": "2012-10-17"
        }
      },
      "Metadata": {
        "aws:cdk:path": "AWSAccelerator-InstallerStack/UpdatePipelineLambdaRole/Resource",
        "cdk_nag": {
          "rules_to_suppress": [
            {
              "id": "AwsSolutions-IAM4",
              "reason": "Managed policies required for IAM role."
            }
          ]
        }
      },
      "Condition": "UseGitHubCondition"
    },
    "UpdatePipelineLambdaPolicy284ABC36": {
      "Type": "AWS::IAM::Policy",
      "Properties": {
        "PolicyDocument": {
          "Statement": [
            {
              "Action": [
                "codepipeline:GetPipeline",
                "codepipeline:UpdatePipeline"
              ],
              "Effect": "Allow",
              "Resource": [
                {
                  "Fn::Join": [
                    "",
                    [
                      "arn:",
                      {
                        "Ref": "AWS::Partition"
                      },
                      ":codepipeline:",
                      {
                        "Ref": "AWS::Region"
                      },
                      ":",
                      {
                        "Ref": "AWS::AccountId"
                      },
                      ":",
                      {
                        "Fn::GetAtt": [
                          "ResourceNamePrefixesGetPrefixResource96A10E6E",
                          "acceleratorPrefix"
                        ]
                      },
                      "-Installer*"
                    ]
                  ]
                },
                {
                  "Fn::Join": [
                    "",
                    [
                      "arn:",
                      {
                        "Ref": "AWS::Partition"
                      },
                      ":codepipeline:",
                      {
                        "Ref": "AWS::Region"
                      },
                      ":",
                      {
                        "Ref": "AWS::AccountId"
                      },
                      ":",
                      {
                        "Fn::GetAtt": [
                          "ResourceNamePrefixesGetPrefixResource96A10E6E",
                          "acceleratorPrefix"
                        ]
                      },
                      "-Pipeline*"
                    ]
                  ]
                }
              ]
            },
            {
              "Action": [
                "secretsmanager:GetResourcePolicy",
                "secretsmanager:GetSecretValue",
                "secretsmanager:DescribeSecret",
                "secretsmanager:ListSecretVersionIds"
              ],
              "Effect": "Allow",
              "Resource": {
                "Fn::Join": [
                  "",
                  [
                    "arn:",
                    {
                      "Ref": "AWS::Partition"
                    },
                    ":secretsmanager:",
                    {
                      "Ref": "AWS::Region"
                    },
                    ":",
                    {
                      "Ref": "AWS::AccountId"
                    },
                    ":secret:accelerator/github-token*"
                  ]
                ]
              }
            },
            {
              "Action": "kms:Decrypt",
              "Effect": "Allow",
              "Resource": "*"
            },
            {
              "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
              ],
              "Effect": "Allow",
              "Resource": "*"
            },
            {
              "Action": "iam:PassRole",
              "Effect": "Allow",
              "Resource": [
                {
                  "Fn::Join": [
                    "",
                    [
                      "arn:",
                      {
                        "Ref": "AWS::Partition"
                      },
                      ":iam::",
                      {
                        "Ref": "AWS::AccountId"
                      },
                      ":role/",
                      {
                        "Fn::GetAtt": [
                          "ResourceNamePrefixesGetPrefixResource96A10E6E",
                          "acceleratorPrefix"
                        ]
                      },
                      "-*"
                    ]
                  ]
                },
                {
                  "Fn::GetAtt": [
                    "GitHubPipelineRole6F4DEF1B",
                    "Arn"
                  ]
                }
              ]
            }
          ],
          "Version": "2012-10-17"
        },
        "PolicyName": "UpdatePipelineLambdaPolicy284ABC36",
        "Roles": [
          {
            "Ref": "UpdatePipelineLambdaRole88CE0535"
          }
        ]
      },
      "Metadata": {
        "cfn_nag": {
          "rules_to_suppress": [
            {
              "id": "W12",
              "reason": "IAM policy should not allow * resource."
            }
          ]
        },
        "cdk_nag": {
          "rules_to_suppress": [
            {
              "id": "AwsSolutions-IAM5",
              "reason": "IAM role requires wildcard permissions."
            }
          ]
        }
      },
      "Condition": "UseGitHubCondition"
    },
    "UpdatePipelineGithubTokenFunction29B64F2E": {
      "Type": "AWS::Lambda::Function",
      "Properties": {
        "Code": {
          "ZipFile": "/**\n *  Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.\n *\n *  Licensed under the Apache License, Version 2.0 (the \"License\"). You may not use this file except in compliance\n *  with the License. A copy of the License is located at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n *  or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES\n *  OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions\n *  and limitations under the License.\n */\n\nconst AWS = require('aws-sdk');\n\nconst secretsManager = new AWS.SecretsManager({});\nconst codePipeline = new AWS.CodePipeline({});\nconst installerPipelineName = process.env['INSTALLER_PIPELINE_NAME'] ?? '';\nconst acceleratorPipelineName = process.env['ACCELERATOR_PIPELINE_NAME'] ?? '';\nconst pipelineArray = [installerPipelineName, acceleratorPipelineName];\n\n/**\n * update-pipeline-github-token - lambda handler\n *\n * @param event\n * @returns\n */\n\nexports.handler = async (event, context) => {\n  const secretDetails = event.detail.requestParameters;\n  const secretArn = secretDetails.secretId;\n  const secretValue = await getSecretValue(secretArn);\n  await updatePipelineDetailsForBothPipelines(secretValue);\n  return {\n    statusCode: 200,\n  };\n};\n\nasync function getSecretValue(secretName) {\n  try {\n    const data = await secretsManager\n      .getSecretValue({\n        SecretId: secretName,\n      })\n      .promise();\n\n    if (!data || !data.SecretString) {\n      throw new Error(`Secret ${secretName} didn't exist.`);\n    }\n    console.log(`Retrieved secret: ${secretName}...`);\n    return data.SecretString;\n  } catch (error) {\n    console.log(error);\n    throw new Error(`Error retrieving secret: ${secretName}.`);\n  }\n}\n\nasync function updateCodePipelineSourceStage(pipelineDetails, secretValue) {\n  const pipelineStages = pipelineDetails.pipeline.stages;\n  const sourceStage = pipelineStages.find(o => o.name == 'Source');\n  const sourceAction = sourceStage.actions.find(a => a.name == 'Source');\n  if (sourceAction.actionTypeId.provider !== 'GitHub') {\n    console.log('Pipeline source is not GitHub, no action will be taken.');\n    return;\n  }\n  sourceAction.configuration.OAuthToken = secretValue;\n\n  return pipelineDetails;\n}\n\nasync function getPipelineDetails(pipelineName) {\n  //This function retrieves the original Code Pipeline structure, so we can update it.\n  const getPipelineParams = {\n    name: pipelineName,\n  };\n  console.log(`Retrieving existing pipeline configuration for: ${pipelineName}...`);\n  const pipelineObject = await codePipeline.getPipeline(getPipelineParams).promise();\n  console.log(JSON.stringify(pipelineObject));\n  return pipelineObject;\n}\n\nasync function updatePipeline(updatedPipelineDetails) {\n  //Remove metadata from getPipelineOutput to use as updatePipelineInput\n  delete updatedPipelineDetails.metadata;\n  console.log(`Updating pipeline with new OAuth Token...`);\n  return codePipeline.updatePipeline(updatedPipelineDetails).promise();\n}\n\nasync function updatePipelineDetailsForBothPipelines(secretValue) {\n  for (const pipeline of pipelineArray) {\n    try {\n      const pipelineDetails = await getPipelineDetails(pipeline);\n      const updatedPipelineDetails = await updateCodePipelineSourceStage(pipelineDetails, secretValue);\n      if (updatedPipelineDetails) {\n        await updatePipeline(updatedPipelineDetails);\n      }\n    } catch (error) {\n      console.error(error);\n      throw new Error(`Error occurred while updating pipeline ${pipeline}`);\n    }\n  }\n}\n"
        },
        "Description": "Lambda function to update CodePipeline OAuth Token",
        "Environment": {
          "Variables": {
            "ACCELERATOR_PIPELINE_NAME": {
              "Fn::Join": [
                "",
                [
                  {
                    "Fn::GetAtt": [
                      "ResourceNamePrefixesGetPrefixResource96A10E6E",
                      "acceleratorPrefix"
                    ]
                  },
                  "-Pipeline"
                ]
              ]
            },
            "INSTALLER_PIPELINE_NAME": {
              "Fn::Join": [
                "",
                [
                  {
                    "Fn::GetAtt": [
                      "ResourceNamePrefixesGetPrefixResource96A10E6E",
                      "acceleratorPrefix"
                    ]
                  },
                  "-Installer"
                ]
              ]
            }
          }
        },
        "Handler": "index.handler",
        "KmsKeyArn": {
          "Fn::GetAtt": [
            "InstallerKey2A6A8C6D",
            "Arn"
          ]
        },
        "Role": {
          "Fn::GetAtt": [
            "UpdatePipelineLambdaRole88CE0535",
            "Arn"
          ]
        },
        "Runtime": "nodejs16.x",
        "Timeout": 60
      },
      "DependsOn": [
        "UpdatePipelineLambdaRole88CE0535"
      ],
      "Metadata": {
        "aws:cdk:path": "AWSAccelerator-InstallerStack/UpdatePipelineGithubTokenFunction/Resource",
        "cfn_nag": {
          "rules_to_suppress": [
            {
              "id": "W58",
              "reason": "CloudWatch Logs are enabled in AWSLambdaBasicExecutionRole"
            },
            {
              "id": "W89",
              "reason": "This function supports infrastructure deployment and is not deployed inside a VPC."
            },
            {
              "id": "W92",
              "reason": "This function supports infrastructure deployment and does not require setting ReservedConcurrentExecutions."
            }
          ]
        }
      },
      "Condition": "UseGitHubCondition"
    },
    "UpdatePipelineGithubTokenRule79D83132": {
      "Type": "AWS::Events::Rule",
      "Properties": {
        "Description": "Rule to trigger Lambda Function when the Github Accelerator Token has been updated.",
        "EventPattern": {
          "detail-type": [
            "AWS API Call via CloudTrail"
          ],
          "detail": {
            "eventSource": [
              "secretsmanager.amazonaws.com"
            ],
            "eventName": [
              "UpdateSecret",
              "PutSecretValue"
            ],
            "requestParameters": {
              "secretId": [
                {
                  "prefix": {
                    "Fn::Join": [
                      "",
                      [
                        "arn:",
                        {
                          "Ref": "AWS::Partition"
                        },
                        ":secretsmanager:",
                        {
                          "Ref": "AWS::Region"
                        },
                        ":",
                        {
                          "Ref": "AWS::AccountId"
                        },
                        ":secret:accelerator/github-token"
                      ]
                    ]
                  }
                }
              ]
            }
          }
        },
        "State": "ENABLED",
        "Targets": [
          {
            "Arn": {
              "Fn::GetAtt": [
                "UpdatePipelineGithubTokenFunction29B64F2E",
                "Arn"
              ]
            },
            "Id": "Target0",
            "RetryPolicy": {
              "MaximumEventAgeInSeconds": 14400,
              "MaximumRetryAttempts": 2
            }
          }
        ]
      },
      "Metadata": {
        "aws:cdk:path": "AWSAccelerator-InstallerStack/UpdatePipelineGithubTokenRule/Resource"
      },
      "Condition": "UseGitHubCondition"
    },
    "UpdatePipelineGithubTokenRuleAllowEventRuleAWSAcceleratorInstallerStackUpdatePipelineGithubTokenFunction2367C02A6E48B7BC": {
      "Type": "AWS::Lambda::Permission",
      "Properties": {
        "Action": "lambda:InvokeFunction",
        "FunctionName": {
          "Fn::GetAtt": [
            "UpdatePipelineGithubTokenFunction29B64F2E",
            "Arn"
          ]
        },
        "Principal": "events.amazonaws.com",
        "SourceArn": {
          "Fn::GetAtt": [
            "UpdatePipelineGithubTokenRule79D83132",
            "Arn"
          ]
        }
      },
      "Metadata": {
        "aws:cdk:path": "AWSAccelerator-InstallerStack/UpdatePipelineGithubTokenRule/AllowEventRuleAWSAcceleratorInstallerStackUpdatePipelineGithubTokenFunction2367C02A"
      },
      "Condition": "UseGitHubCondition"
    },
    "UpdatePipelineGithubTokenFunctionLogGroupFCE3723A": {
      "Type": "AWS::Logs::LogGroup",
      "Properties": {
        "LogGroupName": {
          "Fn::Join": [
            "",
            [
              "/aws/lambda/",
              {
                "Ref": "UpdatePipelineGithubTokenFunction29B64F2E"
              }
            ]
          ]
        },
        "RetentionInDays": 731
      },
      "UpdateReplacePolicy": "Delete",
      "DeletionPolicy": "Delete",
      "Metadata": {
        "cfn_nag": {
          "rules_to_suppress": [
            {
              "id": "W84",
              "reason": "CloudWatchLogs LogGroup should specify a KMS Key Id to encrypt the log data"
            }
          ]
        }
      },
      "Condition": "UseGitHubCondition"
    }
  }
}