Lab - Managing Resources With Tagging
Lab - Managing Resources With Tagging
In the Task portion of this lab, you will use the AWS Command Line Interface (CLI)
to inspect the tags assigned to a number of Amazon EC2 instances. You will then use
pre-provided scripts to shut down and start up a number of Amazon EC2 instances
simultaneously, based on their tags.
In the Challenge portion of this lab, you will be challenged to think of a way to
terminate instances that fail to implement specific tags.
Objectives
After completing this lab, you will be able to:
Scenario
In the Task portion of this lab, you will log in to the Command Host and run some
commands to find and change the Version tag on all development instances. You will
run several examples that show how you can use the JMESPath syntax supported by the
AWS CLI --query option to return richly formatted output. You will then use a set
of pre-provided scripts to stop and re-start all instances that are tagged as
belonging to the development environment.
ResourcesArchitecture
Wait until you see the message "Lab status: ready", then click the X to close the
Start Lab panel.
Tip: If a new browser tab does not open, there will typically be a banner or icon
at the top of your browser indicating that your browser is preventing the site from
opening pop-up windows. Click on the banner or icon and choose "Allow pop ups."
Arrange the AWS Management Console tab so that it displays along side these
instructions. Ideally, you will be able to see both browser tabs at the same time,
to make it easier to follow the lab steps.
Copy the IPv4 Public IP from the Description in the lower pane.
Read through the three bullet points in this step before you start to complete the
actions, because you will not be able see these instructions when the Details panel
is open.
Click on the Details drop down menu above these instructions you are currently
reading, and then click Show. A Credentials window will open.
Click on the Download PPK button and save the labsuser.ppk file. Typically your
browser will save it to the Downloads directory.
Then exit the Details panel by clicking on the X.
Download needed software.
You will use PuTTY to SSH to Amazon EC2 instances. If you do not have PuTTY
installed on your computer, download it here.
Open putty.exe
Click Connection
Set Seconds between keepalives to 30
This allows you to keep the PuTTY session open for a longer period of time.
Click Session
Host Name (or IP address): Paste the Public IPv4 value you copied to your clipboard
earlier in the lab.
Back in PuTTy, in the Connection list, expand SSH
Click Auth (don't expand it)
Click Browse
Browse to and select the lab#.ppk file that you downloaded
Click Open to select it
Click Open
Click Yes, to trust the host and connect to it.
Copy the IPv4 Public IP from the Description in the lower pane.
Read through the three bullet points in this step before you start to complete the
actions, because you will not be able see these instructions when the Details panel
is open.
Click on the Details drop down menu above these instructions you are currently
reading, and then click Show. A Credentials window will open.
Click on the Download PEM button and save the labsuser.pem file.
Then exit the Details panel by clicking on the X.
Open a terminal window, and change directory cd to the directory where the
labsuser.pem file was downloaded.
For example, run this command, if it was saved to your Downloads directory:
cd ~/Downloads
Change the permissions on the key to be read only, by running this command:
To find all instances in your account that are tagged with a tag of Project and a
value of ERPSystem, copy the following command and run it in the Linux terminal
window:
Use the --query parameter to limit the output of the previous command to only the
instance ID of the discovered instance:
[
[
"i-135b491e"
],
[
"i-3e584a33"
],
…
]
The --query command used in this example uses the JMESPath wildcard syntax to
specify that the command should iterate through all reservations and all instances
and return the InstanceId for each instance in the return results.
This is an improvement over returning every property of our instances. But what if
you want to include multiple fields in the output?
Copy the following command and run it in the Linux terminal window to include both
the instance ID and the Availability Zone of each instance in your return result:
object.{Alias1:PropertyName1,Alias2:PropertyName2,[…]}
As seen here, you can specify an alias for each property in order to return a more
abbreviated output format.
With this output, you can clearly see that your filter worked, and you are only
seeing instances that are associated with the project ERPSystem. However, you still
will probably not be able to identify which instances are being returned, based on
this information. In the next steps, you will see how to include the value of your
custom tags in the return output.
To include the value of the Project tag in your output, copy and run the following
command in the Linux terminal:
[[{
"Project": "ERPSystem",
"AZ": "us-west-2a",
"ID": "i-3250b838"
}],
…
]
The value of a specific named tag can be retrieved via a JMESPath query, using the
following syntax:
Tags[?Key==\`Project\`] | [0].Value
This syntax instructs JMESPath to find all elements within the Tags array that have
a Key value of Project. The output of that command—which will be a single Tags
element—is then piped to another command that selects the first instance of this
filtered set and selects the named parameter Value, which is the value of the
Project tag. This result is then assigned the alias Project.
Copy and run the following command to also include the Environment and Version tags
in your output:
[[{
"Environment": "production",
"Project": "ERPSystem",
"Version": "1.0",
"AZ": "us-west-2a",
"ID": "i-3250b838"
}],
…
]
Finally, add a second tag filter to see only the instances associated with the
project named ERPSystem that belong to the Environment named development:
[[{
"Environment": "development",
"Project": "ERPSystem",
"Version": "1.0",
"AZ": "us-west-2a",
"ID": "i-9552ba9f"
}],
…
]
You could individually set these properties on each affected instance, but an
automated approach is more practical. You can use a simple Linux Bash shell script
to build on the queries you built earlier and modify tag entries as a batch
operation.
nano change-resource-tags.sh
Examine the contents of the script:
#!/bin/bash
Notice how the first command uses the --output text option to manipulate the return
results as text instead of as JSON. Using this command instead of JSON on a simple
return result—in this case, a list of IDs—can make it easier to manipulate the
return result and pass it to other commands.
Close the nano editor and run this command from the Linux command prompt:
./change-resource-tags.sh
To verify that the version number on these instances has been incremented and that
other non-development boxes in the ERPSystem project have been unaffected, copy and
run the following command:
cd aws-tools
Open the file stopinator.php and examine its contents:
nano stopinator.php
The stopinator.php script is a simple script that uses the AWS SDK for PHP to stop
and restart instances based on a set of tags. This enables scenarios such as
shutting off your development environment servers at the end of the day and
restarting them the next morning. The script will look in every AWS region for
instances that match the specified tags.
The script takes the following arguments:
./stopinator.php -t"Project=ERPSystem;Environment=development"
The output should look like this, indicating that two instances will be stopped in
your current AWS region. (Your results will differ depending on the region in which
your lab is running.)
Region is us-east-1
No instances to stop in region
Region is us-west-1
No instances to stop in region
Region is us-west-2
Identified instance i-9552ba9f
Identified instance i-d35fb7d9
Stopping all identified instances...
[…]
No instances to stop in region
Region is sa-east-1
No instances to stop in region
Verify that two instances are stopping or have already been stopped.
Return to the SSH session for Command Host, and from the Linux prompt, restart your
instances with the following command:
./stopinator.php -t"Project=ERPSystem;Environment=development" -s
Return to the EC2 Management Console window and verify that the two instances that
were previously shut down are now restarting.
Note If you are already familiar with AWS, we recommend that you try this challenge
yourself before reading the detailed solution provided in the next section. When
you have completed the challenge, check your work by reviewing the detailed
solution.
Challenge Description
Scenario: Your company wants you to create automated processes that will
automatically terminate instances that might allow a possible security breach. You
have identified a list of security risks and are now deciding how to implement them
efficiently by using either AWS CLI commands or the PHP SDK for AWS.
Challenge: Your first security task is simple: find all instances in your private
subnet that do not implement the Environment tag, and terminate them (i.e., a “tag-
or-terminate” policy).
Hints:
If you are not comfortable with PHP or a similar programming language (such as
Python or Ruby) for which an AWS SDK is available, try to use a series of AWS CLI
commands to perform this task.
The AWS PHP call Ec2::terminateInstances() can terminate instances. The equivalent
AWS CLI command is aws ec2 terminate-instances.
You can use the stopinator script from section 2 as a reference for any code you
write.
Challenge Solution Overview
There are multiple ways to approach this problem using a variety of programmatic or
command-line solutions. The general solution to the problem consists of the
following steps:
Identify all of the instances that currently have the Environment tag defined.
Compare this against the list of all available instances, and record the instance
IDs of any instances that are not part of the list obtained from Task 1.
Supply the instance IDs of the non-tagged instances to AWS by using the aws ec2
stop-instance command (AWS CLI) or the Ec2::terminateInstances() API call (PHP).
The following solution demonstrates how this problem could be solved using a PHP
script.
Task 3.1: Review the Tag-Or-Terminate Script
Open the file terminate-instances.php with the nano editor.
nano terminate-instances.php
Examine the params block for this script. Note that it takes two arguments: the
current region that you are running in (region), and the ID of a subnet (subnetid).
The code uses the subnetid argument to determine where to look for non-compliant
instances.
Examine the first block of code, beginning with the comment # Obtain a list of all
instances with the Environment tag set.
This block of code uses the describeInstances() method, a filter to find all
instances that have the Environment tag defined, regardless of the tag’s value. It
stores all of the instance IDs that it finds in a hash table.
This code examines all instances within your subnet and compares them to the list
of instances that are tagged with the Environment tag. If an instance is not in the
tagged list, then its instance ID is added to a list of instances to terminate.
These lines use the list of non-compliant instance IDs as an argument to the
terminateInstances method.
Return to your EC2 Management Console and observe the instances running in your lab
environment.
Select one of the instances in your private subnet.
On the Tags tab for the instance, click Add/Edit Tags.
Find the Environment tag, and click the remove icon.
Click Save. Repeat this process for one other instance in your private subnet.
On the Description tab for your instance, find the Availability zone field, and
copy all but the last letter to a text file. This value will be referred to as
region in a subsequent procedure.
Find the Subnet ID field, and copy its value to a text file. This value will be
referred to as subnet-id in a subsequent procedure.
Return to your SSH session, and run the terminate-instances.php script (replacing
the <region> with your region and <subnet-id> with your subnet-id):
Lab Complete
Congratulations! You have completed the lab.
Click End Lab at the top of this page and then click Yes to confirm that you want
to end the lab.
A panel will appear, indicating that "DELETE has been initiated... You may close
this message box now."