Description: This stack includes resources needed to deploy AWS CDK apps into this
  environment
Parameters:
  TrustedAccounts:
    Description: List of AWS accounts that are trusted to publish assets and deploy
      stacks to this environment
    Default: ''
    Type: CommaDelimitedList
  TrustedAccountsForLookup:
    Description: List of AWS accounts that are trusted to look up values in this
      environment
    Default: ''
    Type: CommaDelimitedList
  CloudFormationExecutionPolicies:
    Description: List of the ManagedPolicy ARN(s) to attach to the CloudFormation
      deployment role
    Default: ''
    Type: CommaDelimitedList
  FileAssetsBucketName:
    Description: The name of the S3 bucket used for file assets
    Default: ''
    Type: String
  FileAssetsBucketKmsKeyId:
    Description: Empty to create a new key (default), 'AWS_MANAGED_KEY' to use a managed
      S3 key, or the ID/ARN of an existing key.
    Default: ''
    Type: String
  ContainerAssetsRepositoryName:
    Description: A user-provided custom name to use for the container assets ECR repository
    Default: ''
    Type: String
  Qualifier:
    Description: An identifier to distinguish multiple bootstrap stacks in the same environment
    Default: hnb659fds
    Type: String
    # "cdk-(qualifier)-image-publishing-role-(account)-(region)" needs to be <= 64 chars
    # account = 12, region <= 14, 10 chars for qualifier and 28 for rest of role name
    AllowedPattern: "[A-Za-z0-9_-]{1,10}"
    ConstraintDescription: Qualifier must be an alphanumeric identifier of at most 10 characters
  PublicAccessBlockConfiguration:
    Description: Whether or not to enable S3 Staging Bucket Public Access Block Configuration
    Default: 'true'
    Type: 'String'
    AllowedValues: ['true', 'false']
  InputPermissionsBoundary:
    Description: Whether or not to use either the CDK supplied or custom permissions boundary
    Default: ''
    Type: 'String'
  UseExamplePermissionsBoundary:
    Default: 'false'
    AllowedValues: [ 'true', 'false' ]
    Type: String
  BootstrapVariant:
    Type: String
    Default: 'AWS CDK: Default Resources'
    Description: Describe the provenance of the resources in this bootstrap
      stack. Change this when you customize the template. To prevent accidents,
      the CDK CLI will not overwrite bootstrap stacks with a different variant.
Conditions:
  HasTrustedAccounts:
    Fn::Not:
      - Fn::Equals:
          - ''
          - Fn::Join:
              - ''
              - Ref: TrustedAccounts
  HasTrustedAccountsForLookup:
    Fn::Not:
      - Fn::Equals:
          - ''
          - Fn::Join:
              - ''
              - Ref: TrustedAccountsForLookup
  HasCloudFormationExecutionPolicies:
    Fn::Not:
      - Fn::Equals:
          - ''
          - Fn::Join:
              - ''
              - Ref: CloudFormationExecutionPolicies
  HasCustomFileAssetsBucketName:
    Fn::Not:
      - Fn::Equals:
          - ''
          - Ref: FileAssetsBucketName
  CreateNewKey:
    Fn::Equals:
      - ''
      - Ref: FileAssetsBucketKmsKeyId
  UseAwsManagedKey:
    Fn::Equals:
      - 'AWS_MANAGED_KEY'
      - Ref: FileAssetsBucketKmsKeyId
  ShouldCreatePermissionsBoundary:
    Fn::Equals:
      - 'true'
      - Ref: UseExamplePermissionsBoundary
  PermissionsBoundarySet:
    Fn::Not:
      - Fn::Equals:
        - ''
        - Ref: InputPermissionsBoundary
  HasCustomContainerAssetsRepositoryName:
    Fn::Not:
      - Fn::Equals:
          - ''
          - Ref: ContainerAssetsRepositoryName
  UsePublicAccessBlockConfiguration:
    Fn::Equals:
      - 'true'
      - Ref: PublicAccessBlockConfiguration
