diff --git a/.github/workflows/push_dev_infrastructure.yml b/.github/workflows/push_dev_infrastructure.yml new file mode 100644 index 0000000..b37b3d8 --- /dev/null +++ b/.github/workflows/push_dev_infrastructure.yml @@ -0,0 +1,26 @@ +name: Push Dev Infrastructure + +on: + push: + branches-ignore: + - master + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout Repo + uses: actions/checkout@v2.1.0 + with: + submodules: 'true' + - name: Ship to S3 + uses: jakejarvis/s3-sync-action@master + with: + args: --follow-symlinks --delete + env: + SOURCE_DIR: infrastructure/cloudformation + AWS_REGION: "us-east-1" + DEST_DIR: dt/develop/cloudformation + AWS_S3_BUCKET: sumu-stacks + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} \ No newline at end of file diff --git a/.github/workflows/release_server.yml b/.github/workflows/release_server.yml index 40af6ff..52e8941 100644 --- a/.github/workflows/release_server.yml +++ b/.github/workflows/release_server.yml @@ -68,4 +68,35 @@ jobs: DOCKERFILE: "server/Dockerfile" IMAGE_NAME: "defend-together" TAG_NAME: ${{ steps.get_tag.outputs.TAG }} - LATEST: "true" \ No newline at end of file + LATEST: "true" + cloudformation: + runs-on: ubuntu-latest + steps: + - name: Checkout Repo + uses: actions/checkout@v2.1.0 + with: + submodules: 'true' + - name: Ship to S3 + uses: jakejarvis/s3-sync-action@master + with: + args: --follow-symlinks --delete + env: + SOURCE_DIR: infrastructure/cloudformation + AWS_REGION: "us-east-1" + DEST_DIR: dt/production/cloudformation + AWS_S3_BUCKET: sumu-stacks + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v1 + with: + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws-region: us-east-1 + - name: Deploy to AWS CloudFormation + uses: aws-actions/aws-cloudformation-github-deploy@v1 + with: + name: ecs-nakama-stack + template: cloudformation/nakama/top.yaml + capabilities: "CAPABILITY_NAMED_IAM,CAPABILITY_IAM" + parameter-overrides: VpcId=${{ secrets.VPC_ID }},Domain=${{ secrets.DOMAIN }},PublicSubnets=${{ secrets.SUBNET_IDS }} \ No newline at end of file diff --git a/infrastructure/cloudformation/dt/dns.yaml b/infrastructure/cloudformation/dt/dns.yaml new file mode 100644 index 0000000..b572551 --- /dev/null +++ b/infrastructure/cloudformation/dt/dns.yaml @@ -0,0 +1,44 @@ +AWSTemplateFormatVersion: "2010-09-09" +Description: DT DNS stack +Parameters: + #------------------------ + # Deployment Information + #------------------------ + environment: + Type: String + Description: Name of the environment + Default: production + + #----------------------- + # Route53 Configuration + #----------------------- + Domain: + Type: String + Description: The HostedZoneName to create the endpoint on + SubDomain: + Type: String + Description: The subdomain to be used by dt + + #----------- + # Resources + #----------- + DtDNS: + Type: String + Description: Load balancer dns name for dt endpoint + +Resources: + DtEndpoint: + Type: AWS::Route53::RecordSet + Properties: + HostedZoneName: !Sub "${Domain}." + Comment: 'DNS name for dt' + Name: !Sub "${SubDomain}.${Domain}." + Type: CNAME + TTL: '300' + ResourceRecords: + - !Ref DtDNS + +Outputs: + Endpoint: + Description: 'DNS name for Defend Together' + Value: !Sub "${SubDomain}.${Domain}." \ No newline at end of file diff --git a/infrastructure/cloudformation/dt/load_balancing.yaml b/infrastructure/cloudformation/dt/load_balancing.yaml new file mode 100644 index 0000000..471b2f8 --- /dev/null +++ b/infrastructure/cloudformation/dt/load_balancing.yaml @@ -0,0 +1,67 @@ +AWSTemplateFormatVersion: "2010-09-09" +Description: DT load balancing stack +Parameters: + environment: + Type: String + Description: Name of the environment + Default: production + release: + Type: String + Description: Name of the release name of the stack version to use. + Default: production + PublicSubnets: + Description: The public subnets for the ALB to run in. + Type: String + VpcId: + Description: ID of the VPC + Type: AWS::EC2::VPC::Id + +Resources: + + #-- Network Load Balancer --# + PublicNLB: + Type: AWS::ElasticLoadBalancingV2::LoadBalancer + Properties: + Type: network + LoadBalancerAttributes: + - Key: deletion_protection.enabled + Value: false + Scheme: internet-facing + Subnets: !Split [",", !Ref PublicSubnets] + Tags: + - Key: Name + Value: !Sub "DT-${environment}-NLB" + - Key: environment + Value: !Ref environment + + NlbTargetGroup: + Type: AWS::ElasticLoadBalancingV2::TargetGroup + Properties: + Port: 7777 + Protocol: TCP_UDP + TargetGroupAttributes: + - Key: deregistration_delay.timeout_seconds + Value: '20' + VpcId: !Ref 'VpcId' + Tags: + - Key: Name + Value: !Sub 'DT-${release}' + + NlbListener: + Type: AWS::ElasticLoadBalancingV2::Listener + Properties: + DefaultActions: + - Type: forward + TargetGroupArn: !Ref NlbTargetGroup + LoadBalancerArn: !Ref PublicNLB + Port: 7777 + Protocol: TCP_UDP + + +Outputs: + TargetGroup: + Description: "" + Value: !Ref NlbTargetGroup + NlbDnsName: + Description: "" + Value: !GetAtt PublicNLB.DNSName \ No newline at end of file diff --git a/infrastructure/cloudformation/dt/task.yaml b/infrastructure/cloudformation/dt/task.yaml new file mode 100644 index 0000000..3118cee --- /dev/null +++ b/infrastructure/cloudformation/dt/task.yaml @@ -0,0 +1,38 @@ +AWSTemplateFormatVersion: '2010-09-09' +Description: Defend Togeher ECS Task +Parameters: + LogGroupName: + Type: String + Description: The AWS CloudWatch log group to output logs to. + Default: "/ecs/dt" + +Resources: + + LogGroup: + Type: AWS::Logs::LogGroup + Properties: + RetentionInDays: 7 + LogGroupName: !Ref LogGroupName + + TaskDefinition: + Type: AWS::ECS::TaskDefinition + Properties: + ContainerDefinitions: + - Name: defend-together + Essential: 'true' + Image: "josephbmanley/defend-together:latest" + MemoryReservation: 800 + PortMappings: + - HostPort: 0 + ContainerPort: 7777 + LogConfiguration: + LogDriver: awslogs + Options: + awslogs-region: + Ref: AWS::Region + awslogs-group: + Ref: LogGroup +Outputs: + TaskArn: + Description: ARN of the TaskDefinition + Value: !Ref TaskDefinition \ No newline at end of file diff --git a/infrastructure/cloudformation/dt/top.yaml b/infrastructure/cloudformation/dt/top.yaml new file mode 100644 index 0000000..3333599 --- /dev/null +++ b/infrastructure/cloudformation/dt/top.yaml @@ -0,0 +1,111 @@ +AWSTemplateFormatVersion: '2010-09-09' +Description: Defend Together ECS Infrastructure +Parameters: + #------------------------ + # Deployment Information + #------------------------ + environment: + Type: String + Description: Name of the environment to use in naming. + Default: production + release: + Type: String + Description: Name of the release name of the stack version to use. + Default: production + AllowedValues: ['develop', 'production'] + ConstraintDescription: "Must be a possible release version." + VpcId: + Description: ID of the VPC + Type: AWS::EC2::VPC::Id + + #----------------- + # Load Balancing + #----------------- + PublicSubnets: + Description: The public subnets for the ALB to run in. (Space seperated) + Type: String + + #----- + # DNS + #----- + Domain: + Type: String + Description: The domain to create the endpoint on (Must have an existing hosted zone ex. `example.com`) Leave blank to skip DNS. + Default: "" + SubDomain: + Type: String + Description: The subdomain to be used by dt. (ex. `dt.example.com`) + Default: dt + + #------------ + # CloudWatch + #------------ + LogGroup: + Type: String + Description: The AWS CloudWatch log group to output logs to. + Default: "/ecs/dt" + +Conditions: + CreateDns: !Not [!Equals [!Ref Domain, ""]] + +Resources: + + #----- + # DNS + #----- + DnsRecords: + Condition: CreateDns + Type: AWS::CloudFormation::Stack + Properties: + TemplateURL: !Sub 'https://s3.${AWS::Region}.amazonaws.com/sumu-stacks/dt/${release}/cloudformation/dt/dns.yaml' + Parameters: + environment: !Ref environment + Domain: !Ref Domain + SubDomain: !Ref SubDomain + DtDNS: !GetAtt LoadBalancing.Outputs.NlbDnsName + + #----------------- + # Load Balancing + #----------------- + LoadBalancing: + Type: AWS::CloudFormation::Stack + Properties: + TemplateURL: !Sub 'https://s3.${AWS::Region}.amazonaws.com/sumu-stacks/dt/${release}/cloudformation/dt/load_balancing.yaml' + Parameters: + environment: !Ref environment + release: !Ref release + VpcId: !Ref VpcId + PublicSubnets: !Join [",", !Split [" ", !Ref PublicSubnets]] + + EcsCluster: + Type: AWS::CloudFormation::Stack + Properties: + TemplateURL: !Sub 'https://s3.${AWS::Region}.amazonaws.com/sumu-stacks/dt/${release}/cloudformation/cluster/top.yaml' + Parameters: + Environment: !Ref environment + VpcId: !Ref VpcId + SubnetIds: !Join [",", !Split [" ", !Ref PublicSubnets]] + Project: "DT" + + #------------------- + # ECS Task & Service + #------------------- + TaskDefinition: + Type: AWS::CloudFormation::Stack + Properties: + TemplateURL: !Sub 'https://s3.${AWS::Region}.amazonaws.com/sumu-stacks/dt/${release}/cloudformation/dt/task.yaml' + Parameters: + LogGroupName: !Ref LogGroup + + + EcsService: + DependsOn: LoadBalancing + Type: AWS::ECS::Service + Properties: + Cluster: !GetAtt EcsCluster.Outputs.Cluster + DesiredCount: 1 + TaskDefinition: !GetAtt TaskDefinition.Outputs.TaskArn + LoadBalancers: + - ContainerName: "defend-together" + ContainerPort: 7777 + TargetGroupArn: !GetAtt LoadBalancing.Outputs.TargetGroup \ No newline at end of file