-
Notifications
You must be signed in to change notification settings - Fork 1
aws sysops 05 cli ec2 elb
CLI Reference: ELB v2
CLI Reference: Auto Scaling
CLI Reference: Amazon CloudWatch
In order to operate an Elastic Load Balancer (ELB), we need:
- 1 VPC
- 1 Internet Gateway
- 2 Subnets in different Availability Zones (AZ)
- 1 Routing Table with a default route to the Internet Gateway
- 1 Security Group in the VPC allowing traffic on port 22 (SSH)
- 2 EC2 instances
- 1 in each Subnet
- 1 public IP per subnet
Let's create them first if required.
$ aws ec2 create-vpc --cidr-block 128.0.0.0/16
# "VpcId": "vpc-77aa341f",
$ aws ec2 create-internet-gateway
# "InternetGatewayId": "igw-6e091f07"
$ aws ec2 attach-internet-gateway --vpc-id vpc-77aa341f --internet-gateway-id igw-54988f3d
$ aws ec2 create-subnet --vpc-id vpc-77aa341f \
--availability-zone eu-central-1a \
--cidr-block 128.0.0.0/24
# "SubnetId": "subnet-7ea0fb16",
$ aws ec2 create-subnet --vpc-id vpc-77aa341f \
--availability-zone eu-central-1b \
--cidr-block 128.0.1.0/24
# "SubnetId": "subnet-90fe98ea"
$ aws ec2 create-route-table --vpc-id vpc-77aa341f
# "RouteTableId": "rtb-e0f1a588"
$ aws ec2 create-route --route-table-id rtb-e0f1a588 \
--destination-cidr-block 0.0.0.0/0 --gateway-id igw-6e091f07
$ aws ec2 create-security-group --group-name LoadBalancing --vpc-id vpc-77aa341f \
--description "Security group for application Load Balancing"
# "GroupId": "sg-11f2787a"
$ aws ec2 authorize-security-group-ingress --group-id sg-11f2787a --protocol tcp --port 22 --cidr 0.0.0.0/0
$ aws ec2 run-instances --image-id ami-060cde69 --count 1 \
--instance-type t2.micro --key-name sysops --security-group-ids sg-11f2787a \
--subnet-id subnet-7ea0fb16
# "InstanceId": "i-05a3fe7a54affda6f"
$ aws ec2 run-instances --image-id ami-060cde69 --count 1 \
--instance-type t2.micro --key-name sysops --security-group-ids sg-11f2787a \
--subnet-id subnet-90fe98ea
# "InstanceId": "i-08889a65ce7e0e7ce"
CLI Reference: create-load-balancer
CLI Reference: create-target-group
CLI Reference: create-listener
CLI Reference: register-targets
We use the create-load-balancer
to create an ELB:
NOTE:
- Mind the elbv2, otherwise you'd create a classic ELB instead of an application ELB.
$ aws elbv2 create-load-balancer --name myLoadBalancer \
--subnets subnet-7ea0fb16 subnet-90fe98ea --security-groups sg-11f2787a
{
"LoadBalancers": [
{
"IpAddressType": "ipv4",
"VpcId": "vpc-77aa341f",
"LoadBalancerArn": "arn:aws:elasticloadbalancing:eu-central-1:832922743754:loadbalancer/app/myLoadBalancer/6b10d007807ede6f",
"State": {
"Code": "provisioning"
},
"DNSName": "myLoadBalancer-571877962.eu-central-1.elb.amazonaws.com",
"SecurityGroups": [
"sg-11f2787a"
],
"LoadBalancerName": "myLoadBalancer",
"CreatedTime": "2017-05-13T13:42:55.200Z",
"Scheme": "internet-facing",
"Type": "application",
"CanonicalHostedZoneId": "Z215JYRZR1TBD5",
"AvailabilityZones": [
{
"SubnetId": "subnet-7ea0fb16",
"ZoneName": "eu-central-1a"
},
{
"SubnetId": "subnet-90fe98ea",
"ZoneName": "eu-central-1b"
}
]
}
]
}
Note the Amazon Resource Name (ARN) of the load balancer:
LoadBalancerArn`: `arn:aws:elasticloadbalancing:eu-central-1:832922743754:loadbalancer/app/myLoadBalancer/6b10d007807ede6f
Note the DNS of the Load Balander: "DNSName": "myLoadBalancer-571877962.eu-central-1.elb.amazonaws.com"
Next, we use the create-target-group
command to create target group:
$ aws elbv2 create-target-group --name targetInstances --protocol HTTP --port 80 \
--vpc-id vpc-77aa341f
{
"TargetGroups": [
{
"HealthCheckPath": "/",
"HealthCheckIntervalSeconds": 30,
"VpcId": "vpc-77aa341f",
"Protocol": "HTTP",
"HealthCheckTimeoutSeconds": 5,
"HealthCheckProtocol": "HTTP",
"UnhealthyThresholdCount": 2,
"HealthyThresholdCount": 5,
"TargetGroupArn": "arn:aws:elasticloadbalancing:eu-central-1:832922743754:targetgroup/targetInstances/611964f09d978756",
"Matcher": {
"HttpCode": "200"
},
"HealthCheckPort": "traffic-port",
"Port": 80,
"TargetGroupName": "targetInstances"
}
]
}
Note the ARN of the target group:
TargetGroupArn`: `arn:aws:elasticloadbalancing:eu-central-1:832922743754:targetgroup/targetInstances/611964f09d978756
Next, we Use the create-listener
command to create a listener for the load balancer with a default rule that forwards requests to your target group:
$ aws elbv2 create-listener \
--load-balancer-arn arn:aws:elasticloadbalancing:eu-central-1:832922743754:loadbalancer/app/myLoadBalancer/6b10d007807ede6f \
--protocol HTTP --port 80 \
--default-actions Type=forward,TargetGroupArn=arn:aws:elasticloadbalancing:eu-central-1:832922743754:targetgroup/targetInstances/611964f09d978756
{
"Listeners": [
{
"Protocol": "HTTP",
"DefaultActions": [
{
"TargetGroupArn": "arn:aws:elasticloadbalancing:eu-central-1:832922743754:targetgroup/targetInstances/611964f09d978756",
"Type": "forward"
}
],
"LoadBalancerArn": "arn:aws:elasticloadbalancing:eu-central-1:832922743754:loadbalancer/app/myLoadBalancer/6b10d007807ede6f",
"Port": 80,
"ListenerArn": "arn:aws:elasticloadbalancing:eu-central-1:832922743754:listener/app/myLoadBalancer/6b10d007807ede6f/e79db64400204ed4"
}
]
}
At that stage we need to make sure the Load Balancer can receive traffic on port 80.
If not done already, add a rule to the Security Group to allow HTTP traffic from anywhere:
$ aws ec2 authorize-security-group-ingress --group-id sg-11f2787a \
--protocol tcp --port 80 --cidr 0.0.0.0/0
Finally we register instances with the target group with the register-targets
command:
$ aws elbv2 register-targets \
--target-group-arn arn:aws:elasticloadbalancing:eu-central-1:832922743754:targetgroup/targetInstances/611964f09d978756 \
--targets Id=i-05a3fe7a54affda6f,Port=3001 Id=i-08889a65ce7e0e7ce,Port=3001
# The command does nos return anything
NOTE:
- use the
deregister-targets
command with the same signature asregister-targets
to deregister a target from a Target Group
aws elbv2 deregister-targets \
--target-group-arn arn:aws:elasticloadbalancing:eu-central-1:832922743754:targetgroup/targetInstances/611964f09d978756 \
--targets Id=i-05a3fe7a54affda6f,Port=3001
Optionally, verify the health of the registered targets for your target group using this describe-target-health
command:
$ aws elbv2 describe-target-health \
--target-group-arn arn:aws:elasticloadbalancing:eu-central-1:832922743754:targetgroup/targetInstances/611964f09d978756
{
"TargetHealthDescriptions": [
{
"Target": {
"Id": "i-08889a65ce7e0e7ce",
"Port": 3001
},
"TargetHealth": {
"State": "initial",
"Reason": "Elb.RegistrationInProgress",
"Description": "Target registration is in progress"
}
},
{
"Target": {
"Id": "i-05a3fe7a54affda6f",
"Port": 3001
},
"TargetHealth": {
"State": "initial",
"Reason": "Elb.RegistrationInProgress",
"Description": "Target registration is in progress"
}
}
]
}
NOTE:
- "Target registration is in progress" means that the no target is considered by healthy by the Load Balancer: no instance is currently able to handle traffic on port 3001, we need to fix this by
- setting-up a server on instances to handle traffic on port 3001
- tune the Target Group health check to target port 3001
We will use Docker on intances to set up a simple http server configured to handle traffic on port 3001
First install Docker. You can follow this tutorial.
Then, have docker fetch and launch the crccheck/hello-world
image from Docher Hub:
$ sudo docker run -d --name web-test -p 3001:8000 crccheck/hello-world
NOTE:
- The
-p 3001:8000
parameter tells the Docker image to listen on port 3001 and redirect internally traffic to port 8000 on which is locally running the http server
Let's pay attention to the content of the Dockerfile:
# Boostrap from a busybox Liux distribution
FROM busybox
# Add local file index.html as /index.html
ADD index.html /index.html
# Listen on port 8000
EXPOSE 8000
# A shell-powered web server using nc (netcat)
# http://www.busybox.net/downloads/BusyBox.html#nc
CMD while true ; do nc -l -p 8000 < /index.html ; done
CLI Reference: modify-target-group
$ aws elbv2 modify-target-group \
--target-group-arn arn:aws:elasticloadbalancing:eu-central-1:832922743754:targetgroup/targetInstances/611964f09d978756 \
--health-check-protocol HTTP --health-check-port 3001
Now check our service is available on the our Load Balander DNS:
http://myLoadBalancer-571877962.eu-central-1.elb.amazonaws.com
Did it work? "Et Voila !" 🙌
The create-rules
can be used to create regex-matching load balancing routing rules on host name or url path.
The following example creates a rule that forwards requests to the specified target group if the URL contains the specified pattern (for example, /img/*):
$ aws elbv2 create-rule \
--listener-arn arn:aws:elasticloadbalancing:eu-central-1:832922743754:loadbalancer/app/myLoadBalancer/6b10d007807ede6f \
--priority 10 \
--conditions Field=path-pattern,Values='/img/*' \
--actions Type=forward,TargetGroupArn=arn:aws:elasticloadbalancing:eu-central-1:832922743754:targetgroup/targetInstances/611964f09d978756
NOTE:
-
--priority
: as one can expect represents the order in which the rule is parsed, the lower the greater -
--conditions
's syntax isField=string,Values=string,string ...
-
Field
value can be-
host-header
for rules on host name (my.example.com) -
path-pattern
for rules on the url path (/static/img/...)
-
-
CLI Reference: create-launch-configuration
We use the create-launch-configuration
command to create a Launch Configuration
$ aws autoscaling create-launch-configuration --launch-configuration-name myWebServerTemplate \
--image-id ami-cbdd04a4 --instance-type t2.micro \
--security-groups sg-11f2787a
# The command does not return anything
Inspect the created Auto Scaling Group using the describe-launch-configurations
command:
$ aws autoscaling describe-launch-configurations --launch-configuration-name myWebServerTemplate
{
"LaunchConfigurations": [
{
"UserData": "",
"EbsOptimized": false,
"LaunchConfigurationARN": "arn:aws:autoscaling:eu-central-1:832922743754:launchConfiguration:f1d47441-89a2-419f-be12-7c9e7eef7014:launchConfigurationName/myWebServerTemplate",
"InstanceMonitoring": {
"Enabled": true
},
"ClassicLinkVPCSecurityGroups": [],
"CreatedTime": "2017-05-14T09:14:47.120Z",
"BlockDeviceMappings": [],
"KeyName": "",
"SecurityGroups": [
"sg-11f2787a"
],
"LaunchConfigurationName": "myWebServerTemplate",
"KernelId": "",
"RamdiskId": "",
"ImageId": "ami-cbdd04a4",
"InstanceType": "t2.micro"
}
]
}
CLI Reference: create-auto-scaling-group
Now, create an Auto Scaling Group to automatize the launch of instances matching the Launch Configuration we just created:
$ aws autoscaling create-auto-scaling-group --auto-scaling-group-name myAutoScalingGroup \
--launch-configuration-name myWebServerTemplate \
--vpc-zone-identifier "subnet-7ea0fb16" \
--vpc-zone-identifier "subnet-90fe98ea" \
--max-size 5 --min-size 1 --desired-capacity 2
# The command does not return anything
Inspect the created Auto Scaling Group using the describe-launch-configurations
command:
$ aws autoscaling describe-auto-scaling-groups --auto-scaling-group-name myAutoScalingGroup
{
"AutoScalingGroups": [
{
"AutoScalingGroupARN": "arn:aws:autoscaling:eu-central-1:832922743754:autoScalingGroup:c9ef1262-fe70-4fcb-a50b-580894936dec:autoScalingGroupName/myAutoScalingGroup",
"TargetGroupARNs": [],
"SuspendedProcesses": [],
"DesiredCapacity": 2,
"Tags": [],
"EnabledMetrics": [],
"LoadBalancerNames": [],
"AutoScalingGroupName": "myAutoScalingGroup",
"DefaultCooldown": 300,
"MinSize": 1,
"Instances": [
{
"ProtectedFromScaleIn": false,
"AvailabilityZone": "eu-central-1b",
"InstanceId": "i-02b7c30abd3395bc1",
"HealthStatus": "Healthy",
"LifecycleState": "Pending",
"LaunchConfigurationName": "myWebServerTemplate"
},
{
"ProtectedFromScaleIn": false,
"AvailabilityZone": "eu-central-1b",
"InstanceId": "i-08e012c42760fd01b",
"HealthStatus": "Healthy",
"LifecycleState": "Pending",
"LaunchConfigurationName": "myWebServerTemplate"
}
],
"MaxSize": 5,
"VPCZoneIdentifier": "subnet-90fe98ea",
"HealthCheckGracePeriod": 0,
"TerminationPolicies": [
"Default"
],
"LaunchConfigurationName": "myWebServerTemplate",
"CreatedTime": "2017-05-14T09:16:55.264Z",
"AvailabilityZones": [
"eu-central-1b"
],
"HealthCheckType": "EC2",
"NewInstancesProtectedFromScaleIn": false
}
]
}
NOTE:
- As you can see 2 new instances are being created just as specified in the Auto Scaling Group configuration (
--desired-capacity 2
).
CLI Reference: create-auto-scaling-group
To make things clean, let's create a new Load Balancer rather than reusing the one from the beginning of the lesson.
$ aws elbv2 create-load-balancer --name myOtherLoadBalancer \
--subnets subnet-7ea0fb16 subnet-90fe98ea --security-groups sg-11f2787a
# "LoadBalancerArn": "arn:aws:elasticloadbalancing:eu-central-1:832922743754:loadbalancer/app/myOtherLoadBalancer/ade199a586a5c0a1"
$ aws elbv2 create-target-group --name autoScaledInstances --protocol HTTP --port 3001 \
--vpc-id vpc-77aa341f
# "TargetGroupArn": "arn:aws:elasticloadbalancing:eu-central-1:832922743754:targetgroup/autoScaledInstances/475b305ae810e515"
$ aws elbv2 create-listener \
--load-balancer-arn arn:aws:elasticloadbalancing:eu-central-1:832922743754:loadbalancer/app/myOtherLoadBalancer/ade199a586a5c0a1 \
--protocol HTTP --port 80 \
--default-actions Type=forward,TargetGroupArn=arn:aws:elasticloadbalancing:eu-central-1:832922743754:targetgroup/autoScaledInstances/475b305ae810e515
NOTE:
- When creating the Load Balancer's Target Group we specified the port on which instances receive traffic with paramater
--port
.
Next, attach the Auto Scaling Group to the Load Balancer's Target Group.
$ aws autoscaling attach-load-balancer-target-groups \
--auto-scaling-group-name myAutoScalingGroup \
--target-group-arns arn:aws:elasticloadbalancing:eu-central-1:832922743754:targetgroup/autoScaledInstances/475b305ae810e515
Inspect the Auto Scaling Group using the describe-launch-configurations
command, the TargetGroupARNs
should now be filled with our Load Balancer's Target Group ARN:
"TargetGroupARNs": [
"arn:aws:elasticloadbalancing:eu-central-1:832922743754:targetgroup/autoScaledInstances/475b305ae810e515"
],
NOTE:
- we could also have attached a Load Balancer right away to an Auto Scaling Group at creation time using the
--target-group-arns
parameter:
--target-group-arns "arn:aws:elasticloadbalancing:eu-central-1:832922743754:targetgroup/autoScaledInstances/475b305ae810e515"
CLI Reference: put-scheduled-update-group-action
You can specify a recurrence schedule, in UTC, using the Cron format with the put-scheduled-update-group-action
command.
- See also Crontab.guru.
$ aws autoscaling put-scheduled-update-group-action \
--scheduled-action-name scaleInAtNight --auto-scaling-group-name myAutoScalingGroup --recurrence "0 2 * * *" --desired-capacity 1
# every night at 02:00
CLI Reference: put-scaling-policy
Use the put-scaling-policy
command to create a scaling policy with an adjustment type ChangeInCapacity
that increases the capacity of the group by 1 instance:
We also specify warmup
and cooldown
values of 30 seconds:
-
--estimated-instance-warmup
defines the time, in seconds, until a newly launched instance can contribute to the CloudWatch metrics -
--cooldown
defines the time, in seconds, after a scaling activity completes and before the next scaling activity can start.
$ aws autoscaling put-scaling-policy --policy-name myScaleoutPolicy \
--auto-scaling-group-name myAutoScalingGroup \
--adjustment-type ChangeInCapacity \
--scaling-adjustment 1
--estimated-instance-warmup 30
--cooldown 30
--
{
"PolicyARN": "arn:aws:autoscaling:us-west-2:123456789012:scalingPolicy:ac542982-cbeb-4294-891c-a5a941dfa787:autoScalingGroupName/myAutoScalingGroup:policyName/myScaleoutPolicy"
}
Use once more the put-scaling-policy
command to create a scaling policy with an adjustment type ChangeInCapacity
that decreases the capacity of the group by 2 instances:
$ aws autoscaling put-scaling-policy --policy-name myScaleinPolicy \
--auto-scaling-group-name myAutoScalingGroup \
--adjustment-type ChangeInCapacity \
--scaling-adjustment -2
--estimated-instance-warmup 30
--cooldown 30
{
"PolicyARN": "arn:aws:autoscaling:us-west-2:123456789012:scalingPolicy:4ee9e543-86b5-4121-b53b-aa4c23b5bbcc:autoScalingGroupName/myAutoScalingGroup:policyName/myScaleinPolicy"
}
CLI Reference: put-metric-alarm
We just created Scaling Policies* that provided instructions to the Auto Scaling Group about how to scale out and scale in when the conditions that you specify change.
In this step, we create Actions triggerd on Alarms* by
- identifying the metrics to watch
- defining the conditions for scaling
- associating the alarms with the scaling policies
Use the CloudWatch put-metric-alarm
command to create an alarm that increases the size of the Auto Scaling Group when the value of the CPUUtilization
metric breaches over 60
.
$ aws cloudwatch put-metric-alarm --alarm-name AddCapacity \
--metric-name CPUUtilization --namespace AWS/EC2 \
--comparison-operator GreaterThanOrEqualToThreshold \
--statistic Average --period 60 --threshold 60 \
--dimensions "Name=AutoScalingGroupName,Value=myAutoScalingGroup" \
--evaluation-periods 2 \
--alarm-actions "arn:aws:autoscaling:us-west-2:123456789012:scalingPolicy:ac542982-cbeb-4294-891c-a5a941dfa787:autoScalingGroupName/myAutoScalingGroup:policyName/myScaleoutPolicy"
# Scale-out Policy ARN
Note:
- The
--dimensions
parameter allows defining the range of resources over which the metric is computed. For example a single instance, a whole Auto Scaling Group, all instances of a given type or image.- CloudWatch Metrics and Dimensions Reference
- You can list available metrics per namespaces and dimensions using the
list-metrics
command for example:aws cloudwatch list-metrics --namespace AWS/EC2
-
--evaluation-periods
defines the consecutive number of periods the metric has to breach the threshold to trigger the action
Use again the CloudWatch put-metric-alarm
command to create an alarm that decreases the size of the Auto Scaling Group when the value of the CPUUtilization
metric breaches under 30
.
$ aws cloudwatch put-metric-alarm --alarm-name RemoveCapacity \
--metric-name CPUUtilization --namespace AWS/EC2 \
--comparison-operator LessThanOrEqualToThreshold \
--statistic Average --period 60 --threshold 30
--dimensions "Name=AutoScalingGroupName,Value=myAutoScalingGroup" \
--evaluation-periods 2 --alarm-actions "arn:aws:autoscaling:us-west-2:123456789012:scalingPolicy:4ee9e543-86b5-4121-b53b-aa4c23b5bbcc:autoScalingGroupName/myAutoScalingGroup:policyName/myScaleinPolicy"
# Scale-in Policy ARN
CLI Reference: describe-scaling-activities
$ aws autoscaling describe-scaling-activities --auto-scaling-group-name myAutoScalingGroup
# Returns activites for a given Auto Scaling Group
$ aws autoscaling describe-scaling-activities --max-items 5
# Returns a specific number of activities
$ aws autoscaling describe-scaling-activities --activity-ids 980bbf70-465c-43c0-ad4c-a2a1d92ebc98
# Returns specific(s) activities
{
"Activities": [
{
"Description": "Launching a new EC2 instance: i-08e012c42760fd01b",
"AutoScalingGroupName": "myAutoScalingGroup",
"ActivityId": "980bbf70-465c-43c0-ad4c-a2a1d92ebc98",
"Details": "{\"Subnet ID\":\"subnet-7ea0fb16\",\"Availability Zone\":\"eu-central-1b\"}",
"StartTime": "2017-05-14T09:16:59.007Z",
"Progress": 100,
"EndTime": "2017-05-14T09:17:31Z",
"Cause": "At 2017-05-14T09:16:55Z a user request created an AutoScalingGroup changing the desired capacity from 0 to 2. At 2017-05-14T09:16:57Z an instance was started in response to a difference between desired and actual capacity, increasing the capacity from 0 to 2.",
"StatusCode": "Successful"
},
]
}
CLI Reference: delete-auto-scaling-group
If the group has instances or scaling activities in progress, you must specify the option to force the deletion in order for it to succeed (--force-delete
).
To remove instances from the Auto Scaling group before deleting it, call detach-instances
with the list of instances and the option to decrement the desired capacity so that Auto Scaling does not launch replacement instances.
To terminate all instances before deleting the Auto Scaling group, call update-auto-scaling-group
and set the minimum size and desired capacity of the Auto Scaling group to zero.
$ aws autoscaling update-auto-scaling-group --auto-scaling-group-name myAutoScalingGroup --min-size 0
$ aws autoscaling update-auto-scaling-group --auto-scaling-group-name myAutoScalingGroup --desired-capacity 0
$ aws autoscaling delete-auto-scaling-group --auto-scaling-group-name myAutoScalingGroup
$ aws autoscaling delete-launch-configuration --launch-configuration-name myWebServerTemplate
- AWS CLI
- CLI tutorials