AWSTemplateFormatVersion: 2010-09-09
Description: multi-region-sam-poc

Parameters:
  DomainName:
    Type: String
  Route53ZoneId:
    Type: String

Resources:
  AWSCloudFormationStackSetAdministrationRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: AWSCloudFormationStackSetAdministrationRole
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service: cloudformation.amazonaws.com
            Action:
              - sts:AssumeRole

  AWSCloudFormationStackSetExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: AWSCloudFormationStackSetExecutionRole
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              AWS: !GetAtt AWSCloudFormationStackSetAdministrationRole.Arn
            Action:
              - sts:AssumeRole
      ManagedPolicyArns:
        - !Sub arn:${AWS::Partition}:iam::aws:policy/AdministratorAccess

  MyStackSet:
    DependsOn:
      - AWSCloudFormationStackSetExecutionRole
    Type: AWS::CloudFormation::StackSet
    Properties:
      StackSetName: !Sub ${AWS::StackName}-StackSet
      Description: Multi-Region AWS SAM POC
      PermissionModel: SELF_MANAGED
      Capabilities:
        - CAPABILITY_AUTO_EXPAND
        - CAPABILITY_IAM
      ManagedExecution:
        Active: true
      StackInstancesGroup:
        - DeploymentTargets:
            Accounts:
              - !Ref AWS::AccountId
          Regions:
            - us-east-1
            - us-east-2
            - us-west-1
            - us-west-2
            - ap-south-1
            - ap-northeast-2
            - ap-southeast-1
            - ap-southeast-2
            - ap-northeast-1
            - ca-central-1
            - eu-central-1
            - eu-west-1
            - eu-west-2
            - eu-west-3
            - eu-north-1
            - sa-east-1
            # - ap-northeast-3 # HttpApi not available
            # I did not opt-in to any additional regions
      OperationPreferences:
        RegionConcurrencyType: PARALLEL
      Parameters:
        - ParameterKey: DomainName
          ParameterValue: !Ref DomainName
        - ParameterKey: Route53ZoneId
          ParameterValue: !Ref Route53ZoneId
      TemplateBody: |
        AWSTemplateFormatVersion: 2010-09-09
        Transform: 'AWS::Serverless-2016-10-31'
        Description: multi-region-sam-poc per region template
        Globals:
          Function:
            MemorySize: 128
            Timeout: 3
          HttpApi:
            Domain:
              CertificateArn: !Ref Certificate
              DomainName: !Ref DomainName
        Parameters:
          DomainName:
            Type: String
          Route53ZoneId:
            Type: String
        Resources:
          Certificate:
            Type: 'AWS::CertificateManager::Certificate'
            Properties:
              DomainName: !Ref DomainName
              DomainValidationOptions:
                - HostedZoneId: !Ref Route53ZoneId
                  DomainName: !Ref DomainName
              ValidationMethod: DNS
          DnsRecord:
            Type: 'AWS::Route53::RecordSet'
            Properties:
              HostedZoneId: !Ref Route53ZoneId
              Name: !Ref DomainName
              Type: A
              AliasTarget:
                HostedZoneId: !GetAtt
                  - ServerlessHttpApi
                  - DomainName
                  - RegionalHostedZoneId
                DNSName: !GetAtt
                  - ServerlessHttpApi
                  - DomainName
                  - RegionalDomainName
                EvaluateTargetHealth: true
              Region: !Ref 'AWS::Region'
              SetIdentifier: !Sub '${AWS::Region}-${DomainName}'
          LambdaFunction:
            Type: 'AWS::Serverless::Function'
            Properties:
              InlineCode: |
                import json
                def handler(event, context):
                  return {
                      "statusCode": 200,
                      "body": json.dumps({"message": f"Greetings from {context.invoked_function_arn.split(':')[3]}"}),
                  }
              Handler: index.handler
              Runtime: python3.9
              Architectures:
                - x86_64
              Events:
                Root:
                  Type: HttpApi
                  Properties:
                    Path: /
                    Method: get
        Outputs:
          SharedUrl:
            Value: !Sub 'https://${ServerlessHttpApi.DomainName}/'
          IndividualUrl:
            Description: API Gateway endpoint URL for this region's Lambda function
            Value: !Sub 'https://${ServerlessHttpApi}.execute-api.${AWS::Region}.amazonaws.com/"'

Outputs:
  SharedUrl:
    Value: !Sub https://${DomainName}/