From 4f36e4e692107f3154184dab3f7d1f0a66d7c839 Mon Sep 17 00:00:00 2001 From: Wilco Breedt Date: Mon, 4 May 2020 13:26:00 +0200 Subject: [PATCH] Split fargate templates into mysql and postgresql --- aws/{fargate.yml => fargate-mysql.yml} | 2 +- aws/fargate-postgresql.yml | 457 +++++++++++++++++++++++++ 2 files changed, 458 insertions(+), 1 deletion(-) rename aws/{fargate.yml => fargate-mysql.yml} (99%) create mode 100644 aws/fargate-postgresql.yml diff --git a/aws/fargate.yml b/aws/fargate-mysql.yml similarity index 99% rename from aws/fargate.yml rename to aws/fargate-mysql.yml index 5491b81..833ea09 100644 --- a/aws/fargate.yml +++ b/aws/fargate-mysql.yml @@ -1,6 +1,6 @@ # Template adapted from https://github.com/nathanpeck/aws-cloudformation-fargate AWSTemplateFormatVersion: '2010-09-09' -Description: AWS Fargate Prisma stack. +Description: AWS Fargate Prisma stack (MySQL). Parameters: PrismaVersion: Type: String diff --git a/aws/fargate-postgresql.yml b/aws/fargate-postgresql.yml new file mode 100644 index 0000000..aac5b05 --- /dev/null +++ b/aws/fargate-postgresql.yml @@ -0,0 +1,457 @@ +# Template adapted from https://github.com/nathanpeck/aws-cloudformation-fargate +AWSTemplateFormatVersion: '2010-09-09' +Description: AWS Fargate Prisma stack (PostgreSQL). +Parameters: + PrismaVersion: + Type: String + Default: 1.34.0 + AllowedValues: + - 1.34.0 + - 1.33.0 + - 1.32.0 + - 1.31.0 + - 1.30.0 + - 1.29.0 + - 1.28.0 + - 1.27.0 + - 1.26.0 + - 1.25.0 + - 1.24.0 + - 1.23.0 + - 1.22.0 + - 1.21.0 + - 1.20.0 + - 1.19.0 + - 1.18.0 + - 1.17.0 + - 1.16.0 + - 1.15.0 + - 1.14.0 + - 1.13.0 + - 1.12.0 + - 1.11.0 + - 1.10.2 + - 1.9.0 + - 1.8.4 + - 1.8.3 + - 1.7.4 + + DbHost: + Type: String + + DbPort: + Type: Number + Default: 5432 + + DbUser: + Type: String + + DbPassword: + Type: String + NoEcho: true + + DbConnector: + Type: String + Default: postgres + + DbName: + Type: String + + DbSchema: + Type: String + Default: public + + + # Important: Follow the CPU + memory combination rules laid out here: + # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-taskdefinition.html + Cpu: + Type: String + Description: The CPU units for the container. Must adhere to https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-taskdefinition.html. + Default: 1024 + + Memory: + Description: The memory reservation for the container. Must adhere to https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-taskdefinition.html. + Type: Number + Default: 2048 + + JvmOpts: + Description: The JVM options passed to prisma. For example, change this value when changing the memory parameter. Max heap memory (Xmx) should be roughly two thirds of the total memory. + Type: String + Default: '-Xmx1350m' + + ManagementApiSecret: + Description: The secret for your Prisma server. + Type: String + +Mappings: + # Hard values for the subnet masks. These masks define + # the range of internal IP addresses that can be assigned. + # The VPC can have all IP's from 10.0.0.0 to 10.0.255.255 + # There are two subnets which cover the ranges: + # + # 10.0.0.0 - 10.0.0.255 + # 10.0.1.0 - 10.0.1.255 + # + # If you need more IP addresses (perhaps you have so many + # instances that you run out) then you can customize these + # ranges to add more + SubnetConfig: + VPC: + CIDR: '10.0.0.0/16' + PublicOne: + CIDR: '10.0.0.0/24' + PublicTwo: + CIDR: '10.0.1.0/24' + +Resources: + # VPC in which containers will be networked. + # It has two public subnets + # We distribute the subnets across the first two available subnets + # for the region, for high availability. + VPC: + Type: AWS::EC2::VPC + Properties: + EnableDnsSupport: true + EnableDnsHostnames: true + CidrBlock: !FindInMap ['SubnetConfig', 'VPC', 'CIDR'] + + # Two public subnets, where containers can have public IP addresses + PublicSubnetOne: + Type: AWS::EC2::Subnet + Properties: + AvailabilityZone: + Fn::Select: + - 0 + - Fn::GetAZs: {Ref: 'AWS::Region'} + VpcId: !Ref 'VPC' + CidrBlock: !FindInMap ['SubnetConfig', 'PublicOne', 'CIDR'] + MapPublicIpOnLaunch: true + + PublicSubnetTwo: + Type: AWS::EC2::Subnet + Properties: + AvailabilityZone: + Fn::Select: + - 1 + - Fn::GetAZs: {Ref: 'AWS::Region'} + VpcId: !Ref 'VPC' + CidrBlock: !FindInMap ['SubnetConfig', 'PublicTwo', 'CIDR'] + MapPublicIpOnLaunch: true + + # Setup networking resources for the public subnets. Containers + # in the public subnets have public IP addresses and the routing table + # sends network traffic via the internet gateway. + InternetGateway: + Type: AWS::EC2::InternetGateway + + GatewayAttachement: + Type: AWS::EC2::VPCGatewayAttachment + Properties: + VpcId: !Ref 'VPC' + InternetGatewayId: !Ref 'InternetGateway' + + PublicRouteTable: + Type: AWS::EC2::RouteTable + Properties: + VpcId: !Ref 'VPC' + + PublicRoute: + Type: AWS::EC2::Route + DependsOn: GatewayAttachement + Properties: + RouteTableId: !Ref 'PublicRouteTable' + DestinationCidrBlock: '0.0.0.0/0' + GatewayId: !Ref 'InternetGateway' + + PublicSubnetOneRouteTableAssociation: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + SubnetId: !Ref PublicSubnetOne + RouteTableId: !Ref PublicRouteTable + + PublicSubnetTwoRouteTableAssociation: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + SubnetId: !Ref PublicSubnetTwo + RouteTableId: !Ref PublicRouteTable + + # ECS Resources + ECSCluster: + Type: AWS::ECS::Cluster + + FargateContainerSecurityGroup: + Type: AWS::EC2::SecurityGroup + Properties: + GroupDescription: Access to the Fargate containers + VpcId: !Ref 'VPC' + + EcsSecurityGroupIngressFromPublicALB: + Type: AWS::EC2::SecurityGroupIngress + Properties: + Description: Ingress from the public ALB + GroupId: !Ref 'FargateContainerSecurityGroup' + IpProtocol: -1 + SourceSecurityGroupId: !Ref 'PublicLoadBalancerSG' + + EcsSecurityGroupIngressFromSelf: + Type: AWS::EC2::SecurityGroupIngress + Properties: + Description: Ingress from other containers in the same security group + GroupId: !Ref 'FargateContainerSecurityGroup' + IpProtocol: -1 + SourceSecurityGroupId: !Ref 'FargateContainerSecurityGroup' + + PublicLoadBalancerSG: + Type: AWS::EC2::SecurityGroup + Properties: + GroupDescription: Access to the public facing load balancer + VpcId: !Ref 'VPC' + SecurityGroupIngress: + - CidrIp: 0.0.0.0/0 + IpProtocol: -1 + + PublicLoadBalancer: + Type: AWS::ElasticLoadBalancingV2::LoadBalancer + Properties: + Scheme: internet-facing + LoadBalancerAttributes: + - Key: idle_timeout.timeout_seconds + Value: '30' + Subnets: + - !Ref PublicSubnetOne + - !Ref PublicSubnetTwo + SecurityGroups: [!Ref 'PublicLoadBalancerSG'] + + PrismaTargetGroup: + Type: AWS::ElasticLoadBalancingV2::TargetGroup + Properties: + HealthCheckIntervalSeconds: 6 + HealthCheckPath: /status + HealthCheckProtocol: HTTP + HealthCheckTimeoutSeconds: 5 + HealthyThresholdCount: 2 + Name: !Join ['-', [!Ref 'AWS::StackName', 'prisma']] + Port: 80 + Protocol: HTTP + UnhealthyThresholdCount: 2 + VpcId: !Ref 'VPC' + TargetType: 'ip' + + PublicLoadBalancerListener: + Type: AWS::ElasticLoadBalancingV2::Listener + DependsOn: + - PublicLoadBalancer + Properties: + DefaultActions: + - TargetGroupArn: !Ref 'PrismaTargetGroup' + Type: 'forward' + LoadBalancerArn: !Ref 'PublicLoadBalancer' + Port: 80 + Protocol: HTTP + + PrismaLogs: + Type: "AWS::Logs::LogGroup" + Properties: + LogGroupName: !Ref 'AWS::StackName' + RetentionInDays: 7 + + TaskDefinition: + Type: AWS::ECS::TaskDefinition + Properties: + Cpu: !Ref Cpu + Memory: !Ref Memory + RequiresCompatibilities: + - FARGATE + Family: prisma + NetworkMode: awsvpc + ExecutionRoleArn: !Ref ECSTaskExecutionRole # arn:aws:iam::000:role/EcsTaskExecutionRole + TaskRoleArn: !Ref ECSTaskExecutionRole #arn:aws:iam::000:role/EcsTaskExecutionRole + ContainerDefinitions: + - Name: prisma-container + Essential: true + Image: !Join [ ':', [ 'prismagraphql/prisma', !Ref PrismaVersion ] ] + PortMappings: + - ContainerPort: 60000 + Environment: + - Name: PRISMA_CONFIG + Value: !Sub + - | + port: 60000 + managementApiSecret: ${ManagementApiSecret} + ssl: true + databases: + default: + connector: ${DbConnector} + host: ${DbHost} + database: ${DbName} + port: ${DbPort} + user: ${DbUser} + password: ${DbPassword} + schema: ${DbSchema} + ssl: true + rawAccess: true + migrations: true + - {} + - Name: JAVA_OPTS + Value: !Ref JvmOpts + + Ulimits: + - Name: nofile + HardLimit: 1000000 + SoftLimit: 1000000 + LogConfiguration: + LogDriver: awslogs + Options: + awslogs-group: !Ref 'AWS::StackName' + awslogs-region: !Ref AWS::Region + awslogs-stream-prefix: prisma + + PrismaService: + Type: AWS::ECS::Service + DependsOn: PublicLoadBalancerListener + Properties: + Cluster: !Ref ECSCluster + ServiceName: Prisma + LaunchType: FARGATE + DesiredCount: 1 + DeploymentConfiguration: + MaximumPercent: 200 + MinimumHealthyPercent: 50 + TaskDefinition: !Ref TaskDefinition + LoadBalancers: + - ContainerName: prisma-container + ContainerPort: 60000 + TargetGroupArn: !Ref PrismaTargetGroup + NetworkConfiguration: + AwsvpcConfiguration: + AssignPublicIp: ENABLED + SecurityGroups: + - !Ref PublicLoadBalancerSG + Subnets: + - !Ref PublicSubnetOne + - !Ref PublicSubnetTwo + + # This is an IAM role which authorizes ECS to manage resources on your + # account on your behalf, such as updating your load balancer with the + # details of where your containers are, so that traffic can reach your + # containers. + ECSRole: + Type: AWS::IAM::Role + Properties: + AssumeRolePolicyDocument: + Statement: + - Effect: Allow + Principal: + Service: [ecs.amazonaws.com] + Action: ['sts:AssumeRole'] + Path: / + Policies: + - PolicyName: ecs-service + PolicyDocument: + Statement: + - Effect: Allow + Action: + # Rules which allow ECS to attach network interfaces to instances + # on your behalf in order for awsvpc networking mode to work right + - 'ec2:AttachNetworkInterface' + - 'ec2:CreateNetworkInterface' + - 'ec2:CreateNetworkInterfacePermission' + - 'ec2:DeleteNetworkInterface' + - 'ec2:DeleteNetworkInterfacePermission' + - 'ec2:Describe*' + - 'ec2:DetachNetworkInterface' + + # Rules which allow ECS to update load balancers on your behalf + # with the information sabout how to send traffic to your containers + - 'elasticloadbalancing:DeregisterInstancesFromLoadBalancer' + - 'elasticloadbalancing:DeregisterTargets' + - 'elasticloadbalancing:Describe*' + - 'elasticloadbalancing:RegisterInstancesWithLoadBalancer' + - 'elasticloadbalancing:RegisterTargets' + Resource: '*' + + # This is a role which is used by the ECS tasks themselves. + ECSTaskExecutionRole: + Type: AWS::IAM::Role + Properties: + AssumeRolePolicyDocument: + Statement: + - Effect: Allow + Principal: + Service: [ecs-tasks.amazonaws.com] + Action: ['sts:AssumeRole'] + Path: / + Policies: + - PolicyName: AmazonECSTaskExecutionRolePolicy + PolicyDocument: + Statement: + - Effect: Allow + Action: + # Allow the ECS Tasks to download images from ECR + - 'ecr:GetAuthorizationToken' + - 'ecr:BatchCheckLayerAvailability' + - 'ecr:GetDownloadUrlForLayer' + - 'ecr:BatchGetImage' + + # Allow the ECS tasks to upload logs to CloudWatch + - 'logs:CreateLogStream' + - 'logs:PutLogEvents' + Resource: '*' + +# These are the values output by the CloudFormation template. Be careful +# about changing any of them, because of them are exported with specific +# names so that the other task related CF templates can use them. +Outputs: + ClusterName: + Description: The name of the ECS cluster + Value: !Ref 'ECSCluster' + Export: + Name: !Join [ ':', [ !Ref 'AWS::StackName', 'ClusterName' ] ] + + ExternalUrl: + Description: The url of the external load balancer + Value: !Join ['', ['http://', !GetAtt 'PublicLoadBalancer.DNSName']] + Export: + Name: !Join [ ':', [ !Ref 'AWS::StackName', 'ExternalUrl' ] ] + + ECSRole: + Description: The ARN of the ECS role + Value: !GetAtt 'ECSRole.Arn' + Export: + Name: !Join [ ':', [ !Ref 'AWS::StackName', 'ECSRole' ] ] + + ECSTaskExecutionRole: + Description: The ARN of the ECS role + Value: !GetAtt 'ECSTaskExecutionRole.Arn' + Export: + Name: !Join [ ':', [ !Ref 'AWS::StackName', 'ECSTaskExecutionRole' ] ] + + PublicListener: + Description: The ARN of the public load balancer's Listener + Value: !Ref PublicLoadBalancerListener + Export: + Name: !Join [ ':', [ !Ref 'AWS::StackName', 'PublicListener' ] ] + + VPCId: + Description: The ID of the VPC that this stack is deployed in + Value: !Ref 'VPC' + Export: + Name: !Join [ ':', [ !Ref 'AWS::StackName', 'VPCId' ] ] + + PublicSubnetOne: + Description: Public subnet one + Value: !Ref 'PublicSubnetOne' + Export: + Name: !Join [ ':', [ !Ref 'AWS::StackName', 'PublicSubnetOne' ] ] + + PublicSubnetTwo: + Description: Public subnet two + Value: !Ref 'PublicSubnetTwo' + Export: + Name: !Join [ ':', [ !Ref 'AWS::StackName', 'PublicSubnetTwo' ] ] + + FargateContainerSecurityGroup: + Description: A security group used to allow Fargate containers to receive traffic + Value: !Ref 'FargateContainerSecurityGroup' + Export: + Name: !Join [ ':', [ !Ref 'AWS::StackName', 'FargateContainerSecurityGroup' ] ] \ No newline at end of file