diff --git a/aws/aws-hello-world/src/main/java/io/reflectoring/awshelloworld/HelloWorldController.java b/aws/aws-hello-world/src/main/java/io/reflectoring/awshelloworld/HelloWorldController.java
index b155b06..81a5720 100644
--- a/aws/aws-hello-world/src/main/java/io/reflectoring/awshelloworld/HelloWorldController.java
+++ b/aws/aws-hello-world/src/main/java/io/reflectoring/awshelloworld/HelloWorldController.java
@@ -8,7 +8,7 @@ public class HelloWorldController {
@GetMapping("/hello")
public String helloWorld(){
- return "Hello AWS!";
+ return "Hello AWS (v4)!";
}
}
diff --git a/aws/cloudformation/ecs-zero-downtime-deployment/README.md b/aws/cloudformation/ecs-zero-downtime-deployment/README.md
new file mode 100644
index 0000000..011d51d
--- /dev/null
+++ b/aws/cloudformation/ecs-zero-downtime-deployment/README.md
@@ -0,0 +1,8 @@
+# Overview
+
+
+
+# Companion Blog Post
+
+[The AWS Journey Part 2: Deploying a Docker image from the Command Line with CloudFormation](https://reflectoring.io/aws-cloudformation-deploy-docker-image/)
+
diff --git a/aws/cloudformation/ecs-zero-downtime-deployment/create.sh b/aws/cloudformation/ecs-zero-downtime-deployment/create.sh
new file mode 100644
index 0000000..f3ea693
--- /dev/null
+++ b/aws/cloudformation/ecs-zero-downtime-deployment/create.sh
@@ -0,0 +1,22 @@
+# Turning off the AWS pager so that the CLI doesn't open an editor for each command result
+export AWS_PAGER=""
+
+aws cloudformation create-stack \
+ --stack-name reflectoring-ecs-zero-downtime-deployment-network \
+ --template-body file://network.yml \
+ --capabilities CAPABILITY_IAM
+
+aws cloudformation wait stack-create-complete --stack-name reflectoring-ecs-zero-downtime-deployment-network
+
+aws cloudformation create-stack \
+ --stack-name reflectoring-ecs-zero-downtime-deployment-service \
+ --template-body file://service.yml \
+ --parameters \
+ ParameterKey=StackName,ParameterValue=reflectoring-ecs-zero-downtime-deployment-network \
+ ParameterKey=ServiceName,ParameterValue=reflectoring-hello-world \
+ ParameterKey=ImageUrl,ParameterValue=docker.io/reflectoring/aws-hello-world:latest \
+ ParameterKey=ContainerPort,ParameterValue=8080 \
+ ParameterKey=HealthCheckPath,ParameterValue=/hello \
+ ParameterKey=HealthCheckIntervalSeconds,ParameterValue=90
+
+aws cloudformation wait stack-create-complete --stack-name reflectoring-ecs-zero-downtime-deployment-service
diff --git a/aws/cloudformation/ecs-zero-downtime-deployment/delete.sh b/aws/cloudformation/ecs-zero-downtime-deployment/delete.sh
new file mode 100644
index 0000000..4ad3bcf
--- /dev/null
+++ b/aws/cloudformation/ecs-zero-downtime-deployment/delete.sh
@@ -0,0 +1,8 @@
+# Turning off the AWS pager so that the CLI doesn't open an editor for each command result
+export AWS_PAGER=""
+
+aws cloudformation delete-stack --stack-name reflectoring-ecs-zero-downtime-deployment-service
+aws cloudformation wait stack-delete-complete --stack-name reflectoring-ecs-zero-downtime-deployment-service
+
+aws cloudformation delete-stack --stack-name reflectoring-ecs-zero-downtime-deployment-network
+aws cloudformation wait stack-delete-complete --stack-name reflectoring-ecs-zero-downtime-deployment-network
\ No newline at end of file
diff --git a/aws/cloudformation/ecs-zero-downtime-deployment/ecs-in-two-public-subnets.drawio b/aws/cloudformation/ecs-zero-downtime-deployment/ecs-in-two-public-subnets.drawio
new file mode 100644
index 0000000..ee42712
--- /dev/null
+++ b/aws/cloudformation/ecs-zero-downtime-deployment/ecs-in-two-public-subnets.drawio
@@ -0,0 +1 @@
+7Vpbb+o4EP41PC7K/fLIrWcr9UiVWO05+4RM4garIc4aU6C/fseJc7ND6ekB9nQXVKmZsTMez3yf7TEM7Ml6/4WhfPWVxjgdWEa8H9jTgWWZphXCP6E5lBrPcEpFwkgsOzWKOXnFUmlI7ZbEeNPpyClNOcm7yohmGY54R4cYo7tutyeadkfNUYI1xTxCqa79RmK+qublhU3D75gkKzl0YPllwxpVneVMNisU011LZc8G9oRRysun9X6CUxG8Ki7le3dHWmvHGM74e15Y4cjav97736avy2fP+Rr/vVj+Vjn3gtKtnPGfjxPpMD9UUcgpyXgRSXcMf/DSxBi40DIR0tByFYUq+12FqUvCRlehyn5XYarmTWV8U3WwpdCkjnlDGd9oOQh/9phueUoyPKkxZ4AyYSgmkIsJTSkDXUYziN54xdcpSCY87laE43mOIhHVHfAFdE804xL1plXJMvDiHUBNLp7X+0QQbIh2G2eYMLrNiyHvAfe9rYuXPBKvc0afceXSwLItJwhMRwxE0lRx9QUzTgD6o5QkwiqnYhAkpRQ/cWER/CdZ8lBIU9uQPreGGI3G/jgAfYw2KxzL8EicwRB4fxTBZs0LWFAwXWPODtClesGTaJVrSQXeXUNMO5S6VYuTjiGVSC4GSW264Qs8SMr8AH3MUKPP43aZkkjQZ7vMML9R6fNTaYOjLSP8sGg6zwteSXffRzLQz8I7e+adj2n1OOdmmm0pTLPCoR1obKsZ2Gab6ZkFSC5COPvGtxvf/vt8c4Buftj6uL8A90xfI99sMgfFHLMXAshQqddzxNBS5468SeC1Q2oezZcKMCU7talzJMTvJsTvXf9MuycHVnip04arxX9geamA7hIeEvEwynNYDREnwK2qjVWNDxTFuhZogLIIs6oFXKvNaSntXT46bKhS94CWOH2kG1L4Yk+XlHO6PsnFCBIEvnQWn56FxB6iZqaLFCa2WFbz0JaBOzdwbef4OncGvMAZs4MX0w+GgQ6Yqmps48W3LgSX4DRc7kWwi13TQ2uRhmy5yYuIqCj5gjjeocMnAwmR81sk0v1+bHgXxUa9SrSw4esL+lWxodct5VL+B9o8vy+f6tZoW3difC2OIsZ+MDPa/JsSBobKlGeUiQioeZka7gQ2nJ4d46n4XAFRp843aJOX4Xgie+FH/4GH4Q3dsgiXx50xiH0HHxxtzgO2utatwGb07lx+z8blX6xKdm5o+3+gzXL/fbRZeo2oYQzHCa6CKxBBE5qhdNZo25nBWTwSN8kivymNnoUqXRZyleYCOYjxqp/cPODNO5LWO5R29nXcsSeQCmVOFtfggtizw/e28JcQoKqT4nTfbpwe2tIjZgTiKNDVKk7EfN9OMYSnAM5bgZWbBkw0wfzUwUPHTPvgXOGG4RSOcC9d5/ogIc09imq+wV+owM9Uap9yTvKl9t24YsdU6i9bvTEs56wZKgBaT/EnMOvdMPsRzJ6Eons1KFrqUvhhLAYKFs0rY1Ev8z8ZFveEf6/GhucWEkFqgCiEQ0u44NLpvhOu5UnpKng1TfXKyfgYXq1Tho7gFXIt6sm6m7yoPeqw7fYT7JhfWv/QUehSenBe8vQV3TfyXIU84dW4Y1ff+9VfjzjDIDDqj2LwvUxyHLdr1hOn6aNmfxFemc41eKVfWLx1mfUp76isH7+dqn9T0nwtUv1KxT7TxaaS7MDvu7vyw6FUtks81zlOrCMlHojNL2JK8DS/K7Jn/wA=
\ No newline at end of file
diff --git a/aws/cloudformation/ecs-zero-downtime-deployment/ecs-in-two-public-subnets.svg b/aws/cloudformation/ecs-zero-downtime-deployment/ecs-in-two-public-subnets.svg
new file mode 100644
index 0000000..e50e2c9
--- /dev/null
+++ b/aws/cloudformation/ecs-zero-downtime-deployment/ecs-in-two-public-subnets.svg
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/aws/cloudformation/ecs-zero-downtime-deployment/network.yml b/aws/cloudformation/ecs-zero-downtime-deployment/network.yml
new file mode 100644
index 0000000..32561ad
--- /dev/null
+++ b/aws/cloudformation/ecs-zero-downtime-deployment/network.yml
@@ -0,0 +1,247 @@
+AWSTemplateFormatVersion: '2010-09-09'
+Description: A network stack for deploying containers in AWS ECS.
+ This stack creates a VPC with two public subnets and a loadbalancer to balance traffic between those subnets.
+ Derived from a template at https://github.com/nathanpeck/aws-cloudformation-fargate.
+Resources:
+
+ VPC:
+ Type: AWS::EC2::VPC
+ Properties:
+ CidrBlock: '10.0.0.0/16'
+
+ PublicSubnetOne:
+ Type: AWS::EC2::Subnet
+ Properties:
+ AvailabilityZone:
+ Fn::Select:
+ - 0
+ - Fn::GetAZs: {Ref: 'AWS::Region'}
+ VpcId: !Ref 'VPC'
+ CidrBlock: '10.0.1.0/24'
+ MapPublicIpOnLaunch: true
+
+ PublicSubnetTwo:
+ Type: AWS::EC2::Subnet
+ Properties:
+ AvailabilityZone:
+ Fn::Select:
+ - 1
+ - Fn::GetAZs: {Ref: 'AWS::Region'}
+ VpcId: !Ref 'VPC'
+ CidrBlock: '10.0.2.0/24'
+ MapPublicIpOnLaunch: true
+
+ 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'
+
+ PublicSubnetOneRouteTableAssociation:
+ Type: AWS::EC2::SubnetRouteTableAssociation
+ Properties:
+ SubnetId: !Ref PublicSubnetOne
+ RouteTableId: !Ref PublicRouteTable
+
+ PublicSubnetTwoRouteTableAssociation:
+ Type: AWS::EC2::SubnetRouteTableAssociation
+ Properties:
+ SubnetId: !Ref PublicSubnetTwo
+ RouteTableId: !Ref PublicRouteTable
+
+ PublicRoute:
+ Type: AWS::EC2::Route
+ DependsOn: GatewayAttachement
+ Properties:
+ RouteTableId: !Ref 'PublicRouteTable'
+ DestinationCidrBlock: '0.0.0.0/0'
+ GatewayId: !Ref 'InternetGateway'
+
+ PublicLoadBalancerSecurityGroup:
+ Type: AWS::EC2::SecurityGroup
+ Properties:
+ GroupDescription: Access to the public facing load balancer
+ VpcId: !Ref 'VPC'
+ SecurityGroupIngress:
+ # Allow access to ALB from anywhere on the internet
+ - CidrIp: 0.0.0.0/0
+ IpProtocol: -1
+
+ PublicLoadBalancer:
+ Type: AWS::ElasticLoadBalancingV2::LoadBalancer
+ Properties:
+ Scheme: internet-facing
+ Subnets:
+ # The load balancer is placed into the public subnets, so that traffic
+ # from the internet can reach the load balancer directly via the internet gateway
+ - !Ref PublicSubnetOne
+ - !Ref PublicSubnetTwo
+ SecurityGroups: [!Ref 'PublicLoadBalancerSecurityGroup']
+
+ DummyTargetGroupPublic:
+ Type: AWS::ElasticLoadBalancingV2::TargetGroup
+ Properties:
+ HealthCheckIntervalSeconds: 6
+ HealthCheckPath: /
+ HealthCheckProtocol: HTTP
+ HealthCheckTimeoutSeconds: 5
+ HealthyThresholdCount: 2
+ Name: "no-op"
+ Port: 80
+ Protocol: HTTP
+ UnhealthyThresholdCount: 2
+ VpcId: !Ref 'VPC'
+
+ PublicLoadBalancerListener:
+ Type: AWS::ElasticLoadBalancingV2::Listener
+ DependsOn:
+ - PublicLoadBalancer
+ Properties:
+ DefaultActions:
+ - TargetGroupArn: !Ref 'DummyTargetGroupPublic'
+ Type: 'forward'
+ LoadBalancerArn: !Ref 'PublicLoadBalancer'
+ Port: 80
+ Protocol: HTTP
+
+ ECSCluster:
+ Type: AWS::ECS::Cluster
+
+ ECSSecurityGroup:
+ Type: AWS::EC2::SecurityGroup
+ Properties:
+ GroupDescription: Access to the ECS containers
+ VpcId: !Ref 'VPC'
+
+ ECSSecurityGroupIngressFromPublicALB:
+ Type: AWS::EC2::SecurityGroupIngress
+ Properties:
+ Description: Ingress from the public ALB
+ GroupId: !Ref 'ECSSecurityGroup'
+ IpProtocol: -1
+ SourceSecurityGroupId: !Ref 'PublicLoadBalancerSecurityGroup'
+
+ ECSSecurityGroupIngressFromSelf:
+ Type: AWS::EC2::SecurityGroupIngress
+ Properties:
+ Description: Ingress from other containers in the same security group
+ GroupId: !Ref 'ECSSecurityGroup'
+ IpProtocol: -1
+ SourceSecurityGroupId: !Ref 'ECSSecurityGroup'
+
+ 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: '*'
+
+ 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: '*'
+
+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' ] ]
+ ECSSecurityGroup:
+ Description: A security group used to allow ECS containers to receive traffic
+ Value: !Ref 'ECSSecurityGroup'
+ Export:
+ Name: !Join [ ':', [ !Ref 'AWS::StackName', 'ECSSecurityGroup' ] ]
\ No newline at end of file
diff --git a/aws/cloudformation/ecs-zero-downtime-deployment/service.yml b/aws/cloudformation/ecs-zero-downtime-deployment/service.yml
new file mode 100644
index 0000000..1357080
--- /dev/null
+++ b/aws/cloudformation/ecs-zero-downtime-deployment/service.yml
@@ -0,0 +1,139 @@
+AWSTemplateFormatVersion: '2010-09-09'
+Description: Deploy a service on AWS Fargate, hosted in two public subnets and accessible via a public load balancer.
+ Derived from a template at https://github.com/nathanpeck/aws-cloudformation-fargate.
+Parameters:
+ StackName:
+ Type: String
+ Description: The name of the networking stack that
+ these resources are put into.
+ ServiceName:
+ Type: String
+ Description: A human-readable name for the service.
+ HealthCheckPath:
+ Type: String
+ Default: /health
+ Description: Path to perform the healthcheck on each instance.
+ HealthCheckIntervalSeconds:
+ Type: Number
+ Default: 5
+ Description: Number of seconds to wait between each health check.
+ ImageUrl:
+ Type: String
+ Description: The url of a docker image that will handle incoming traffic.
+ ContainerPort:
+ Type: Number
+ Default: 80
+ Description: The port number the application inside the docker container
+ is binding to.
+ ContainerCpu:
+ Type: Number
+ Default: 256
+ Description: How much CPU to give the container. 1024 is 1 CPU.
+ ContainerMemory:
+ Type: Number
+ Default: 512
+ Description: How much memory in megabytes to give the container.
+ Path:
+ Type: String
+ Default: "*"
+ Description: A path on the public load balancer that this service
+ should be connected to.
+ DesiredCount:
+ Type: Number
+ Default: 2
+ Description: How many copies of the service task to run.
+
+Resources:
+
+ TargetGroup:
+ Type: AWS::ElasticLoadBalancingV2::TargetGroup
+ Properties:
+ HealthCheckIntervalSeconds: !Ref 'HealthCheckIntervalSeconds'
+ HealthCheckPath: !Ref 'HealthCheckPath'
+ HealthCheckProtocol: HTTP
+ HealthCheckTimeoutSeconds: 5
+ HealthyThresholdCount: 2
+ TargetType: ip
+ Name: !Ref 'ServiceName'
+ Port: !Ref 'ContainerPort'
+ Protocol: HTTP
+ UnhealthyThresholdCount: 2
+ VpcId:
+ Fn::ImportValue:
+ !Join [':', [!Ref 'StackName', 'VPCId']]
+
+ LoadBalancerRule:
+ Type: AWS::ElasticLoadBalancingV2::ListenerRule
+ Properties:
+ Actions:
+ - TargetGroupArn: !Ref 'TargetGroup'
+ Type: 'forward'
+ Conditions:
+ - Field: path-pattern
+ Values: [!Ref 'Path']
+ ListenerArn:
+ Fn::ImportValue:
+ !Join [':', [!Ref 'StackName', 'PublicListener']]
+ Priority: 1
+
+ LogGroup:
+ Type: AWS::Logs::LogGroup
+ Properties:
+ LogGroupName: !Ref 'ServiceName'
+ RetentionInDays: 1
+
+ TaskDefinition:
+ Type: AWS::ECS::TaskDefinition
+ Properties:
+ Family: !Ref 'ServiceName'
+ Cpu: !Ref 'ContainerCpu'
+ Memory: !Ref 'ContainerMemory'
+ NetworkMode: awsvpc
+ RequiresCompatibilities:
+ - FARGATE
+ ExecutionRoleArn:
+ Fn::ImportValue:
+ !Join [':', [!Ref 'StackName', 'ECSTaskExecutionRole']]
+ ContainerDefinitions:
+ - Name: !Ref 'ServiceName'
+ Cpu: !Ref 'ContainerCpu'
+ Memory: !Ref 'ContainerMemory'
+ Image: !Ref 'ImageUrl'
+ PortMappings:
+ - ContainerPort: !Ref 'ContainerPort' serve
+ LogConfiguration:
+ LogDriver: 'awslogs'
+ Options:
+ awslogs-group: !Ref 'ServiceName'
+ awslogs-region: !Ref AWS::Region
+ awslogs-stream-prefix: !Ref 'ServiceName'
+
+ Service:
+ Type: AWS::ECS::Service
+ DependsOn: LoadBalancerRule
+ Properties:
+ ServiceName: !Ref 'ServiceName'
+ Cluster:
+ Fn::ImportValue:
+ !Join [':', [!Ref 'StackName', 'ClusterName']]
+ LaunchType: FARGATE
+ DeploymentConfiguration:
+ MaximumPercent: 200
+ MinimumHealthyPercent: 50
+ DesiredCount: !Ref 'DesiredCount'
+ NetworkConfiguration:
+ AwsvpcConfiguration:
+ AssignPublicIp: ENABLED
+ SecurityGroups:
+ - Fn::ImportValue:
+ !Join [':', [!Ref 'StackName', 'ECSSecurityGroup']]
+ Subnets:
+ - Fn::ImportValue:
+ !Join [':', [!Ref 'StackName', 'PublicSubnetOne']]
+ - Fn::ImportValue:
+ !Join [':', [!Ref 'StackName', 'PublicSubnetTwo']]
+ TaskDefinition: !Ref 'TaskDefinition'
+ LoadBalancers:
+ - ContainerName: !Ref 'ServiceName'
+ ContainerPort: !Ref 'ContainerPort'
+ TargetGroupArn: !Ref 'TargetGroup'
diff --git a/aws/cloudformation/ecs-zero-downtime-deployment/task.yml b/aws/cloudformation/ecs-zero-downtime-deployment/task.yml
new file mode 100644
index 0000000..ccba239
--- /dev/null
+++ b/aws/cloudformation/ecs-zero-downtime-deployment/task.yml
@@ -0,0 +1,109 @@
+AWSTemplateFormatVersion: '2010-09-09'
+Description: Deploy a service on AWS Fargate, hosted in two public subnets and accessible via a public load balancer.
+ Derived from a template at https://github.com/nathanpeck/aws-cloudformation-fargate.
+Parameters:
+ StackName:
+ Type: String
+ Description: The name of the networking stack that
+ these resources are put into.
+ ServiceName:
+ Type: String
+ Description: A human-readable name for the service.
+ HealthCheckPath:
+ Type: String
+ Default: /health
+ Description: Path to perform the healthcheck on each instance.
+ HealthCheckIntervalSeconds:
+ Type: Number
+ Default: 5
+ Description: Number of seconds to wait between each health check.
+ ImageUrl:
+ Type: String
+ Description: The url of a docker image that will handle incoming traffic.
+ ContainerPort:
+ Type: Number
+ Default: 80
+ Description: The port number the application inside the docker container
+ is binding to.
+ ContainerCpu:
+ Type: Number
+ Default: 256
+ Description: How much CPU to give the container. 1024 is 1 CPU.
+ ContainerMemory:
+ Type: Number
+ Default: 512
+ Description: How much memory in megabytes to give the container.
+ Path:
+ Type: String
+ Default: "*"
+ Description: A path on the public load balancer that this service
+ should be connected to.
+ DesiredCount:
+ Type: Number
+ Default: 2
+ Description: How many copies of the service task to run.
+
+Resources:
+
+ TargetGroup:
+ Type: AWS::ElasticLoadBalancingV2::TargetGroup
+ Properties:
+ HealthCheckIntervalSeconds: !Ref 'HealthCheckIntervalSeconds'
+ HealthCheckPath: !Ref 'HealthCheckPath'
+ HealthCheckProtocol: HTTP
+ HealthCheckTimeoutSeconds: 5
+ HealthyThresholdCount: 2
+ TargetType: ip
+ Name: !Ref 'ServiceName'
+ Port: !Ref 'ContainerPort'
+ Protocol: HTTP
+ UnhealthyThresholdCount: 2
+ VpcId:
+ Fn::ImportValue:
+ !Join [':', [!Ref 'StackName', 'VPCId']]
+
+ LoadBalancerRule:
+ Type: AWS::ElasticLoadBalancingV2::ListenerRule
+ Properties:
+ Actions:
+ - TargetGroupArn: !Ref 'TargetGroup'
+ Type: 'forward'
+ Conditions:
+ - Field: path-pattern
+ Values: [!Ref 'Path']
+ ListenerArn:
+ Fn::ImportValue:
+ !Join [':', [!Ref 'StackName', 'PublicListener']]
+ Priority: 1
+
+ LogGroup:
+ Type: AWS::Logs::LogGroup
+ Properties:
+ LogGroupName: !Ref 'ServiceName'
+ RetentionInDays: 1
+
+ TaskDefinition:
+ Type: AWS::ECS::TaskDefinition
+ Properties:
+ Family: !Ref 'ServiceName'
+ Cpu: !Ref 'ContainerCpu'
+ Memory: !Ref 'ContainerMemory'
+ NetworkMode: awsvpc
+ RequiresCompatibilities:
+ - FARGATE
+ ExecutionRoleArn:
+ Fn::ImportValue:
+ !Join [':', [!Ref 'StackName', 'ECSTaskExecutionRole']]
+ ContainerDefinitions:
+ - Name: !Ref 'ServiceName'
+ Cpu: !Ref 'ContainerCpu'
+ Memory: !Ref 'ContainerMemory'
+ Image: !Ref 'ImageUrl'
+ PortMappings:
+ - ContainerPort: !Ref 'ContainerPort'
+ LogConfiguration:
+ LogDriver: 'awslogs'
+ Options:
+ awslogs-group: !Ref 'ServiceName'
+ awslogs-region: !Ref AWS::Region
+ awslogs-stream-prefix: !Ref 'ServiceName'
\ No newline at end of file
diff --git a/junit/assumptions/gradlew b/junit/assumptions/gradlew
old mode 100644
new mode 100755
diff --git a/reactive/gradlew b/reactive/gradlew
old mode 100644
new mode 100755
diff --git a/solid/gradlew b/solid/gradlew
old mode 100644
new mode 100755
diff --git a/spring-boot/argumentresolver/gradlew b/spring-boot/argumentresolver/gradlew
old mode 100644
new mode 100755
diff --git a/spring-boot/boundaries/gradlew b/spring-boot/boundaries/gradlew
old mode 100644
new mode 100755
diff --git a/spring-boot/cache/gradle/wrapper/gradle-wrapper.properties b/spring-boot/cache/gradle/wrapper/gradle-wrapper.properties
index 8a46ded..a004df5 100644
--- a/spring-boot/cache/gradle/wrapper/gradle-wrapper.properties
+++ b/spring-boot/cache/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,5 @@
#Mon Jun 15 21:48:44 CEST 2020
-distributionUrl=https\://services.gradle.org/distributions/gradle-6.4.1-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
diff --git a/spring-boot/data-migration/liquibase/mvnw b/spring-boot/data-migration/liquibase/mvnw
old mode 100644
new mode 100755
diff --git a/spring-boot/spring-boot-openapi/mvnw b/spring-boot/spring-boot-openapi/mvnw
old mode 100644
new mode 100755
diff --git a/spring-boot/thymeleaf-vue/client/package.json b/spring-boot/thymeleaf-vue/client/package.json
index 32f0dd2..51345a3 100644
--- a/spring-boot/thymeleaf-vue/client/package.json
+++ b/spring-boot/thymeleaf-vue/client/package.json
@@ -11,9 +11,9 @@
"test": "vue-cli-service test:unit"
},
"dependencies": {
+ "chart.js": "^2.9.3",
"core-js": "^3.6.5",
- "vue": "^2.6.11",
- "chart.js": "^2.9.3"
+ "vue": "^2.6.11"
},
"devDependencies": {
"@babel/core": "^7.10.2",
@@ -23,15 +23,15 @@
"@storybook/vue": "^5.3.19",
"@vue/cli-plugin-babel": "~4.4.0",
"@vue/cli-plugin-eslint": "~4.4.0",
- "@vue/cli-service": "~4.4.0",
"@vue/cli-plugin-unit-jest": "^4.4.0",
+ "@vue/cli-service": "~4.4.0",
"@vue/test-utils": "^1.0.3",
- "jest-canvas-mock": "^2.2.0",
"babel-eslint": "^10.1.0",
"babel-loader": "^8.1.0",
"babel-preset-vue": "^2.0.2",
"eslint": "^6.7.2",
"eslint-plugin-vue": "^6.2.2",
+ "jest-canvas-mock": "^2.2.0",
"vue-template-compiler": "^2.6.11"
},
"eslintConfig": {
diff --git a/spring-data/spring-data-jdbc-converter/gradlew b/spring-data/spring-data-jdbc-converter/gradlew
old mode 100644
new mode 100755