Resources:
  FileAssetsBucketEncryptionKey:
    Type: AWS::KMS::Key
    Properties:
      KeyPolicy:
        Statement:
          - Action:
              - kms:Create*
              - kms:Describe*
              - kms:Enable*
              - kms:List*
              - kms:Put*
              - kms:Update*
              - kms:Revoke*
              - kms:Disable*
              - kms:Get*
              - kms:Delete*
              - kms:ScheduleKeyDeletion
              - kms:CancelKeyDeletion
              - kms:GenerateDataKey
              - kms:TagResource
              - kms:UntagResource
            Effect: Allow
            Principal:
              AWS:
                Ref: AWS::AccountId
            Resource: "*"
          - Action:
              - kms:Decrypt
              - kms:DescribeKey
              - kms:Encrypt
              - kms:ReEncrypt*
              - kms:GenerateDataKey*
            Effect: Allow
            Principal:
              # Not actually everyone -- see below for Conditions
              AWS: "*"
            Resource: "*"
            Condition:
              StringEquals:
                # See https://docs.aws.amazon.com/kms/latest/developerguide/policy-conditions.html#conditions-kms-caller-account
                kms:CallerAccount:
                  Ref: AWS::AccountId
                kms:ViaService:
                  - Fn::Sub: s3.${AWS::Region}.amazonaws.com
          - Action:
              - kms:Decrypt
              - kms:DescribeKey
              - kms:Encrypt
              - kms:ReEncrypt*
              - kms:GenerateDataKey*
            Effect: Allow
            Principal:
              AWS:
                Fn::Sub: "${FilePublishingRole.Arn}"
            Resource: "*"
    Condition: CreateNewKey
    UpdateReplacePolicy: Delete
    DeletionPolicy: Delete
  FileAssetsBucketEncryptionKeyAlias:
    Condition: CreateNewKey
    Type: AWS::KMS::Alias
    Properties:
      AliasName:
        Fn::Sub: "alias/cdk-${Qualifier}-assets-key"
      TargetKeyId:
        Ref: FileAssetsBucketEncryptionKey
  StagingBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName:
        Fn::If:
          - HasCustomFileAssetsBucketName
          - Fn::Sub: "${FileAssetsBucketName}"
          - Fn::Sub: cdk-${Qualifier}-assets-${AWS::AccountId}-${AWS::Region}
      AccessControl: Private
      BucketEncryption:
        ServerSideEncryptionConfiguration:
          - ServerSideEncryptionByDefault:
              SSEAlgorithm: aws:kms
              KMSMasterKeyID:
                Fn::If:
                  - CreateNewKey
                  - Fn::Sub: "${FileAssetsBucketEncryptionKey.Arn}"
                  - Fn::If:
                    - UseAwsManagedKey
                    - Ref: AWS::NoValue
                    - Fn::Sub: "${FileAssetsBucketKmsKeyId}"
      PublicAccessBlockConfiguration:
        Fn::If:
          - UsePublicAccessBlockConfiguration
          - BlockPublicAcls: true
            BlockPublicPolicy: true
            IgnorePublicAcls: true
            RestrictPublicBuckets: true
          - Ref: AWS::NoValue
      VersioningConfiguration:
        Status: Enabled
      LifecycleConfiguration:
        Rules:
          # Objects will only be noncurrent if they are deleted via garbage collection.
          - Id: CleanupOldVersions
            Status: Enabled
            NoncurrentVersionExpiration:
              NoncurrentDays: 30
          - Id: AbortIncompleteMultipartUploads
            Status: Enabled
            AbortIncompleteMultipartUpload:
              DaysAfterInitiation: 1
    UpdateReplacePolicy: Retain
    DeletionPolicy: Retain
  StagingBucketPolicy:
    Type: 'AWS::S3::BucketPolicy'
    Properties:
      Bucket: { Ref: 'StagingBucket' }
      PolicyDocument:
        Id: 'AccessControl'
        Version: '2012-10-17'
        Statement:
          - Sid: 'AllowSSLRequestsOnly'
            Action: 's3:*'
            Effect: 'Deny'
            Resource:
              - { 'Fn::Sub': '${StagingBucket.Arn}' }
              - { 'Fn::Sub': '${StagingBucket.Arn}/*' }
            Condition:
              Bool: { 'aws:SecureTransport': 'false' }
            Principal: '*'
  ContainerAssetsRepository:
    Type: AWS::ECR::Repository
    Properties:
      ImageTagMutability: IMMUTABLE
      # Untagged images should never exist but Security Hub wants this rule to exist
      LifecyclePolicy:
        LifecyclePolicyText: |
          {
            "rules": [
              {
                "rulePriority": 1,
                "description": "Untagged images should not exist, but expire any older than one year",
                "selection": {
                  "tagStatus": "untagged",
                  "countType": "sinceImagePushed",
                  "countUnit": "days",
                  "countNumber": 365
                },
                "action": { "type": "expire" }
              }
            ]
          }
      RepositoryName:
        Fn::If:
          - HasCustomContainerAssetsRepositoryName
          - Fn::Sub: "${ContainerAssetsRepositoryName}"
          - Fn::Sub: cdk-${Qualifier}-container-assets-${AWS::AccountId}-${AWS::Region}
      RepositoryPolicyText:
        Version: "2012-10-17"
        Statement:
          # Necessary for Lambda container images
          # https://docs.aws.amazon.com/lambda/latest/dg/configuration-images.html#configuration-images-permissions
          - Sid: LambdaECRImageRetrievalPolicy
            Effect: Allow
            Principal: { Service: "lambda.amazonaws.com" }
            Action:
              - ecr:BatchGetImage
              - ecr:GetDownloadUrlForLayer
            Condition:
              StringLike:
                "aws:sourceArn": { "Fn::Sub": "arn:${AWS::Partition}:lambda:${AWS::Region}:${AWS::AccountId}:function:*" }
          # Necessary for EMR Serverless container images
          # https://docs.aws.amazon.com/emr/latest/EMR-Serverless-UserGuide/application-custom-image.html#access-repo
          - Sid: EmrServerlessImageRetrievalPolicy
            Effect: Allow
            Principal:
              Service: emr-serverless.amazonaws.com
            Action:
              - ecr:BatchGetImage
              - ecr:GetDownloadUrlForLayer
              - ecr:DescribeImages
            Condition:
              StringLike:
                "aws:sourceArn": { "Fn::Sub": "arn:${AWS::Partition}:emr-serverless:${AWS::Region}:${AWS::AccountId}:/applications/*" }
  FilePublishingRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          # allows this role to be assumed with session tags.
          # see https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html#id_session-tags_permissions-required
          - Action: sts:TagSession
            Effect: Allow
            Principal:
              AWS:
                Ref: AWS::AccountId
          - Action: sts:AssumeRole
            Effect: Allow
            Principal:
              AWS:
                Ref: AWS::AccountId
          - Fn::If:
              - HasTrustedAccounts
              - Action: sts:AssumeRole
                Effect: Allow
                Principal:
                  AWS:
                    Ref: TrustedAccounts
              - Ref: AWS::NoValue
      RoleName:
        Fn::Sub: cdk-${Qualifier}-file-publishing-role-${AWS::AccountId}-${AWS::Region}
      Tags:
        - Key: aws-cdk:bootstrap-role
          Value: file-publishing
  ImagePublishingRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          # allows this role to be assumed with session tags.
          # see https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html#id_session-tags_permissions-required
          - Action: sts:TagSession
            Effect: Allow
            Principal:
              AWS:
                Ref: AWS::AccountId
          - Action: sts:AssumeRole
            Effect: Allow
            Principal:
              AWS:
                Ref: AWS::AccountId
          - Fn::If:
              - HasTrustedAccounts
              - Action: sts:AssumeRole
                Effect: Allow
                Principal:
                  AWS:
                    Ref: TrustedAccounts
              - Ref: AWS::NoValue
      RoleName:
        Fn::Sub: cdk-${Qualifier}-image-publishing-role-${AWS::AccountId}-${AWS::Region}
      Tags:
        - Key: aws-cdk:bootstrap-role
          Value: image-publishing
  LookupRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          # allows this role to be assumed with session tags.
          # see https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html#id_session-tags_permissions-required
          - Action: sts:TagSession
            Effect: Allow
            Principal:
              AWS:
                Ref: AWS::AccountId
          - Action: sts:AssumeRole
            Effect: Allow
            Principal:
              AWS:
                Ref: AWS::AccountId
          - Fn::If:
              - HasTrustedAccountsForLookup
              - Action: sts:AssumeRole
                Effect: Allow
                Principal:
                  AWS:
                    Ref: TrustedAccountsForLookup
              - Ref: AWS::NoValue
          - Fn::If:
              - HasTrustedAccounts
              - Action: sts:AssumeRole
                Effect: Allow
                Principal:
                  AWS:
                    Ref: TrustedAccounts
              - Ref: AWS::NoValue
      RoleName:
        Fn::Sub: cdk-${Qualifier}-lookup-role-${AWS::AccountId}-${AWS::Region}
      ManagedPolicyArns:
        - Fn::Sub: "arn:${AWS::Partition}:iam::aws:policy/ReadOnlyAccess"
      Policies:
        - PolicyDocument:
            Statement:
              - Sid: DontReadSecrets
                Effect: Deny
                Action:
                  - kms:Decrypt
                Resource: "*"
            Version: '2012-10-17'
          PolicyName: LookupRolePolicy
      Tags:
        - Key: aws-cdk:bootstrap-role
          Value: lookup
  FilePublishingRoleDefaultPolicy:
    Type: AWS::IAM::Policy
    Properties:
      PolicyDocument:
        Statement:
          - Action:
              - s3:GetObject*
              - s3:GetBucket*
              - s3:GetEncryptionConfiguration
              - s3:List*
              - s3:DeleteObject*
              - s3:PutObject*
              - s3:Abort*
            Resource:
              - Fn::Sub: "${StagingBucket.Arn}"
              - Fn::Sub: "${StagingBucket.Arn}/*"
            Condition:
              StringEquals:
                aws:ResourceAccount:
                  - Fn::Sub: ${AWS::AccountId}
            Effect: Allow
          - Action:
              - kms:Decrypt
              - kms:DescribeKey
              - kms:Encrypt
              - kms:ReEncrypt*
              - kms:GenerateDataKey*
            Effect: Allow
            Resource:
              Fn::If:
                - CreateNewKey
                - Fn::Sub: "${FileAssetsBucketEncryptionKey.Arn}"
                - Fn::Sub: arn:${AWS::Partition}:kms:${AWS::Region}:${AWS::AccountId}:key/${FileAssetsBucketKmsKeyId}
        Version: '2012-10-17'
      Roles:
        - Ref: FilePublishingRole
      PolicyName:
        Fn::Sub: cdk-${Qualifier}-file-publishing-role-default-policy-${AWS::AccountId}-${AWS::Region}
  ImagePublishingRoleDefaultPolicy:
    Type: AWS::IAM::Policy
    Properties:
      PolicyDocument:
        Statement:
          - Action:
              - ecr:PutImage
              - ecr:InitiateLayerUpload
              - ecr:UploadLayerPart
              - ecr:CompleteLayerUpload
              - ecr:BatchCheckLayerAvailability
              - ecr:DescribeRepositories
              - ecr:DescribeImages
              - ecr:BatchGetImage
              - ecr:GetDownloadUrlForLayer
            Resource:
              Fn::Sub: "${ContainerAssetsRepository.Arn}"
            Effect: Allow
          - Action:
              - ecr:GetAuthorizationToken
            Resource: "*"
            Effect: Allow
        Version: '2012-10-17'
      Roles:
        - Ref: ImagePublishingRole
      PolicyName:
        Fn::Sub: cdk-${Qualifier}-image-publishing-role-default-policy-${AWS::AccountId}-${AWS::Region}
  DeploymentActionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          # allows this role to be assumed with session tags.
          # see https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html#id_session-tags_permissions-required
          - Action: sts:TagSession
            Effect: Allow
            Principal:
              AWS:
                Ref: AWS::AccountId
          - Action: sts:AssumeRole
            Effect: Allow
            Principal:
              AWS:
                Ref: AWS::AccountId
          - Fn::If:
              - HasTrustedAccounts
              - Action: sts:AssumeRole
                Effect: Allow
                Principal:
                  AWS:
                    Ref: TrustedAccounts
              - Ref: AWS::NoValue
      Policies:
        - PolicyDocument:
            Statement:
              - Sid: CloudFormationPermissions
                Effect: Allow
                Action:
                  - cloudformation:CreateChangeSet
                  - cloudformation:DeleteChangeSet
                  - cloudformation:DescribeChangeSet
                  - cloudformation:DescribeStacks
                  - cloudformation:ExecuteChangeSet
                  - cloudformation:CreateStack
                  - cloudformation:UpdateStack
                  - cloudformation:RollbackStack
                  - cloudformation:ContinueUpdateRollback
                Resource: "*"
              - Sid: PipelineCrossAccountArtifactsBucket
                # Read/write buckets in different accounts. Permissions to buckets in
                # same account are granted by bucket policies.
                #
                # Write permissions necessary to write outputs to the cross-region artifact replication bucket
                # https://aws.amazon.com/premiumsupport/knowledge-center/codepipeline-deploy-cloudformation/.
                Effect: Allow
                Action:
                  - s3:GetObject*
                  - s3:GetBucket*
                  - s3:List*
                  - s3:Abort*
                  - s3:DeleteObject*
                  - s3:PutObject*
                Resource: "*"
                Condition:
                    StringNotEquals:
                        s3:ResourceAccount:
                            Ref: 'AWS::AccountId'
              - Sid: PipelineCrossAccountArtifactsKey
                # Use keys only for the purposes of reading encrypted files from S3.
                Effect: Allow
                Action:
                  - kms:Decrypt
                  - kms:DescribeKey
                  - kms:Encrypt
                  - kms:ReEncrypt*
                  - kms:GenerateDataKey*
                Resource: "*"
                Condition:
                  StringEquals:
                    kms:ViaService:
                      Fn::Sub: s3.${AWS::Region}.amazonaws.com
              - Action: iam:PassRole
                Resource:
                  Fn::Sub: "${CloudFormationExecutionRole.Arn}"
                Effect: Allow
              - Sid: CliPermissions
                Action:
                  # Permissions needed by the CLI when doing `cdk deploy`.
                  # Our CI/CD does not need DeleteStack,
                  # but we also want to use this role from the CLI,
                  # and there you can call `cdk destroy`
                  - cloudformation:DescribeStackEvents
                  - cloudformation:GetTemplate
                  - cloudformation:DeleteStack
                  - cloudformation:UpdateTerminationProtection
                  - sts:GetCallerIdentity
                  # `cdk import`
                  - cloudformation:GetTemplateSummary
                Resource: "*"
                Effect: Allow
              - Sid: CliStagingBucket
                Effect: Allow
                Action:
                  - s3:GetObject*
                  - s3:GetBucket*
                  - s3:List*
                Resource:
                  - Fn::Sub: ${StagingBucket.Arn}
                  - Fn::Sub: ${StagingBucket.Arn}/*
              - Sid: ReadVersion
                Effect: Allow
                Action:
                  - ssm:GetParameter
                  - ssm:GetParameters # CreateChangeSet uses this to evaluate any SSM parameters (like `CdkBootstrapVersion`)
                Resource:
                  - Fn::Sub: "arn:${AWS::Partition}:ssm:${AWS::Region}:${AWS::AccountId}:parameter${CdkBootstrapVersion}"
              - Sid: Refactor
                Effect: Allow
                Action:
                  # Permissions needed to use the CDK CLI with stack refactor
                  - cloudformation:CreateStackRefactor
                  - cloudformation:DescribeStackRefactor
                  - cloudformation:ExecuteStackRefactor
                  - cloudformation:ListStackRefactorActions
                  - cloudformation:ListStackRefactors
                  - cloudformation:ListStacks
                Resource: "*"
            Version: '2012-10-17'
          PolicyName: default
      RoleName:
        Fn::Sub: cdk-${Qualifier}-deploy-role-${AWS::AccountId}-${AWS::Region}
      Tags:
        - Key: aws-cdk:bootstrap-role
          Value: deploy
  CloudFormationExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Action: sts:AssumeRole
            Effect: Allow
            Principal:
              Service: cloudformation.amazonaws.com
        Version: '2012-10-17'
      ManagedPolicyArns:
        Fn::If:
          - HasCloudFormationExecutionPolicies
          - Ref: CloudFormationExecutionPolicies
          - Fn::If:
            - HasTrustedAccounts
            # The CLI will prevent this case from occurring
            - Ref: AWS::NoValue
            # The CLI will advertise that we picked this implicitly
            - - Fn::Sub: "arn:${AWS::Partition}:iam::aws:policy/AdministratorAccess"
      RoleName:
        Fn::Sub: cdk-${Qualifier}-cfn-exec-role-${AWS::AccountId}-${AWS::Region}
      PermissionsBoundary:
        Fn::If:
          - PermissionsBoundarySet
          - Fn::Sub: 'arn:${AWS::Partition}:iam::${AWS::AccountId}:policy/${InputPermissionsBoundary}'
          - Ref: AWS::NoValue
  CdkBoostrapPermissionsBoundaryPolicy:
    # Edit the template prior to boostrap in order to have this example policy created
    Condition: ShouldCreatePermissionsBoundary
    Type: AWS::IAM::ManagedPolicy
    Properties:
      PolicyDocument:
        Statement:
          # If permission boundaries do not have an explicit `allow`, then the effect is `deny`
          - Sid: ExplicitAllowAll
            Action:
              - "*"
            Effect: Allow
            Resource: "*"
          # Default permissions to prevent privilege escalation
          - Sid: DenyAccessIfRequiredPermBoundaryIsNotBeingApplied
            Action:
              - iam:CreateUser
              - iam:CreateRole
              - iam:PutRolePermissionsBoundary
              - iam:PutUserPermissionsBoundary
            Condition:
              StringNotEquals:
                iam:PermissionsBoundary:
                  Fn::Sub: arn:${AWS::Partition}:iam::${AWS::AccountId}:policy/cdk-${Qualifier}-permissions-boundary-${AWS::AccountId}-${AWS::Region}
            Effect: Deny
            Resource: "*"
          # Forbid the policy itself being edited
          - Sid: DenyPermBoundaryIAMPolicyAlteration
            Action:
              - iam:CreatePolicyVersion
              - iam:DeletePolicy
              - iam:DeletePolicyVersion
              - iam:SetDefaultPolicyVersion
            Effect: Deny
            Resource:
              Fn::Sub: arn:${AWS::Partition}:iam::${AWS::AccountId}:policy/cdk-${Qualifier}-permissions-boundary-${AWS::AccountId}-${AWS::Region}
          # Forbid removing the permissions boundary from any user or role that has it associated
          - Sid: DenyRemovalOfPermBoundaryFromAnyUserOrRole
            Action:
              - iam:DeleteUserPermissionsBoundary
              - iam:DeleteRolePermissionsBoundary
            Effect: Deny
            Resource: "*"
          # Add your specific organizational security policy here
          # Uncomment the example to deny access to AWS Config
          #- Sid: OrganizationalSecurityPolicy
          #  Action:
          #    - "config:*"
          #  Effect: Deny
          #  Resource: "*"
        Version: "2012-10-17"
      Description: "Bootstrap Permission Boundary"
      ManagedPolicyName:
        Fn::Sub: cdk-${Qualifier}-permissions-boundary-${AWS::AccountId}-${AWS::Region}
      Path: /
  # The SSM parameter is used in pipeline-deployed templates to verify the version
  # of the bootstrap resources.
  CdkBootstrapVersion:
    Type: AWS::SSM::Parameter
    Properties:
      Type: String
      Name:
        Fn::Sub: '/cdk-bootstrap/${Qualifier}/version'
      Value: '28'
Outputs:
  BucketName:
    Description: The name of the S3 bucket owned by the CDK toolkit stack
    Value:
      Fn::Sub: "${StagingBucket}"
  BucketDomainName:
    Description: The domain name of the S3 bucket owned by the CDK toolkit stack
    Value:
      Fn::Sub: "${StagingBucket.RegionalDomainName}"
  # @deprecated - This Export can be removed at some future point in time.
  # We can't do it today because if there are stacks that use it, the bootstrap
  # stack cannot be updated. Not used anymore by apps >= 1.60.0
  FileAssetKeyArn:
    Description: The ARN of the KMS key used to encrypt the asset bucket (deprecated)
    Value:
      Fn::If:
        - CreateNewKey
        - Fn::Sub: "${FileAssetsBucketEncryptionKey.Arn}"
        - Fn::Sub: "${FileAssetsBucketKmsKeyId}"
    Export:
      Name:
        Fn::Sub: CdkBootstrap-${Qualifier}-FileAssetKeyArn
  ImageRepositoryName:
    Description: The name of the ECR repository which hosts docker image assets
    Value:
      Fn::Sub: "${ContainerAssetsRepository}"
  # The Output is used by the CLI to verify the version of the bootstrap resources.
  BootstrapVersion:
    Description: The version of the bootstrap resources that are currently mastered
      in this stack
    Value:
      Fn::GetAtt: [CdkBootstrapVersion, Value]
