Built.io Blog

Stop/Start Functionality for Non-production AWS Instances Using AWS Command Line Interface

,

Note: To get the most out of this blog post, you should be familiar with the basic concepts of AWS Command Line Interface and Identity and Access Management.

For many companies, cloud costs can be a concern. In order to control costs, managers will request that environments be stopped when not in use. In order to do this in non-production environments, you can use AWS Command Line Interface to start and stop these and AWS instance.

Most of the time non-production instances in Amazon Web Services can remain in a stopped state while the cloud management team is offline in order to control infrastructure costs. It makes sense to automate this activity because it needs to be carried out every day. This automated stop-start of AWS instances can be achieved effectively through AWS Command Line Interface with the necessary access restrictions in place on AWS resources using Identity and Access Management policies.

Before we begin, in order to make use of automated stop-start, you should set up your instance with all the required upstart configurations such that your application or services running on that instance come up after an instance reboot.

Let’s consider the different types of applications, with respect to AWS infrastructure:

  • Without Elastic Load Balancer (ELB): the application has single or multiple instances.
  • ELB without autoscaling: the application has instance(s) behind ELB.
  • ELB with autoscaling: the application has a pool of instances controlled through Auto-Scaling Group (ASG).

This post will demonstrate how AWS Command Line Interface can be used for applications of these three types and their associated Identity and Access Management policies. All Identity and Access Management policies will have EC2-read only access in common. The keys generated for IAM user which has these IAM policies associated, would be used to configure aws-cli.

Without Elastic Load Balancer

Command Line Interface Commands

These applications may have single or multiple instances. To stop/start instance following command is executed:

aws ec2 stop-instances --instance-ids i-1a2b3c4d
aws ec2 start-instances --instance-ids i-1a2b3c4d

In place of instance-id multiple IDs can be passed. A huge disadvantage if we use this command directly is that we would need to hard-code the instance-ids in our scripts. This approach certainly needs to be changed. As a solution, we can use the above command in combination with following command:

aws ec2 describe-instances --filters "Name=tag:Name,Values=Test: Instance 1" --query 'Reservations[].Instances[].[InstanceId]

The filter applied is: Name=”Test: Instance 1”. This filter can be modified per your use-case, for example: the tag could be Environment and value could be Staging. So, it could be written as: --filters "Name=tag:Environment,Values=Staging".

The describe-instances command will return the required instance-ids and those can be passed on as arguments to stop-instances or start-instances command.

Identity and Access Management Policy

In this Identity and Access Management policy, we will restrict the stop/start action as follows:

{
    "Version": "2012-10-17",
    "Statement": [
    {
        "Sid": "Stmt1412598595000",
        "Effect": "Allow",
        "Action": [
        "ec2:StartInstances",
        "ec2:StopInstances"
                    ],
        "Resource": [
        "arn:aws:ec2:us-east-1:123456789012:instance/i-1a2b3c4d",
        "arn:aws:ec2:us-east-1:123456789012:instance/i-12ab34cd"
                    ]
    }
                    ]
}

This way, we can ensure the AWS Command Line Interface onlys has access to stop/start the instances we want. For resource specifications, Amazon Resource Names (ARN) are used.

Elastic Load Balancer without Autoscaling

CLI Commands

Instances behind ELB (without autoscaling) can be stopped/started using the method specified in step one. However, when instances behind ELB are started, it takes some time to have that instance "in service". The following command will help in getting the instance in service in ELB quickly:

aws elb deregister-instances-from-load-balancer --load-balancer-name elb-name --instances i-12ab34cd
aws elb register-instances-from-load-balancer --load-balancer-name elb-name --instances i-12ab34cd

Identity and Access Management Policy

In this Identity and Access Management policy, we will restrict access to a specific ELB for the required actions:

{
    "Version": "2012-10-17",
    "Statement": [
    {
        "Sid": "Stmt1412674402000",
        "Effect": "Allow",
        "Action": [
        "elasticloadbalancing:DeregisterInstancesFromLoadBalancer",
        "elasticloadbalancing:RegisterInstancesWithLoadBalancer"
                    ],
        "Resource": [                       
        "arn:aws:elasticloadbalancing:us-east-1:123456789012:loadbalancer/load-balancer-name"
                    ]
    }
                    ]
}

where, load-balancer-name - ELB name.

Elastic Load Balancer with Autoscaling

CLI Commands

If multiple instances behind ELB are controlled from an Auto-Scaling Group (ASG), then we do not need to stop/start specific instance(s). We can update ASG as follows:

aws autoscaling update-auto-scaling-group --auto-scaling-group-name "asg-name"  --launch-configuration-name "launch-config-name" --min-size 0 --max-size 0
aws autoscaling update-auto-scaling-group --auto-scaling-group-name "asg-name"  --launch-configuration-name "launch-config-name" --min-size 1 --max-size 1

where,

asg-name - auto-scaling group name
launch-config-name - launch configuration name associated with auto-scaling group
    min-size - minimum number of instances should be present behind ELB
    max-size - maximum number of instances should be present behind ELB

Identity and Access Management Policy

Unfortunately, for auto-scaling resource-level permission does not exist. That means, we cannot restrict the IAM user to a specific auto-scaling group. Maximum possible restriction is as follows:

{
    "Version": "2012-10-17",
    "Statement": [
    {
        "Sid": "Stmt1417434656000",
        "Effect": "Allow",
        "Action": [
        "autoscaling:DescribeAutoScalingGroups",
        "autoscaling:UpdateAutoScalingGroup"
                    ],
        "Resource": [
        "*"
                    ]
    }
                    ]
}

Using the above combinations, it's possible to automate stop/start of simple or complex environments on whenever needed, and to optimize infrastructure costs by doing so. If you have any questions, please leave them in the comments.

Subscribe to our blog