---
resources:
    {% if type == "SPOT" %}
    SpotFleetRole:
        Type: "AWS::IAM::Role"
        Properties:
            AssumeRolePolicyDocument:
                Version: "2012-10-17"
                Statement:
                  -
                    Effect: "Allow"
                    Principal:
                      Service:
                        - "spotfleet.amazonaws.com"
                    Action:
                      - "sts:AssumeRole"
            ManagedPolicyArns:
                - "arn:aws:iam::aws:policy/service-role/AmazonEC2SpotFleetTaggingRole"
    {% endif %}

    EcsInstanceRole:
        Type: "AWS::IAM::Role"
        Properties:
            AssumeRolePolicyDocument:
                Version: "2012-10-17"
                Statement:
                  -
                    Effect: "Allow"
                    Principal:
                      Service:
                        - "ec2.amazonaws.com"
                    Action:
                      - "sts:AssumeRole"
            Policies:
                - PolicyName: "EcsInstanceRolePolicy"
                  PolicyDocument:
                    Version: "2012-10-17"
                    Statement:
                        -   Effect: "Allow"
                            Action:
                                - "ecs:CreateCluster"
                                - "ecs:DeregisterContainerInstance"
                                - "ecs:DiscoverPollEndpoint"
                                - "ecs:Poll"
                                - "ecs:RegisterContainerInstance"
                                - "ecs:StartTelemetrySession"
                                - "ecs:UpdateContainerInstancesState"
                                - "ecs:Submit*"
                                - "ecr:GetAuthorizationToken"
                                - "ecr:BatchCheckLayerAvailability"
                                - "ecr:GetDownloadUrlForLayer"
                                - "ecr:BatchGetImage"
                                - "logs:CreateLogStream"
                                - "logs:PutLogEvents"
                            "Resource": "*"

    EcsInstanceProfile:
        Type: "AWS::IAM::InstanceProfile"
        Properties:
            Roles:
                - Ref: EcsInstanceRole
            InstanceProfileName: "{{__context.environment.name}}-{{__context.layer.name}}-{{__context.stage}}"

    ServiceRole:
        Type: "AWS::IAM::Role"
        Properties:
            AssumeRolePolicyDocument:
                Version: "2012-10-17"
                Statement:
                  -
                    Effect: "Allow"
                    Principal: 
                      Service: 
                        - "batch.amazonaws.com"
                    Action: 
                      - "sts:AssumeRole"
            Path: "/"
            Policies:
                - PolicyName: "EnhancedBatchServicePolicy"
                  PolicyDocument:
                      "Version": "2012-10-17"
                      "Statement": [
                        {
                            "Effect": "Allow",
                            "Action": [
                                "ec2:RunInstances",
                                "ec2:CreateTags",
                                "ec2:RequestSpotFleet",
                                "ec2:ModifySpotFleetRequest",
                                "ec2:CancelSpotFleetRequests",
                                "ec2:DescribeSpotFleetRequests",
                                "ec2:DescribeSpotFleetInstances",
                                "ec2:DescribeSpotFleetRequestHistory"
                            ],
                            "Resource": "*"
                        },
                        {
                            "Effect": "Allow",
                            "Action": "iam:PassRole",
                            "Resource": "arn:aws:iam::*:role/aws-ec2-spot-fleet-tagging-role"
                        },
                        {
                            "Effect": "Allow",
                            "Action": [
                                "iam:CreateServiceLinkedRole",
                                "iam:ListRoles",
                                "iam:ListInstanceProfiles"
                            ],
                            "Resource": "*"
                        }
                      ]
                - PolicyName: "BatchServicePolicy"
                  PolicyDocument:
                      "Version": "2012-10-17"
                      "Statement": [{
                        "Effect": "Allow",
                        "Action": [
                            "ec2:DescribeAccountAttributes",
                            "ec2:DescribeInstances",
                            "ec2:DescribeSubnets",
                            "ec2:DescribeSecurityGroups",
                            "ec2:DescribeKeyPairs",
                            "ec2:DescribeImages",
                            "ec2:DescribeImageAttribute",
                            "ec2:DescribeSpotFleetInstances",
                            "ec2:DescribeSpotFleetRequests",
                            "ec2:DescribeSpotPriceHistory",
                            "ec2:RequestSpotFleet",
                            "ec2:CancelSpotFleetRequests",
                            "ec2:ModifySpotFleetRequest",
                            "ec2:TerminateInstances",
                            "autoscaling:DescribeAccountLimits",
                            "autoscaling:DescribeAutoScalingGroups",
                            "autoscaling:DescribeLaunchConfigurations",
                            "autoscaling:DescribeAutoScalingInstances",
                            "autoscaling:CreateLaunchConfiguration",
                            "autoscaling:CreateAutoScalingGroup",
                            "autoscaling:UpdateAutoScalingGroup",
                            "autoscaling:SetDesiredCapacity",
                            "autoscaling:DeleteLaunchConfiguration",
                            "autoscaling:DeleteAutoScalingGroup",
                            "autoscaling:CreateOrUpdateTags",
                            "autoscaling:SuspendProcesses",
                            "autoscaling:PutNotificationConfiguration",
                            "autoscaling:TerminateInstanceInAutoScalingGroup",
                            "ecs:DescribeClusters",
                            "ecs:DescribeContainerInstances",
                            "ecs:DescribeTaskDefinitions",
                            "ecs:DescribeTasks",
                            "ecs:ListClusters",
                            "ecs:ListContainerInstances",
                            "ecs:ListTaskDefinitionFamilies",
                            "ecs:ListTaskDefinitions",
                            "ecs:ListTasks",
                            "ecs:CreateCluster",
                            "ecs:DeleteCluster",
                            "ecs:RegisterTaskDefinition",
                            "ecs:DeregisterTaskDefinition",
                            "ecs:RunTask",
                            "ecs:StartTask",
                            "ecs:StopTask",
                            "ecs:UpdateContainerAgent",
                            "ecs:DeregisterContainerInstance",
                            "logs:CreateLogGroup",
                            "logs:CreateLogStream",
                            "logs:PutLogEvents",
                            "logs:DescribeLogGroups",
                            "iam:GetInstanceProfile",
                            "iam:PassRole"],
                        "Resource": "*"
                      }]

    SecurityGroup:
        Type: "AWS::EC2::SecurityGroup"
        Properties:
            GroupDescription: Security group for AWS Batch instances ({{_env.name}})
            VpcId: {{vpc_id or vpc}}
            {% if tags %}
            Tags:
                {% for key, value in tags.items() %}
                - {"Key": key, "Value": value}
                {% endfor %}
            {% endif %}
            {% if ip_whitelist or sg_whitelist %}
            SecurityGroupIngress:
                {% for ip in ip_whitelist %}
                - IpProtocol: tcp
                  FromPort: 1
                  ToPort: 9999
                  CidrIp: {{ip}}
                - IpProtocol: icmp
                  FromPort: -1
                  ToPort: -1
                  CidrIp: {{ip}}
                {% endfor %}
                {% for sg in sg_whitelist %}
                - IpProtocol: tcp
                  FromPort: 1
                  ToPort: 9999
                  SourceSecurityGroupId: {{sg}}
                {% endfor %}
            {% endif %}

    ComputeEnvironment:
      Type: "AWS::Batch::ComputeEnvironment"
      Properties:
        Type: MANAGED
        ServiceRole:
            "Fn::GetAtt" : ["ServiceRole", "Arn"]
        ComputeEnvironmentName: "{{__context.environment.name}}-{{__context.layer.name}}-{{__context.stage}}"
        ComputeResources:
            {% if type == "SPOT" %}
            BidPercentage: {{bid_percentage}}
            {% endif %}
            {% if ami_id %}
            ImageId: {{ami_id}}
            {% endif %}
            {% if key_name %}
            Ec2KeyPair: {{key_name}}
            {% endif %}
            MaxvCpus: {{max_cpus}}
            MinvCpus: {{min_cpus}}
            {% if type != "SPOT" %}
            # Tags are not supported for SPOT environments
            Tags: {{tags}}
            {% endif %}
            {% if key_name %}
            Ec2KeyPair: {{key_name}}
            {% endif %}
            Subnets:
                {% for subnet in subnet_ids %}
                - {{subnet}}
                {% endfor %}
            InstanceTypes: {{instance_types}}
            {% if type == "SPOT" %}
            SpotIamFleetRole:
                "Fn::GetAtt" : ["SpotFleetRole", "Arn"]
            {% endif %}
            InstanceRole:
                "Fn::GetAtt" : ["EcsInstanceProfile", "Arn"]
            SecurityGroupIds:
                - {Ref: SecurityGroup}
                {% for sg in security_group_ids %}
                - {{sg}}
                {% endfor %}
            Type: {{type}}
            {% if type == "SPOT" %}
            BidPercentage: {{bid_percentage}}
            {% endif %}
        State: "{{state}}"

    {% if type == "SPOT" %}
    ComputeEnvironmentOndemandFallback:
      Type: "AWS::Batch::ComputeEnvironment"
      Properties:
        Type: MANAGED
        ServiceRole:
            "Fn::GetAtt" : ["ServiceRole", "Arn"]
        ComputeEnvironmentName: "{{__context.environment.name}}-{{__context.layer.name}}-{{__context.stage}}-ondemand-fallback"
        ComputeResources:
            {% if ami_id %}
            ImageId: {{ami_id}}
            {% endif %}
            {% if key_name %}
            Ec2KeyPair: {{key_name}}
            {% endif %}
            MaxvCpus: {{max_cpus}}
            MinvCpus: {{min_cpus}}
            Tags: {{tags}}
            {% if key_name %}
            Ec2KeyPair: {{key_name}}
            {% endif %}
            Subnets:
                {% for subnet in subnet_ids %}
                - {{subnet}}
                {% endfor %}
            InstanceTypes: {{instance_types}}
            InstanceRole:
                "Fn::GetAtt" : ["EcsInstanceProfile", "Arn"]
            SecurityGroupIds:
                - {Ref: SecurityGroup}
                {% for sg in security_group_ids %}
                - {{sg}}
                {% endfor %}
            Type: EC2
        State: "{{state}}"
    {% endif %}

    {% if has_priority_queue %}
    PriorityJobQueue:
        Type: "AWS::Batch::JobQueue"
        Properties:
            ComputeEnvironmentOrder:
                - Order: 1
                  ComputeEnvironment: {Ref: ComputeEnvironment}
                - Order: 2
                  ComputeEnvironment: {Ref: ComputeEnvironmentOndemandFallback}
            Priority: 100
            JobQueueName: "{{__context.environment.name}}-{{__context.layer.name}}-{{__context.stage}}-priority"
    {% endif %}

    DefaultJobQueue:
        Type: "AWS::Batch::JobQueue"
        Properties:
            ComputeEnvironmentOrder:
                - Order: 1
                  ComputeEnvironment: {Ref: ComputeEnvironment}
                - Order: 2
                  ComputeEnvironment: {Ref: ComputeEnvironmentOndemandFallback}
            Priority: 1
            JobQueueName: "{{__context.environment.name}}-{{__context.layer.name}}-{{__context.stage}}-default"
