Many enterprises know that turning off unused AWS instances can save money. But not all IT pros know which method...
is best and how to set it up.
There are a few ways to turn off unused Amazon Web Services (AWS) Elastic Compute Cloud (EC2) instances. If you don't use Auto Scaling, you will need to configure this process manually. One method is to use command-line interface (CLI) tools ec2-start-instances and ec2-stop-instances on Linux, using either a role-based method or an identity access management user-credential method.
Setting up role-based security enables you to associate AWS identity and access management (IAM) roles with the instance, without having to manually add plain-text security credentials. This not only improves security, but is easier to manage. Identify an instance that will perform CLI start and stop scripts, or create a dedicated micro-instance to perform these maintenance tasks.
IAM roles cannot be embedded in instances that have been created; they must be defined during the setup phase. This tip walks you through the instance configuration process needed to run CLI commands based on IAM roles.
Setting up role-based security on an EC2 instance
- From the AWS Management Console, click IAM -- Secure AWS Access Control and then Roles and then select Create a New Role.
- Enter ec2-privs-for-cron (or any unique name you choose) and click Next Step.
- Hit Select, which is found next to the Amazon EC2 - Allows EC2 instances to call AWS services on your behalf role description. Select the Next Step button.
- Click on Policy Generator and hit Select next to the Use the policy generator to create your own set of permissions text.
In the policy generator interface, check that Allow is selected and choose Amazon EC2 from the Amazon Service dropdown list. Then click Actions and StartInstances, followed by StopInstances. Enter an Amazon Resource Name (ARN): arn:aws:ec2:*:*:*", and click Next Step.
This will bring you to a screen showing the new policy as:
Review the Role Name, Role ARN and the Trusted Entities, and click Create Role and then Done. You can now attach the new role, which is called "ec2-privs-for-cron," to a new EC2.
Next, spin up new EC2 instance. To do so, launch a new Amazon Machine Instance (AMI), which comes preinstalled with the AWS CLI tools. For this scenario, we'll choose the default instance settings. If you spin up a non-AMI Linux instance, you should install the AWS Command Line Interface software.
Select the ec2-privs-for-cron role In the Configure Instance Details page of the IAM role field. You won't be able to change the IAM role once the instance is launched. The AWS access keys with the specified permissions of this role will be available to this EC2 instance automatically. Ensure you can Secure Socket Shell (SSH) into the instance to complete the configuration. Finally, click Launch Instance.
Configure the EC2 instance
To configure the new instance, SSH into the instance and create EC2 start / stop scripts. Then create a directory, such as "scripts," in the home ec2-user account.
Change directory into the scripts directory and create a "stop-ec2.sh" script file; add the "ec2-stop-instances i-xxxxxxxx" AWS CLI command where "i-xxxxxxxx" is the instance ID you want to stop. Repeat the CLI for each instance you want to stop.
Next, create a second script file named "start-ec2.sh" and add the "ec2-start-instances i-xxxxxxxx" AWS CLI where "i-xxxxxxxx" is the instance ID you want to start. Next, ensure the execute bit is set on these scripts. Add cron entries.
Edit the crontab file using the "crontab –e" command and add the follow lines:
- EC2_HOME = /opt/aws/apitools/ec2-188.8.131.52 -- This must be the actual AWS CLI root directory; it cannot reference a symbolic directory name.
- JAVA_HOME=/usr/lib/jvm/jre-1.7.0-openjdk.x86_64 -- This must be the actual JAVA root directory; it cannot reference a symbolic directory name.
- PATH=/bin:/usr/bin:/opt/aws/apitools/ec2-184.108.40.206/bin -- The PATH environment variable containing the bin directories of any executables used in cron script files must be part of the path.
- "30 2 * * * /home/ec2-user/scripts/stop-ec2.sh >> /tmp/aws_instance_stop.log 2>&1" -- This is the actual cron entry that executes the stop-ec2.sh scipt. The first five parameters define the date/time and frequency the script is to be run; cron uses the time zone predefined in the instance. As such, since my instance is set to the UTC time zone, the entry states the stop-ec2.sh script will run every day at 2:30 a.m. UTC or 10 p.m. EST.
- Reference the cron wiki to learn how to set different date and time frequencies. The ">> /tmp/aws_instance_stop.log" logs the results of script execution to the aws_instance_stop.log file in the /tmp directory.
- "15 10 0 0 * /home/ec2-user/scripts/start-ec2.sh >> /tmp/aws_instance_start.log 2>&1" This is the actual cron entry that executes the start-ec2.sh scipt. Notes: cron will execute this start-ec2.sh script every day at 10:15 a.m. UTC or 6:15 a.m. EST.
- The ">> /tmp/aws_instance_start.log" logs the results of script execution to the aws_instance_start.log file in the /tmp directory.
- Your crontab file should now look something like this:
# cron entries for starting/stopping EC2 instances (rjv) 10.21.2014
# Set Environment Variables
# define scripts to run based on schedule
30 2 * * * /home/ec2-user/scripts/stop-ec2.sh > /tmp/aws_instance_stop.log 2>&1
15 10 * * * /home/ec2-user/scripts/start-ec2.sh > /tmp/aws_instance_start.log 2>&1
About the author:
Russ Vanderpool, MSCS and MBA, is a technologist interested in using cloud technology to deliver solutions, help companies better serve customers and identify new businesses. He has hands-on experience as an architect/developer and a business adviser across the finance, energy, education, technology and nonprofit sectors. Russ has architected and built a cloud infrastructure for a green tech company and while working for Japan's largest system's integration firm, he developed proprietary object-oriented database visualization software for that market.