From 37a0093dd73e00b8f7f30be23e20ecaa42056493 Mon Sep 17 00:00:00 2001 From: Joe Bailey Date: Sun, 12 Feb 2023 17:47:25 -0800 Subject: [PATCH] Aws pipeline (#2) Got the code pipeline nearly done, need to get the updated docker file in main. --- Dockerfile | 2 +- infra/templates/deployment-pipeline.yaml | 68 ++++++------ infra/templates/ecs-cluster.yaml | 130 ++--------------------- infra/templates/service.yaml | 75 +++++++------ 4 files changed, 87 insertions(+), 188 deletions(-) diff --git a/Dockerfile b/Dockerfile index fd7caee0e..12b89f4d0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,3 +1,3 @@ -FROM openjdk:8-jdk-alpine +FROM openjdk:20-ea-17-jdk COPY target/spring-petclinic-3.0.0-SNAPSHOT.jar spring-petclinic-3.0.0-SNAPSHOT.jar ENTRYPOINT ["java","-jar","/spring-petclinic-3.0.0-SNAPSHOT.jar"] diff --git a/infra/templates/deployment-pipeline.yaml b/infra/templates/deployment-pipeline.yaml index acde08b22..a924d1301 100644 --- a/infra/templates/deployment-pipeline.yaml +++ b/infra/templates/deployment-pipeline.yaml @@ -29,6 +29,7 @@ Parameters: Type: String Resources: + BlueGreenFlipLambda: Type: AWS::Lambda::Function Properties: @@ -44,19 +45,20 @@ Resources: Role: !GetAtt BlueGreenFlipLambdaRole.Arn BlueGreenFlipLambdaRole: - Type: AWS::IAM::Role - Properties: - #RoleName: !Sub lambda-${GitHubRepo}-blue-green-swap-role - AssumeRolePolicyDocument: - Version: "2012-10-17" - Statement: - - Effect: Allow - Principal: - Service: - - lambda.amazonaws.com - Action: - - sts:AssumeRole - Path: / + Type: AWS::IAM::Role + Properties: + #RoleName: !Sub lambda-${GitHubRepo}-blue-green-swap-role + AssumeRolePolicyDocument: + Version: "2012-10-17" + Statement: + - + Effect: Allow + Principal: + Service: + - lambda.amazonaws.com + Action: + - sts:AssumeRole + Path: / BlueGreenFlipLambdaPolicy: Type: AWS::IAM::Policy @@ -65,20 +67,23 @@ Resources: PolicyDocument: Version: "2012-10-17" Statement: - - Effect: Allow + - + Effect: Allow Action: - elasticloadbalancing:* - codepipeline:PutJobFailureResult - codepipeline:PutJobSuccessResult Resource: "*" - - Effect: Allow + - + Effect: Allow Action: - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents Resource: arn:aws:logs:*:*:* Roles: - - !Ref BlueGreenFlipLambdaRole + - + !Ref BlueGreenFlipLambdaRole Repository: Type: AWS::ECR::Repository @@ -212,23 +217,21 @@ Resources: phases: # install: # commands: - # - apt-get update -y - # - apt-get -y install python-pip - # - pip install --upgrade python - # - pip install --upgrade awscli + # - apt-get update && apt-get -y install python-pip + # - pip install --upgrade python + # - pip install --upgrade awscli pre_build: commands: - printenv - echo -n "$CODEBUILD_LOG_PATH" > /tmp/build_id.out - printf "%s:%s" "$REPOSITORY_URI" "$(cat /tmp/build_id.out)" > /tmp/build_tag.out - printf '{"tag":"%s"}' "$(cat /tmp/build_id.out)" > /tmp/build.json - # - $(aws ecr get-login-password) + - echo Logging in to Amazon ECR... + - aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin "$(aws sts get-caller-identity --query \"Account\" --output text)".dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com build: commands: - - ./mvnw package + - ./mvnw package -DskipTests - docker build --tag "$(cat /tmp/build_tag.out)" . - # - ./mvnw spring-boot:build-image - - docker image tag spring-petclinic:3.0.0-SNAPSHOT "$(cat /tmp/build_tag.out)" post_build: commands: - docker push "$(cat /tmp/build_tag.out)" @@ -239,13 +242,12 @@ Resources: ComputeType: "BUILD_GENERAL1_SMALL" Image: "aws/codebuild/standard:6.0" Type: "LINUX_CONTAINER" + PrivilegedMode: true EnvironmentVariables: - Name: AWS_DEFAULT_REGION Value: !Ref AWS::Region - Name: REPOSITORY_URI Value: !Sub ${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/${Repository} - - Name: DOCKER_HOST - Value: unix:///var/run/docker.sock Name: !Sub ${AWS::StackName}-codebuildproject ServiceRole: !Ref CodeBuildServiceRole @@ -259,11 +261,11 @@ Resources: BuildSpec: | version: 0.1 phases: - install: - commands: - - pip install --upgrade python - - pip install --upgrade awscli - - pip install --upgrade boto3 + # install: + # commands: + # - pip install --upgrade python + # - pip install --upgrade awscli + # - pip install --upgrade boto3 pre_build: commands: - printenv @@ -274,7 +276,7 @@ Resources: discard-paths: yes Environment: ComputeType: "BUILD_GENERAL1_SMALL" - Image: aws/codebuild/python:2.7.12 + Image: "aws/codebuild/standard:6.0" Type: "LINUX_CONTAINER" EnvironmentVariables: - Name: AWS_DEFAULT_REGION @@ -415,6 +417,8 @@ Resources: } RunOrder: 3 + + Outputs: PipelineUrl: Value: !Sub https://console.aws.amazon.com/codepipeline/home?region=${AWS::Region}#/view/${Pipeline} diff --git a/infra/templates/ecs-cluster.yaml b/infra/templates/ecs-cluster.yaml index 52331ecd6..8f8dc4ac3 100644 --- a/infra/templates/ecs-cluster.yaml +++ b/infra/templates/ecs-cluster.yaml @@ -41,137 +41,13 @@ Parameters: S3 Bucket used for nested templates -Mappings: - AWSRegionToAMI: - us-east-1: - AMI: ami-71ef560b - us-east-2: - AMI: ami-1b8ca37e - us-west-1: - AMI: ami-e5cdf385 - us-west-2: - AMI: ami-a64d9ade - eu-west-1: - AMI: ami-014ae578 - eu-west-2: - AMI: ami-4f8d912b - eu-central-1: - AMI: ami-4255d32d - ap-northeast-1: - AMI: ami-3405af52 - ap-southeast-1: - AMI: ami-134e0670 - ap-southeast-2: - AMI: ami-2ab95148 - ca-central-1: - AMI: ami-c802baac - - Resources: - ECSRole: - Type: AWS::IAM::Role - Properties: - Path: / - #RoleName: !Sub ecs-${AWS::StackName} - AssumeRolePolicyDocument: | - { - "Statement": [{ - "Effect": "Allow", - "Principal": { "Service": [ "ec2.amazonaws.com" ]}, - "Action": [ "sts:AssumeRole" ] - }] - } - ManagedPolicyArns: - - arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role - - InstanceProfile: - Type: AWS::IAM::InstanceProfile - Properties: - Path: / - Roles: - - !Ref ECSRole - - SecurityGroup: - Type: "AWS::EC2::SecurityGroup" - Properties: - GroupDescription: !Sub ${AWS::StackName}-hosts - SecurityGroupIngress: - - SourceSecurityGroupId: !GetAtt LoadBalancer.Outputs.SecurityGroup - IpProtocol: -1 - VpcId: !Ref VpcId Cluster: Type: AWS::ECS::Cluster Properties: ClusterName: !Ref AWS::StackName - AutoScalingGroup: - Type: AWS::AutoScaling::AutoScalingGroup - Properties: - VPCZoneIdentifier: - - !Ref Subnet1 - - !Ref Subnet2 - LaunchConfigurationName: !Ref LaunchConfiguration - MinSize: !Ref ClusterSize - MaxSize: !Ref ClusterSize - DesiredCapacity: !Ref ClusterSize - Tags: - - Key: Name - Value: !Sub ${AWS::StackName} - ECS Host - PropagateAtLaunch: true - CreationPolicy: - ResourceSignal: - Timeout: PT15M - UpdatePolicy: - AutoScalingRollingUpdate: - MinInstancesInService: 1 - MaxBatchSize: 1 - PauseTime: PT15M - WaitOnResourceSignals: true - - LaunchConfiguration: - Type: AWS::AutoScaling::LaunchConfiguration - Metadata: - AWS::CloudFormation::Init: - config: - commands: - 01_add_instance_to_cluster: - command: !Sub echo ECS_CLUSTER=${Cluster} > /etc/ecs/ecs.config - files: - "/etc/cfn/cfn-hup.conf": - mode: 000400 - owner: root - group: root - content: !Sub | - [main] - stack=${AWS::StackId} - region=${AWS::Region} - "/etc/cfn/hooks.d/cfn-auto-reloader.conf": - content: !Sub | - [cfn-auto-reloader-hook] - triggers=post.update - path=Resources.ContainerInstances.Metadata.AWS::CloudFormation::Init - action=/opt/aws/bin/cfn-init -v --region ${AWS::Region} --stack ${AWS::StackName} --resource LaunchConfiguration - services: - sysvinit: - cfn-hup: - enabled: true - ensureRunning: true - files: - - /etc/cfn/cfn-hup.conf - - /etc/cfn/hooks.d/cfn-auto-reloader.conf - Properties: - ImageId: !FindInMap [ AWSRegionToAMI, !Ref "AWS::Region", AMI ] - InstanceType: !Ref InstanceType - IamInstanceProfile: !Ref InstanceProfile - SecurityGroups: - - !Ref SecurityGroup - UserData: - "Fn::Base64": !Sub | - #!/bin/bash - yum install -y aws-cfn-bootstrap - /opt/aws/bin/cfn-init -v --region ${AWS::Region} --stack ${AWS::StackName} --resource LaunchConfiguration - /opt/aws/bin/cfn-signal -e $? --region ${AWS::Region} --stack ${AWS::StackName} --resource AutoScalingGroup LoadBalancer: Type: AWS::CloudFormation::Stack @@ -198,6 +74,9 @@ Resources: Repository: !Ref Repository Identifier: "Code2" IsProduction: False + Subnet1 : !Ref Subnet1 + Subnet2 : !Ref Subnet2 + ALBSg : !GetAtt LoadBalancer.Outputs.SecurityGroup BlueService: Type: AWS::CloudFormation::Stack @@ -213,6 +92,9 @@ Resources: Repository: !Ref Repository Identifier: "Code1" IsProduction: True + Subnet1 : !Ref Subnet1 + Subnet2 : !Ref Subnet2 + ALBSg : !GetAtt LoadBalancer.Outputs.SecurityGroup Outputs: diff --git a/infra/templates/service.yaml b/infra/templates/service.yaml index cd944ac5d..a2d6cc5bf 100644 --- a/infra/templates/service.yaml +++ b/infra/templates/service.yaml @@ -31,9 +31,16 @@ Parameters: IsProduction: Type: String + Subnet1: + Type: String + + Subnet2: + Type: String + + ALBSg: + Type: String Resources: - LoadBalancerListener: Type: AWS::ElasticLoadBalancingV2::Listener Properties: @@ -48,6 +55,7 @@ Resources: Type: AWS::ElasticLoadBalancingV2::TargetGroup Properties: VpcId: !Ref VpcId + TargetType: ip Port: !Ref Port Protocol: HTTP Matcher: @@ -77,69 +85,74 @@ Resources: Conditions: - Field: path-pattern Values: - - "*" + - "*" ListenerArn: !Ref LoadBalancerListener Priority: 1 - ECSServiceRole: + TaskIamRole: Type: AWS::IAM::Role Properties: - #RoleName: !Sub ecs-service-${AWS::StackName} Path: / AssumeRolePolicyDocument: | { "Statement": [{ "Effect": "Allow", - "Principal": { "Service": [ "ecs.amazonaws.com" ]}, + "Principal": { "Service": [ "ecs-tasks.amazonaws.com" ]}, "Action": [ "sts:AssumeRole" ] }] } ManagedPolicyArns: - - arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceRole + - arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly + - arn:aws:iam::aws:policy/CloudWatchLogsFullAccess + SecurityGroup: + Type: AWS::EC2::SecurityGroup + Properties: + GroupDescription: !Sub ${AWS::StackName} + SecurityGroupIngress: + - SourceSecurityGroupId: !Ref ALBSg + IpProtocol: -1 + VpcId: !Ref VpcId Service: Type: AWS::ECS::Service Properties: Cluster: !Ref Cluster - Role: !Ref ECSServiceRole DesiredCount: !Ref DesiredCount + LaunchType: FARGATE TaskDefinition: !Ref TaskDefinition LoadBalancers: - ContainerName: simple-app - ContainerPort: 80 + ContainerPort: 8080 TargetGroupArn: !Ref TargetGroup + NetworkConfiguration: + AwsvpcConfiguration: + AssignPublicIp: ENABLED #MENTION DISABLED if in private subnet with NAT gateway + SecurityGroups: + - !GetAtt SecurityGroup.GroupId + Subnets: + - !Ref Subnet1 + - !Ref Subnet2 TaskDefinition: Type: AWS::ECS::TaskDefinition Properties: - #Family: !Sub ${AWS::StackName}-simple-app + Cpu: 512 + Memory: 512 + NetworkMode: awsvpc + RequiresCompatibilities: + - FARGATE + ExecutionRoleArn: !GetAtt TaskIamRole.Arn ContainerDefinitions: - Name: simple-app Image: !Sub ${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/${Repository}:${Tag} - EntryPoint: - - /usr/sbin/apache2 - - -D - - FOREGROUND + # EntryPoint: + # - /usr/sbin/apache2 + # - -D + # - FOREGROUND Essential: true - Memory: 128 - MountPoints: - - SourceVolume: my-vol - ContainerPath: /var/www/my-vol + Memory: 512 PortMappings: - - ContainerPort: 80 + - ContainerPort: 8080 Environment: - Name: Tag Value: !Ref Tag - - Name: busybox - Image: busybox - EntryPoint: - - sh - - -c - Essential: false - Memory: 128 - VolumesFrom: - - SourceContainer: simple-app - Command: - - /bin/sh -c "while true; do /bin/date > /var/www/my-vol/date; sleep 1; done" - Volumes: - - Name: my-vol