| AWSTemplateFormatVersion: '2010-09-09' |
| Description: Deploy a service into an ECS cluster behind a public load balancer. |
| Parameters: |
| LBServiceName: |
| Type: String |
| Default: gerrit-load-balancer |
| ClusterStackName: |
| Description: Stack name of the ECS cluster to deploy the services |
| Type: String |
| Default: gerrit-cluster |
| TemplateBucketName: |
| Description: S3 bucket containing cloudformation templates |
| Type: String |
| EnvironmentName: |
| Description: An environment name used to build the log stream names |
| Type: String |
| Default: test |
| HAProxyDockerImage: |
| Description: HAProxy Docker image |
| Type: String |
| Default: aws-gerrit/haproxy:latest |
| SidecarDockerImage: |
| Description: Syslog sidecar Docker image |
| Type: String |
| Default: aws-gerrit/syslog-sidecar:latest |
| DockerRegistryUrl: |
| Description: Docker registry URL |
| Type: String |
| DesiredCount: |
| Description: How many instances of this task should we run across our cluster? |
| Type: Number |
| MinValue: 2 |
| Default: 2 |
| ConstraintDescription: number of haproxy must be at least 2 |
| HTTPGerritPort: |
| Description: Gerrit HTTP port |
| Type: Number |
| Default: 8080 |
| SSHGerritPort: |
| Description: Gerrit SSH port |
| Type: Number |
| Default: 29418 |
| HTTPContainerPort: |
| Description: Gerrit HTTP port |
| Type: Number |
| Default: 80 |
| HTTPSHostPort: |
| Description: Gerrit HTTPS port |
| Type: Number |
| Default: 443 |
| HTTPHostPort: |
| Description: HAProxy HTTP port |
| Type: Number |
| Default: 80 |
| CertificateArn: |
| Description: SSL Certificates ARN |
| Type: String |
| HostedZoneName: |
| Description: The route53 HostedZoneName. |
| Type: String |
| Subdomain: |
| Description: The subdomain of the Gerrit cluster |
| Type: String |
| Default: gerrit-dual-primary |
| LoadBalancerScheme: |
| Description: Load Balancer schema, The nodes of an Internet-facing load balancer have public IP addresses. |
| Type: String |
| Default: internet-facing |
| AllowedValues: [internal, internet-facing] |
| GerritKeyPrefix: |
| Description: Gerrit credentials keys prefix |
| Type: String |
| Primary1ServiceStackName: |
| Description: Stack name of the ECS Primary Gerrit service |
| Type: String |
| Default: gerrit-service-primary-1 |
| Primary2ServiceStackName: |
| Description: Stack name of the ECS Primary Gerrit service |
| Type: String |
| Default: gerrit-service-primary-2 |
| SyslogSidecarServiceName: |
| Description: HAPRoxy Syslog Sidecar service name |
| Type: String |
| Default: gerrit-haproxy-sidecar |
| HealthCheckGracePeriodSeconds: |
| Description: HAProxy Healtcheck Grace Period |
| Type: Number |
| Default: 60 |
| |
| Resources: |
| LBService: |
| Type: AWS::ECS::Service |
| DependsOn: |
| - HTTPListener |
| - SSHListener |
| Properties: |
| Cluster: |
| Fn::ImportValue: |
| !Join [':', [!Ref 'ClusterStackName', 'ClusterName']] |
| DesiredCount: !Ref DesiredCount |
| TaskDefinition: !Ref TaskDefinition |
| HealthCheckGracePeriodSeconds: !Ref HealthCheckGracePeriodSeconds |
| LoadBalancers: |
| - ContainerName: !Ref LBServiceName |
| ContainerPort: !Ref HTTPContainerPort |
| TargetGroupArn: !Ref HTTPTargetGroup |
| - ContainerName: !Ref LBServiceName |
| ContainerPort: !Ref SSHGerritPort |
| TargetGroupArn: !Ref SSHTargetGroup |
| |
| TaskDefinition: |
| Type: AWS::ECS::TaskDefinition |
| Properties: |
| Family: !Sub '${LBServiceName}TaskDefinition' |
| TaskRoleArn: !GetAtt ECSTaskExecutionRoleStack.Outputs.TaskExecutionRoleRef |
| ExecutionRoleArn: !GetAtt ECSTaskExecutionRoleStack.Outputs.TaskExecutionRoleRef |
| NetworkMode: bridge |
| PlacementConstraints: |
| - Expression: !Sub 'attribute:target_group == haproxy' |
| Type: "memberOf" |
| ContainerDefinitions: |
| - Name: !Ref LBServiceName |
| Essential: true |
| Image: !Sub '${DockerRegistryUrl}/${HAProxyDockerImage}' |
| Environment: |
| - Name: GERRIT_PRIMARY_1_URL |
| Value: |
| Fn::ImportValue: !Join [':', [!Ref 'Primary1ServiceStackName', 'PublicLoadBalancerDNSName']] |
| - Name: GERRIT_PRIMARY_2_URL |
| Value: |
| Fn::ImportValue: !Join [':', [!Ref 'Primary2ServiceStackName', 'PublicLoadBalancerDNSName']] |
| - Name: SYSLOG_SIDECAR |
| Value: !Ref SyslogSidecarServiceName |
| Cpu: 1024 |
| Memory: 2048 |
| PortMappings: |
| - ContainerPort: !Ref HTTPContainerPort |
| HostPort: !Ref HTTPHostPort |
| Protocol: tcp |
| - ContainerPort: !Ref SSHGerritPort |
| HostPort: !Ref SSHGerritPort |
| Protocol: tcp |
| Links: |
| - !Ref SyslogSidecarServiceName |
| LogConfiguration: |
| LogDriver: awslogs |
| Options: |
| awslogs-group: !Ref ClusterStackName |
| awslogs-region: !Ref AWS::Region |
| awslogs-stream-prefix: !Ref EnvironmentName |
| - Name: !Ref SyslogSidecarServiceName |
| Essential: true |
| Image: !Sub '${DockerRegistryUrl}/${SidecarDockerImage}' |
| Cpu: 256 |
| Memory: 512 |
| LogConfiguration: |
| LogDriver: awslogs |
| Options: |
| awslogs-group: !Ref ClusterStackName |
| awslogs-region: !Ref AWS::Region |
| awslogs-stream-prefix: !Ref EnvironmentName |
| |
| ECSTaskExecutionRoleStack: |
| Type: AWS::CloudFormation::Stack |
| Properties: |
| TemplateURL: !Join [ '', ['https://', !Ref TemplateBucketName, '.s3.amazonaws.com/cf-gerrit-task-execution-role.yml'] ] |
| TimeoutInMinutes: '5' |
| |
| LoadBalancer: |
| Type: AWS::ElasticLoadBalancingV2::LoadBalancer |
| Properties: |
| Type: network |
| Scheme: !Ref 'LoadBalancerScheme' |
| LoadBalancerAttributes: |
| - Key: 'load_balancing.cross_zone.enabled' |
| Value: true |
| Subnets: |
| - Fn::ImportValue: |
| !Join [':', [!Ref 'ClusterStackName', 'PublicSubnetOne']] |
| - Fn::ImportValue: |
| !Join [':', [!Ref 'ClusterStackName', 'PublicSubnetTwo']] |
| Tags: |
| - Key: Name |
| Value: !Join ['-', [!Ref 'EnvironmentName', !Ref 'LBServiceName', 'alb']] |
| |
| HTTPTargetGroup: |
| Type: AWS::ElasticLoadBalancingV2::TargetGroup |
| DependsOn: LoadBalancer |
| Properties: |
| VpcId: |
| Fn::ImportValue: |
| !Join [':', [!Ref 'ClusterStackName', 'VPCId']] |
| Port: !Ref HTTPHostPort |
| Protocol: TCP |
| Name: 'haproxy-http' |
| |
| HTTPListener: |
| Type: AWS::ElasticLoadBalancingV2::Listener |
| DependsOn: LoadBalancer |
| Properties: |
| Certificates: |
| - CertificateArn: !Ref CertificateArn |
| DefaultActions: |
| - Type: forward |
| TargetGroupArn: !Ref HTTPTargetGroup |
| LoadBalancerArn: !Ref LoadBalancer |
| Port: !Ref HTTPSHostPort |
| Protocol: TLS |
| |
| SSHTargetGroup: |
| Type: AWS::ElasticLoadBalancingV2::TargetGroup |
| DependsOn: LoadBalancer |
| Properties: |
| VpcId: |
| Fn::ImportValue: |
| !Join [':', [!Ref 'ClusterStackName', 'VPCId']] |
| Port: !Ref SSHGerritPort |
| Protocol: TCP |
| Name: 'haproxy-ssh' |
| |
| SSHListener: |
| Type: AWS::ElasticLoadBalancingV2::Listener |
| DependsOn: LoadBalancer |
| Properties: |
| DefaultActions: |
| - Type: forward |
| TargetGroupArn: !Ref SSHTargetGroup |
| LoadBalancerArn: !Ref LoadBalancer |
| Port: !Ref SSHGerritPort |
| Protocol: TCP |
| |
| Outputs: |
| PublicLoadBalancerDNSName: |
| Description: The DNS name of the external load balancer |
| Value: !GetAtt 'LoadBalancer.DNSName' |
| Export: |
| Name: !Join [ ':', [ !Ref 'AWS::StackName', 'PublicLoadBalancerDNSName' ] ] |
| CanonicalHostedZoneID: |
| Description: Canonical Hosted Zone ID |
| Value: !GetAtt 'LoadBalancer.CanonicalHostedZoneID' |
| Export: |
| Name: !Join [ ':', [ !Ref 'AWS::StackName', 'CanonicalHostedZoneID' ] ] |
| PublicLoadBalancerUrl: |
| Description: The url of the external load balancer |
| Value: !Join ['', ['https://', !GetAtt 'LoadBalancer.DNSName']] |
| Export: |
| Name: !Join [ ':', [ !Ref 'AWS::StackName', 'PublicLoadBalancerUrl' ] ] |
| HostedZoneName: |
| Description: Route53 Hosted Zone name |
| Value: !Ref HostedZoneName |
| Export: |
| Name: !Join [ ':', [ !Ref 'AWS::StackName', 'HostedZoneName' ] ] |
| Subdomain: |
| Description: Service DNS subdomain |
| Value: !Ref Subdomain |
| Export: |
| Name: !Join [ ':', [ !Ref 'AWS::StackName', 'Subdomain' ] ] |
| CanonicalWebUrl: |
| Description: Canonical Web URL |
| Value: !Sub 'https://${Subdomain}.${HostedZoneName}' |
| Export: |
| Name: !Join [ ':', [ !Ref 'AWS::StackName', 'CanonicalWebUrl' ] ] |