cloudformation/FIXEngineApplication.yml [343:866]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Resources:
  ApplicationIDParam:
    Condition: ''
    Properties:
      Description: !Join
        - ''
        - - 'FIX Application ID for '
          - !Ref 'AWS::StackName'
          - ' stack'
      Name: !Join
        - /
        - - /fixengine
          - !Ref 'AWS::StackName'
          - ApplicationID
      Tier: Standard
      Type: String
      Value: !Ref 'ApplicationID'
    Type: AWS::SSM::Parameter
  AutomationDocumentStarterFunction:
    Condition: ''
    DependsOn:
      - AutomationDocumentStarterRole
    Metadata:
      cfn_nag:
        rules_to_suppress:
          - id: W89
            reason: This function is only invoked during the deployment of this solution,
              potentially PRIOR to the creation of a VPC, and is never used again.
          - id: W92
            reason: This function is only invoked during the deployment of this solution
              and is never used again. Reserving concurrency would therefore be wasteful.
    Properties:
      Code:
        ZipFile: "import json\nimport time\nimport boto3\nimport logging\nimport cfnresponse\n\
          from botocore.exceptions import ClientError\n\nLOGGER = logging.getLogger()\n\
          LOGGER.setLevel(logging.INFO)\nlogging.getLogger('boto3').setLevel(logging.INFO)\n\
          logging.getLogger('botocore').setLevel(logging.INFO)\n\nssm_client = boto3.client('ssm')\n\
          \ndef start_document(properties):\n    \n    try:\n        \n        response\
          \ = ssm_client.start_automation_execution(\n            Parameters = {\n\
          \                'ExecutionRoleArn': [\n                    properties['ExecutionRoleArn']\n\
          \                ]\n            },\n            DocumentName = properties['AutomationDocumentName'],\n\
          \        )\n    \n        return True\n    \n    except ClientError as e:\n\
          \        print(str(e)); return False\n\n'''\n    - ExecutionRoleArn | str\n\
          \    - EligibleRequestTypes | list\n    - AutomationDocumentName | str\n\
          '''\ndef handler(event, context):\n\n    LOGGER.info('----- REQUEST RECEIVED\
          \ -----')\n    LOGGER.info(json.dumps(event))\n    \n    responseData =\
          \ {}\n\n    operation = event['ResourceProperties']['Type'].split('Custom::')[1]\n\
          \    properties = event['ResourceProperties']['Properties']\n    \n    if\
          \ 'EligibleRequestTypes' not in properties:\n        properties['EligibleRequestTypes']\
          \ = ['Create']\n    \n    if event['RequestType'] in properties['EligibleRequestTypes']:\n\
          \        \n        attempt_cnt = 0\n        while attempt_cnt < 5:\n   \
          \         \n            if attempt_cnt > 0:\n                time.sleep(10)\n\
          \            \n            if start_document(properties) is True:\n    \
          \            return cfnresponse.send(event, context, cfnresponse.SUCCESS,\
          \ responseData, properties['AutomationDocumentName'])\n        \n      \
          \      attempt_cnt += 1\n            \n        return cfnresponse.send(event,\
          \ context, cfnresponse.FAILED, responseData)\n    \n    elif event['RequestType']\
          \ not in properties['EligibleRequestTypes']:\n        \n        return cfnresponse.send(event,\
          \ context, cfnresponse.SUCCESS, responseData)"
      Description: !Join
        - ''
        - - 'AutomationDocumentStarter resource for '
          - !Ref 'AWS::StackName'
          - ' stack'
      Handler: index.handler
      KmsKeyArn: !If
        - KMSKeySupplied
        - !Ref 'KMSKeyARN'
        - ''
      Role: !GetAtt 'AutomationDocumentStarterRole.Arn'
      Runtime: python3.7
      Timeout: 180
    Type: AWS::Lambda::Function
  AutomationDocumentStarterLogGroup:
    Condition: ''
    DependsOn:
      - AutomationDocumentStarterFunction
    Metadata:
      cfn_nag:
        rules_to_suppress:
          - id: W84
            reason: These logs do not contain sensitive data.
    Properties:
      LogGroupName: !Join
        - ''
        - - /aws/lambda/
          - !Ref 'AutomationDocumentStarterFunction'
      RetentionInDays: !Ref 'LogRetentionInDays'
    Type: AWS::Logs::LogGroup
  AutomationDocumentStarterRole:
    Condition: ''
    DependsOn: []
    Metadata: {}
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Action:
              - sts:AssumeRole
            Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
      Policies: []
    Type: AWS::IAM::Role
  CloudWatchDashboard:
    Properties:
      DashboardBody: !Sub
        - "{\n   \"start\": \"-PT3H\",\n   \"periodOverride\": \"inherit\",\n    \"\
          widgets\": [\n        {\n            \"type\": \"metric\",\n           \
          \ \"properties\": {\n                \"view\": \"timeSeries\",\n       \
          \         \"width\": 20,\n                \"height\": 12,\n            \
          \    \"title\": \"Fargate Resource Utlization\",\n                \"period\"\
          : 300,\n                \"stacked\": false,\n                \"metrics\"\
          : [\n                    [\n                        \"AWS/ECS\", \n    \
          \                    \"MemoryUtilization\", \n                        \"\
          ServiceName\", \n                        \"${PRIMARY_ECS_SERVICE_NAME}\"\
          ,\n                        \"ClusterName\", \n                        \"\
          ${PRIMARY_ECS_CLUSTER_NAME}\",\n                        {\n            \
          \                \"label\": \"PrimaryMemUtilization\"\n                \
          \        }\n                    ],\n                    [ \n           \
          \             \"AWS/ECS\", \n                        \"CPUUtilization\"\
          , \n                        \"ServiceName\", \n                        \"\
          ${PRIMARY_ECS_SERVICE_NAME}\",\n                        \"ClusterName\"\
          , \n                        \"${PRIMARY_ECS_CLUSTER_NAME}\",\n         \
          \               {\n                            \"label\": \"PrimaryCPUUtilization\"\
          \n                        }\n                    ],\n                  \
          \  [\n                        \"AWS/ECS\", \n                        \"\
          MemoryUtilization\", \n                        \"ServiceName\", \n     \
          \                   \"${FAILOVER_ECS_SERVICE_NAME}\",\n                \
          \        \"ClusterName\", \n                        \"${FAILOVER_ECS_CLUSTER_NAME}\"\
          ,\n                        {\n                            \"label\": \"\
          FailoverMemUtilization\"\n                        }\n                  \
          \  ],\n                    [ \n                        \"AWS/ECS\", \n \
          \                       \"CPUUtilization\", \n                        \"\
          ServiceName\", \n                        \"${FAILOVER_ECS_SERVICE_NAME}\"\
          ,\n                        \"ClusterName\", \n                        \"\
          ${FAILOVER_ECS_CLUSTER_NAME}\",\n                        {\n           \
          \                 \"label\": \"FailoverCPUUtilization\"\n              \
          \          }\n                    ]\n                ],\n              \
          \  \"region\": \"us-east-1\"\n            }\n        }\n    ]\n}"
        - FAILOVER_ECS_CLUSTER_NAME: !Ref 'FailoverECSCluster'
          FAILOVER_ECS_SERVICE_NAME: !If
            - IsInitiatorStack
            - !Ref 'FailoverInitiatorECSService'
            - !Ref 'FailoverAcceptorECSService'
          PRIMARY_ECS_CLUSTER_NAME: !Ref 'PrimaryECSCluster'
          PRIMARY_ECS_SERVICE_NAME: !If
            - IsInitiatorStack
            - !Ref 'PrimaryInitiatorECSService'
            - !Ref 'PrimaryAcceptorECSService'
    Type: AWS::CloudWatch::Dashboard
  ConnectionTypeParam:
    Condition: ''
    Properties:
      Description: !Join
        - ''
        - - 'FIX engine connection type defined in the parameters of the '
          - !Ref 'AWS::StackName'
          - ' stack'
      Name: !Join
        - /
        - - /fixengine
          - !Ref 'AWS::StackName'
          - ConnectionType
      Tier: Standard
      Type: String
      Value: !Ref 'ConnectionType'
    Type: AWS::SSM::Parameter
  DatabaseNameParam:
    Condition: ''
    Properties:
      Description: !Join
        - ''
        - - 'FIX engine MySQL database name for '
          - !Ref 'AWS::StackName'
          - ' stack'
      Name: !Join
        - /
        - - /fixengine
          - !Ref 'AWS::StackName'
          - DatabaseName
      Tier: Standard
      Type: String
      Value: quickfix
    Type: AWS::SSM::Parameter
  DebugLoggingParam:
    Condition: ''
    Properties:
      Description: !Join
        - ''
        - - 'FIX debug logging setting defined in the parameters of the '
          - !Ref 'AWS::StackName'
          - ' stack'
      Name: !Join
        - /
        - - /fixengine
          - !Ref 'AWS::StackName'
          - DebugLogging
      Tier: Standard
      Type: String
      Value: !Ref 'DebugLogging'
    Type: AWS::SSM::Parameter
  ECRRepository:
    DependsOn:
      - StackNameManipulator
    Metadata:
      cfn_nag:
        rules_to_suppress:
          - id: W28
            reason: ECR does not allow capital letters in repository names which is
              why we must sanitize/lowercase the auto-generated name.
    Properties:
      EncryptionConfiguration: !If
        - KMSKeySupplied
        - EncryptionType: KMS
          KmsKey: !Ref 'KMSKeyARN'
        - EncryptionType: AES256
      ImageScanningConfiguration:
        ScanOnPush: true
      RepositoryName: !Join
        - ''
        - - fix-engine-on-aws/
          - !GetAtt 'StackNameManipulator.OutputString'
    Type: AWS::ECR::Repository
  ECSImageBuildDocument:
    DependsOn:
      - ECRRepository
      - ECSImageBuildSecurityGroup
      - ECSImageBuildExecutionRole
      - ECSImageBuildInstanceRoleProfile
    Properties:
      Content:
        assumeRole: '{{ExecutionRoleArn}}'
        description: !Join
          - ''
          - - 'Creates the client and server images use by CloudFormation stack '
            - !Ref 'AWS::StackName'
        mainSteps:
          - action: aws:runInstances
            inputs:
              BlockDeviceMappings:
                - DeviceName: /dev/sda1
                  Ebs:
                    Encrypted: true
                    VolumeSize: 8
                    VolumeType: gp2
              IamInstanceProfileName: !Ref 'ECSImageBuildInstanceRoleProfile'
              ImageId: '{{LatestAmazonLinux2AMIId}}'
              InstanceType: t3a.small
              MaxInstanceCount: 1
              MinInstanceCount: 1
              SecurityGroupIds:
                - !Ref 'ECSImageBuildSecurityGroup'
              SubnetId: !Ref 'PrimaryPrivateSubnet'
              TagSpecifications:
                - ResourceType: instance
                  Tags:
                    - Key: Name
                      Value: !Join
                        - '-'
                        - - !Ref 'AWS::StackName'
                          - ECSImageBuilder
                    - Key: LaunchedBy
                      Value: SSMAutomation
                    - Key: StackName
                      Value: !Ref 'AWS::StackName'
            maxAttempts: 3
            name: LaunchInstance
            onFailure: step:SignalFailure
            timeoutSeconds: 300
          - action: aws:runCommand
            inputs:
              CloudWatchOutputConfig:
                CloudWatchLogGroupName: !Ref 'ECSImageBuildLogGroup'
                CloudWatchOutputEnabled: true
              DocumentName: AWS-RunShellScript
              InstanceIds:
                - '{{LaunchInstance.InstanceIds}}'
              Parameters:
                commands:
                  - sudo yum update
                  - sudo yum install jq git docker java-1.8.0-openjdk-devel -y
                  - '# Installs Gradle'
                  - sudo wget -c https://services.gradle.org/distributions/gradle-6.6.1-all.zip
                  - sudo unzip gradle-6.6.1-all.zip -d /opt
                  - sudo ln -s /opt/gradle-6.6.1 /opt/gradle
                  - export GRADLE_HOME=/opt/gradle
                  - export PATH=$PATH:\/opt/gradle/bin
                  - cd /tmp
                  - git clone https://github.com/aws-samples/amazon-resilient-fix-engine-demo.git
                  - cd amazon-resilient-fix-engine-demo
                  - !Join
                    - ' '
                    - - sh scripts/dockerbuild.sh --ecr-repo-name
                      - !Ref 'ECRRepository'
                      - --engine-role
                      - !If
                        - IsAcceptorStack
                        - Server
                        - Client
            name: BuildECSImage
            onFailure: step:TerminateInstanceOnFailure
            timeoutSeconds: 1800
          - action: aws:executeAwsApi
            inputs:
              Api: TerminateInstances
              InstanceIds:
                - '{{LaunchInstance.InstanceIds}}'
              Service: ec2
            name: TerminateInstanceOnSuccess
            onFailure: step:SignalFailure
          - action: aws:executeAwsApi
            inputs:
              Api: SignalResource
              LogicalResourceId: ECSImageBuildWaiter
              Service: cloudformation
              StackName: !Ref 'AWS::StackName'
              Status: SUCCESS
              UniqueId: !Ref 'AWS::StackName'
            isEnd: true
            name: SignalSuccess
            onFailure: step:SignalFailure
          - action: aws:executeAwsApi
            inputs:
              Api: TerminateInstances
              InstanceIds:
                - '{{LaunchInstance.InstanceIds}}'
              Service: ec2
            name: TerminateInstanceOnFailure
            onFailure: step:SignalFailure
          - action: aws:executeAwsApi
            inputs:
              Api: SignalResource
              LogicalResourceId: ECSImageBuildWaiter
              Service: cloudformation
              StackName: !Ref 'AWS::StackName'
              Status: FAILURE
              UniqueId: !Ref 'AWS::StackName'
            isEnd: true
            name: SignalFailure
        parameters:
          ExecutionRoleArn:
            default: !GetAtt 'ECSImageBuildExecutionRole.Arn'
            description: The service role to use for this automation.
            type: String
          LatestAmazonLinux2AMIId:
            default: '{{ssm:/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-ebs}}'
            description: The latest Amazon Linux 2 AMI queried from the public parameter.
            type: String
        schemaVersion: '0.3'
      DocumentType: Automation
    Type: AWS::SSM::Document
  ECSImageBuildExecutionRole:
    DependsOn:
      - ECSImageBuildInstanceRole
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Action:
              - sts:AssumeRole
            Effect: Allow
            Principal:
              Service:
                - ssm.amazonaws.com
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AmazonSSMAutomationRole
      Policies:
        - PolicyDocument:
            Statement:
              - Action:
                  - ec2:RunInstances
                Effect: Allow
                Resource:
                  - !Join
                    - ''
                    - - 'arn:aws:ec2:'
                      - !Ref 'AWS::Region'
                      - ::image/*
                  - !Join
                    - ''
                    - - 'arn:aws:ec2:'
                      - !Ref 'AWS::Region'
                      - ':'
                      - !Ref 'AWS::AccountId'
                      - :subnet/*
                  - !Join
                    - ''
                    - - 'arn:aws:ec2:'
                      - !Ref 'AWS::Region'
                      - ':'
                      - !Ref 'AWS::AccountId'
                      - :security-group/
                      - !GetAtt 'ECSImageBuildSecurityGroup.GroupId'
              - Action:
                  - iam:PassRole
                Effect: Allow
                Resource:
                  - !GetAtt 'ECSImageBuildInstanceRole.Arn'
              - Action:
                  - cloudformation:SignalResource
                Effect: Allow
                Resource:
                  - !Ref 'AWS::StackId'
          PolicyName: primary-policy
    Type: AWS::IAM::Role
  ECSImageBuildInstanceRole:
    DependsOn:
      - ECRRepository
      - ECSImageBuildLogGroup
    Metadata:
      cfn_nag:
        rules_to_suppress:
          - id: W11
            reason: ecr:GetAuthorizationToken does not support resource filtering.
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Action:
              - sts:AssumeRole
            Effect: Allow
            Principal:
              Service:
                - ec2.amazonaws.com
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
      Policies:
        - PolicyDocument:
            Statement:
              - Action:
                  - ecr:PutImage
                  - ecr:UploadLayerPart
                  - ecr:InitiateLayerUpload
                  - ecr:CompleteLayerUpload
                  - ecr:BatchCheckLayerAvailability
                Effect: Allow
                Resource:
                  - !GetAtt 'ECRRepository.Arn'
              - Action:
                  - ecr:GetAuthorizationToken
                Effect: Allow
                Resource:
                  - '*'
              - Action:
                  - logs:PutLogEvents
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:DescribeLogGroups
                  - logs:DescribeLogStreams
                Effect: Allow
                Resource:
                  - !Join
                    - ''
                    - - 'arn:aws:logs:'
                      - !Ref 'AWS::Region'
                      - ':'
                      - !Ref 'AWS::AccountId'
                      - ':log-group:'
                      - !Ref 'ECSImageBuildLogGroup'
                  - !Join
                    - ''
                    - - 'arn:aws:logs:'
                      - !Ref 'AWS::Region'
                      - ':'
                      - !Ref 'AWS::AccountId'
                      - ':log-group:'
                      - !Ref 'ECSImageBuildLogGroup'
                      - :log-stream:*
          PolicyName: primary-policy
    Type: AWS::IAM::Role
  ECSImageBuildInstanceRoleProfile:
    DependsOn:
      - ECSImageBuildInstanceRole
    Properties:
      Path: /
      Roles:
        - !Ref 'ECSImageBuildInstanceRole'
    Type: AWS::IAM::InstanceProfile
  ECSImageBuildLogGroup:
    Metadata:
      cfn_nag:
        rules_to_suppress:
          - id: W84
            reason: These logs do not contain sensitive data.
    Properties:
      LogGroupName: !Join
        - /
        - - /aws/ssm
          - !Ref 'AWS::StackName'
          - ECSImageBuild
      RetentionInDays: !Ref 'LogRetentionInDays'
    Type: AWS::Logs::LogGroup
  ECSImageBuildPolicy:
    DependsOn:
      - AutomationDocumentStarterRole
      - ECSImageBuildDocument
      - ECSImageBuildExecutionRole
    Properties:
      PolicyDocument:
        Statement:
          - Action:
              - iam:PassRole
            Effect: Allow
            Resource:
              - !GetAtt 'ECSImageBuildExecutionRole.Arn'
          - Action:
              - ssm:StartAutomationExecution
            Effect: Allow
            Resource:
              - !Join
                - ''
                - - 'arn:aws:ssm:'
                  - !Ref 'AWS::Region'
                  - ':'
                  - !Ref 'AWS::AccountId'
                  - :automation-definition/
                  - !Ref 'ECSImageBuildDocument'
                  - :$DEFAULT
      PolicyName: ECSImageBuildPolicy
      Roles:
        - !Ref 'AutomationDocumentStarterRole'
    Type: AWS::IAM::Policy
  ECSImageBuildSecurityGroup:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



cloudformation/FIXEngineVPCApplication.yml [351:874]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Resources:
  ApplicationIDParam:
    Condition: ''
    Properties:
      Description: !Join
        - ''
        - - 'FIX Application ID for '
          - !Ref 'AWS::StackName'
          - ' stack'
      Name: !Join
        - /
        - - /fixengine
          - !Ref 'AWS::StackName'
          - ApplicationID
      Tier: Standard
      Type: String
      Value: !Ref 'ApplicationID'
    Type: AWS::SSM::Parameter
  AutomationDocumentStarterFunction:
    Condition: ''
    DependsOn:
      - AutomationDocumentStarterRole
    Metadata:
      cfn_nag:
        rules_to_suppress:
          - id: W89
            reason: This function is only invoked during the deployment of this solution,
              potentially PRIOR to the creation of a VPC, and is never used again.
          - id: W92
            reason: This function is only invoked during the deployment of this solution
              and is never used again. Reserving concurrency would therefore be wasteful.
    Properties:
      Code:
        ZipFile: "import json\nimport time\nimport boto3\nimport logging\nimport cfnresponse\n\
          from botocore.exceptions import ClientError\n\nLOGGER = logging.getLogger()\n\
          LOGGER.setLevel(logging.INFO)\nlogging.getLogger('boto3').setLevel(logging.INFO)\n\
          logging.getLogger('botocore').setLevel(logging.INFO)\n\nssm_client = boto3.client('ssm')\n\
          \ndef start_document(properties):\n    \n    try:\n        \n        response\
          \ = ssm_client.start_automation_execution(\n            Parameters = {\n\
          \                'ExecutionRoleArn': [\n                    properties['ExecutionRoleArn']\n\
          \                ]\n            },\n            DocumentName = properties['AutomationDocumentName'],\n\
          \        )\n    \n        return True\n    \n    except ClientError as e:\n\
          \        print(str(e)); return False\n\n'''\n    - ExecutionRoleArn | str\n\
          \    - EligibleRequestTypes | list\n    - AutomationDocumentName | str\n\
          '''\ndef handler(event, context):\n\n    LOGGER.info('----- REQUEST RECEIVED\
          \ -----')\n    LOGGER.info(json.dumps(event))\n    \n    responseData =\
          \ {}\n\n    operation = event['ResourceProperties']['Type'].split('Custom::')[1]\n\
          \    properties = event['ResourceProperties']['Properties']\n    \n    if\
          \ 'EligibleRequestTypes' not in properties:\n        properties['EligibleRequestTypes']\
          \ = ['Create']\n    \n    if event['RequestType'] in properties['EligibleRequestTypes']:\n\
          \        \n        attempt_cnt = 0\n        while attempt_cnt < 5:\n   \
          \         \n            if attempt_cnt > 0:\n                time.sleep(10)\n\
          \            \n            if start_document(properties) is True:\n    \
          \            return cfnresponse.send(event, context, cfnresponse.SUCCESS,\
          \ responseData, properties['AutomationDocumentName'])\n        \n      \
          \      attempt_cnt += 1\n            \n        return cfnresponse.send(event,\
          \ context, cfnresponse.FAILED, responseData)\n    \n    elif event['RequestType']\
          \ not in properties['EligibleRequestTypes']:\n        \n        return cfnresponse.send(event,\
          \ context, cfnresponse.SUCCESS, responseData)"
      Description: !Join
        - ''
        - - 'AutomationDocumentStarter resource for '
          - !Ref 'AWS::StackName'
          - ' stack'
      Handler: index.handler
      KmsKeyArn: !If
        - KMSKeySupplied
        - !Ref 'KMSKeyARN'
        - ''
      Role: !GetAtt 'AutomationDocumentStarterRole.Arn'
      Runtime: python3.7
      Timeout: 180
    Type: AWS::Lambda::Function
  AutomationDocumentStarterLogGroup:
    Condition: ''
    DependsOn:
      - AutomationDocumentStarterFunction
    Metadata:
      cfn_nag:
        rules_to_suppress:
          - id: W84
            reason: These logs do not contain sensitive data.
    Properties:
      LogGroupName: !Join
        - ''
        - - /aws/lambda/
          - !Ref 'AutomationDocumentStarterFunction'
      RetentionInDays: !Ref 'LogRetentionInDays'
    Type: AWS::Logs::LogGroup
  AutomationDocumentStarterRole:
    Condition: ''
    DependsOn: []
    Metadata: {}
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Action:
              - sts:AssumeRole
            Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
      Policies: []
    Type: AWS::IAM::Role
  CloudWatchDashboard:
    Properties:
      DashboardBody: !Sub
        - "{\n   \"start\": \"-PT3H\",\n   \"periodOverride\": \"inherit\",\n    \"\
          widgets\": [\n        {\n            \"type\": \"metric\",\n           \
          \ \"properties\": {\n                \"view\": \"timeSeries\",\n       \
          \         \"width\": 20,\n                \"height\": 12,\n            \
          \    \"title\": \"Fargate Resource Utlization\",\n                \"period\"\
          : 300,\n                \"stacked\": false,\n                \"metrics\"\
          : [\n                    [\n                        \"AWS/ECS\", \n    \
          \                    \"MemoryUtilization\", \n                        \"\
          ServiceName\", \n                        \"${PRIMARY_ECS_SERVICE_NAME}\"\
          ,\n                        \"ClusterName\", \n                        \"\
          ${PRIMARY_ECS_CLUSTER_NAME}\",\n                        {\n            \
          \                \"label\": \"PrimaryMemUtilization\"\n                \
          \        }\n                    ],\n                    [ \n           \
          \             \"AWS/ECS\", \n                        \"CPUUtilization\"\
          , \n                        \"ServiceName\", \n                        \"\
          ${PRIMARY_ECS_SERVICE_NAME}\",\n                        \"ClusterName\"\
          , \n                        \"${PRIMARY_ECS_CLUSTER_NAME}\",\n         \
          \               {\n                            \"label\": \"PrimaryCPUUtilization\"\
          \n                        }\n                    ],\n                  \
          \  [\n                        \"AWS/ECS\", \n                        \"\
          MemoryUtilization\", \n                        \"ServiceName\", \n     \
          \                   \"${FAILOVER_ECS_SERVICE_NAME}\",\n                \
          \        \"ClusterName\", \n                        \"${FAILOVER_ECS_CLUSTER_NAME}\"\
          ,\n                        {\n                            \"label\": \"\
          FailoverMemUtilization\"\n                        }\n                  \
          \  ],\n                    [ \n                        \"AWS/ECS\", \n \
          \                       \"CPUUtilization\", \n                        \"\
          ServiceName\", \n                        \"${FAILOVER_ECS_SERVICE_NAME}\"\
          ,\n                        \"ClusterName\", \n                        \"\
          ${FAILOVER_ECS_CLUSTER_NAME}\",\n                        {\n           \
          \                 \"label\": \"FailoverCPUUtilization\"\n              \
          \          }\n                    ]\n                ],\n              \
          \  \"region\": \"us-east-1\"\n            }\n        }\n    ]\n}"
        - FAILOVER_ECS_CLUSTER_NAME: !Ref 'FailoverECSCluster'
          FAILOVER_ECS_SERVICE_NAME: !If
            - IsInitiatorStack
            - !Ref 'FailoverInitiatorECSService'
            - !Ref 'FailoverAcceptorECSService'
          PRIMARY_ECS_CLUSTER_NAME: !Ref 'PrimaryECSCluster'
          PRIMARY_ECS_SERVICE_NAME: !If
            - IsInitiatorStack
            - !Ref 'PrimaryInitiatorECSService'
            - !Ref 'PrimaryAcceptorECSService'
    Type: AWS::CloudWatch::Dashboard
  ConnectionTypeParam:
    Condition: ''
    Properties:
      Description: !Join
        - ''
        - - 'FIX engine connection type defined in the parameters of the '
          - !Ref 'AWS::StackName'
          - ' stack'
      Name: !Join
        - /
        - - /fixengine
          - !Ref 'AWS::StackName'
          - ConnectionType
      Tier: Standard
      Type: String
      Value: !Ref 'ConnectionType'
    Type: AWS::SSM::Parameter
  DatabaseNameParam:
    Condition: ''
    Properties:
      Description: !Join
        - ''
        - - 'FIX engine MySQL database name for '
          - !Ref 'AWS::StackName'
          - ' stack'
      Name: !Join
        - /
        - - /fixengine
          - !Ref 'AWS::StackName'
          - DatabaseName
      Tier: Standard
      Type: String
      Value: quickfix
    Type: AWS::SSM::Parameter
  DebugLoggingParam:
    Condition: ''
    Properties:
      Description: !Join
        - ''
        - - 'FIX debug logging setting defined in the parameters of the '
          - !Ref 'AWS::StackName'
          - ' stack'
      Name: !Join
        - /
        - - /fixengine
          - !Ref 'AWS::StackName'
          - DebugLogging
      Tier: Standard
      Type: String
      Value: !Ref 'DebugLogging'
    Type: AWS::SSM::Parameter
  ECRRepository:
    DependsOn:
      - StackNameManipulator
    Metadata:
      cfn_nag:
        rules_to_suppress:
          - id: W28
            reason: ECR does not allow capital letters in repository names which is
              why we must sanitize/lowercase the auto-generated name.
    Properties:
      EncryptionConfiguration: !If
        - KMSKeySupplied
        - EncryptionType: KMS
          KmsKey: !Ref 'KMSKeyARN'
        - EncryptionType: AES256
      ImageScanningConfiguration:
        ScanOnPush: true
      RepositoryName: !Join
        - ''
        - - fix-engine-on-aws/
          - !GetAtt 'StackNameManipulator.OutputString'
    Type: AWS::ECR::Repository
  ECSImageBuildDocument:
    DependsOn:
      - ECRRepository
      - ECSImageBuildSecurityGroup
      - ECSImageBuildExecutionRole
      - ECSImageBuildInstanceRoleProfile
    Properties:
      Content:
        assumeRole: '{{ExecutionRoleArn}}'
        description: !Join
          - ''
          - - 'Creates the client and server images use by CloudFormation stack '
            - !Ref 'AWS::StackName'
        mainSteps:
          - action: aws:runInstances
            inputs:
              BlockDeviceMappings:
                - DeviceName: /dev/sda1
                  Ebs:
                    Encrypted: true
                    VolumeSize: 8
                    VolumeType: gp2
              IamInstanceProfileName: !Ref 'ECSImageBuildInstanceRoleProfile'
              ImageId: '{{LatestAmazonLinux2AMIId}}'
              InstanceType: t3a.small
              MaxInstanceCount: 1
              MinInstanceCount: 1
              SecurityGroupIds:
                - !Ref 'ECSImageBuildSecurityGroup'
              SubnetId: !Ref 'PrimaryPrivateSubnet'
              TagSpecifications:
                - ResourceType: instance
                  Tags:
                    - Key: Name
                      Value: !Join
                        - '-'
                        - - !Ref 'AWS::StackName'
                          - ECSImageBuilder
                    - Key: LaunchedBy
                      Value: SSMAutomation
                    - Key: StackName
                      Value: !Ref 'AWS::StackName'
            maxAttempts: 3
            name: LaunchInstance
            onFailure: step:SignalFailure
            timeoutSeconds: 300
          - action: aws:runCommand
            inputs:
              CloudWatchOutputConfig:
                CloudWatchLogGroupName: !Ref 'ECSImageBuildLogGroup'
                CloudWatchOutputEnabled: true
              DocumentName: AWS-RunShellScript
              InstanceIds:
                - '{{LaunchInstance.InstanceIds}}'
              Parameters:
                commands:
                  - sudo yum update
                  - sudo yum install jq git docker java-1.8.0-openjdk-devel -y
                  - '# Installs Gradle'
                  - sudo wget -c https://services.gradle.org/distributions/gradle-6.6.1-all.zip
                  - sudo unzip gradle-6.6.1-all.zip -d /opt
                  - sudo ln -s /opt/gradle-6.6.1 /opt/gradle
                  - export GRADLE_HOME=/opt/gradle
                  - export PATH=$PATH:\/opt/gradle/bin
                  - cd /tmp
                  - git clone https://github.com/aws-samples/amazon-resilient-fix-engine-demo.git
                  - cd amazon-resilient-fix-engine-demo
                  - !Join
                    - ' '
                    - - sh scripts/dockerbuild.sh --ecr-repo-name
                      - !Ref 'ECRRepository'
                      - --engine-role
                      - !If
                        - IsAcceptorStack
                        - Server
                        - Client
            name: BuildECSImage
            onFailure: step:TerminateInstanceOnFailure
            timeoutSeconds: 1800
          - action: aws:executeAwsApi
            inputs:
              Api: TerminateInstances
              InstanceIds:
                - '{{LaunchInstance.InstanceIds}}'
              Service: ec2
            name: TerminateInstanceOnSuccess
            onFailure: step:SignalFailure
          - action: aws:executeAwsApi
            inputs:
              Api: SignalResource
              LogicalResourceId: ECSImageBuildWaiter
              Service: cloudformation
              StackName: !Ref 'AWS::StackName'
              Status: SUCCESS
              UniqueId: !Ref 'AWS::StackName'
            isEnd: true
            name: SignalSuccess
            onFailure: step:SignalFailure
          - action: aws:executeAwsApi
            inputs:
              Api: TerminateInstances
              InstanceIds:
                - '{{LaunchInstance.InstanceIds}}'
              Service: ec2
            name: TerminateInstanceOnFailure
            onFailure: step:SignalFailure
          - action: aws:executeAwsApi
            inputs:
              Api: SignalResource
              LogicalResourceId: ECSImageBuildWaiter
              Service: cloudformation
              StackName: !Ref 'AWS::StackName'
              Status: FAILURE
              UniqueId: !Ref 'AWS::StackName'
            isEnd: true
            name: SignalFailure
        parameters:
          ExecutionRoleArn:
            default: !GetAtt 'ECSImageBuildExecutionRole.Arn'
            description: The service role to use for this automation.
            type: String
          LatestAmazonLinux2AMIId:
            default: '{{ssm:/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-ebs}}'
            description: The latest Amazon Linux 2 AMI queried from the public parameter.
            type: String
        schemaVersion: '0.3'
      DocumentType: Automation
    Type: AWS::SSM::Document
  ECSImageBuildExecutionRole:
    DependsOn:
      - ECSImageBuildInstanceRole
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Action:
              - sts:AssumeRole
            Effect: Allow
            Principal:
              Service:
                - ssm.amazonaws.com
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AmazonSSMAutomationRole
      Policies:
        - PolicyDocument:
            Statement:
              - Action:
                  - ec2:RunInstances
                Effect: Allow
                Resource:
                  - !Join
                    - ''
                    - - 'arn:aws:ec2:'
                      - !Ref 'AWS::Region'
                      - ::image/*
                  - !Join
                    - ''
                    - - 'arn:aws:ec2:'
                      - !Ref 'AWS::Region'
                      - ':'
                      - !Ref 'AWS::AccountId'
                      - :subnet/*
                  - !Join
                    - ''
                    - - 'arn:aws:ec2:'
                      - !Ref 'AWS::Region'
                      - ':'
                      - !Ref 'AWS::AccountId'
                      - :security-group/
                      - !GetAtt 'ECSImageBuildSecurityGroup.GroupId'
              - Action:
                  - iam:PassRole
                Effect: Allow
                Resource:
                  - !GetAtt 'ECSImageBuildInstanceRole.Arn'
              - Action:
                  - cloudformation:SignalResource
                Effect: Allow
                Resource:
                  - !Ref 'AWS::StackId'
          PolicyName: primary-policy
    Type: AWS::IAM::Role
  ECSImageBuildInstanceRole:
    DependsOn:
      - ECRRepository
      - ECSImageBuildLogGroup
    Metadata:
      cfn_nag:
        rules_to_suppress:
          - id: W11
            reason: ecr:GetAuthorizationToken does not support resource filtering.
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Action:
              - sts:AssumeRole
            Effect: Allow
            Principal:
              Service:
                - ec2.amazonaws.com
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
      Policies:
        - PolicyDocument:
            Statement:
              - Action:
                  - ecr:PutImage
                  - ecr:UploadLayerPart
                  - ecr:InitiateLayerUpload
                  - ecr:CompleteLayerUpload
                  - ecr:BatchCheckLayerAvailability
                Effect: Allow
                Resource:
                  - !GetAtt 'ECRRepository.Arn'
              - Action:
                  - ecr:GetAuthorizationToken
                Effect: Allow
                Resource:
                  - '*'
              - Action:
                  - logs:PutLogEvents
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:DescribeLogGroups
                  - logs:DescribeLogStreams
                Effect: Allow
                Resource:
                  - !Join
                    - ''
                    - - 'arn:aws:logs:'
                      - !Ref 'AWS::Region'
                      - ':'
                      - !Ref 'AWS::AccountId'
                      - ':log-group:'
                      - !Ref 'ECSImageBuildLogGroup'
                  - !Join
                    - ''
                    - - 'arn:aws:logs:'
                      - !Ref 'AWS::Region'
                      - ':'
                      - !Ref 'AWS::AccountId'
                      - ':log-group:'
                      - !Ref 'ECSImageBuildLogGroup'
                      - :log-stream:*
          PolicyName: primary-policy
    Type: AWS::IAM::Role
  ECSImageBuildInstanceRoleProfile:
    DependsOn:
      - ECSImageBuildInstanceRole
    Properties:
      Path: /
      Roles:
        - !Ref 'ECSImageBuildInstanceRole'
    Type: AWS::IAM::InstanceProfile
  ECSImageBuildLogGroup:
    Metadata:
      cfn_nag:
        rules_to_suppress:
          - id: W84
            reason: These logs do not contain sensitive data.
    Properties:
      LogGroupName: !Join
        - /
        - - /aws/ssm
          - !Ref 'AWS::StackName'
          - ECSImageBuild
      RetentionInDays: !Ref 'LogRetentionInDays'
    Type: AWS::Logs::LogGroup
  ECSImageBuildPolicy:
    DependsOn:
      - AutomationDocumentStarterRole
      - ECSImageBuildDocument
      - ECSImageBuildExecutionRole
    Properties:
      PolicyDocument:
        Statement:
          - Action:
              - iam:PassRole
            Effect: Allow
            Resource:
              - !GetAtt 'ECSImageBuildExecutionRole.Arn'
          - Action:
              - ssm:StartAutomationExecution
            Effect: Allow
            Resource:
              - !Join
                - ''
                - - 'arn:aws:ssm:'
                  - !Ref 'AWS::Region'
                  - ':'
                  - !Ref 'AWS::AccountId'
                  - :automation-definition/
                  - !Ref 'ECSImageBuildDocument'
                  - :$DEFAULT
      PolicyName: ECSImageBuildPolicy
      Roles:
        - !Ref 'AutomationDocumentStarterRole'
    Type: AWS::IAM::Policy
  ECSImageBuildSecurityGroup:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



