Using AWS CLI (and AWS SDK)
The AWS CLI is an open source tool built using the AWS SDK for Python (Boto3) that provides commands to interact with AWS services. With minimal configuration, you can use all the features provided by the AWS management console from your favorite terminal.
AWS SDKs provide an API for different programming languages (Python, Java, JavaScript, C++, .NET, GO, PHP, Ruby,…) to programmatically build and use AWS services.
In this article, we will see some tips to make the best use of these 2 tools.
- CLI AWS Installation
- AWS CLI Profiles
- Temporary session
- Priorities of Credentials
- Signing HTTP Request
- Debugging
- AWS EC2 Instance Metadata
- AWS SDKs
- AWS Limits and Backoff
CLI AWS Installation
AWS CLI is available in 2 versions:
- Version 2: the latest and supports the latest features
- Version 1: original version, should no longer be used
To install AWS CLI Version 2 on Docker, Linux, macOS or Windows, refer to the AWS documentation https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html
After a successful installation, you should be able to run the following commands:
AWS CLI Profiles
It is possible to register multiple user accounts in AWS CLI. This is called Profiles.
To do this, once your default account is configured, you can add a new one by executing the command:
Now you can run an AWS CLI command under this new Profile by adding the parameter:
Temporary session
When an AWS account is protected by an MFA code, it is possible to create a temporary session using AWS Security Token Service (AWS STS) to request temporary identifiers with limited privileges.
To do this, run the following command:
You get new Credentials, valid, the time of the session.
Priorities of Credentials
It is possible to set Credentials in several places. There is therefore a priority order that must be known to fully understand the adverse effects that this can cause.
For AWS CLI
- Passed in command line (–region, –output, –profile)
- Passed in ENVIRONMENT VARIABLES (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN)
- Saved in the
/. aws/credentials
file generated by theaws configure
command - Saved in the
/. aws/config
file generated by theaws configure
command - Recorded in Container Credentials (for ECS Tasks)
- Saved in the EC2 Instances Profiles
For AWS SDK
- Passed in Language System Properties
- Passed in ENVIRONMENT VARIABLES (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN)
- Saved in the default
/. aws/credentials
file in many SDKs - Recorded in Container Credentials (for ECS Tasks)
- Saved in the EC2 Instances Profiles
Good Practices
To avoid any pitfalls with Credentials, here are some rules to follow:
- NEVER save Credentials in the code!!
- But rather define the Credentials in the best place in the priority chain:
- If you are inside AWS, use Roles IAM (EC2 Instance Roles, ECS Roles, Lambda Roles)
- If you are outside the AWS network, use environment variables or Profiles
Signing HTTP Request
When using AWS CLI or AWS SDK, HTTP calls to AWS are automatically signed. The protocol used is called Signature Version 4 (SigV4) and comes from AWS.
It comes in two possible forms:
- HTTP headers (Authorization header)
- URL parameters (Query string)
Debugging
Here are some tools that will help you debug and understand what’s going on if there are problems:
Policy Simulator
It may be useful to check the access rights to an AWS resource based on a User, Group or Role. There is a tool in AWS that can run these tests, the Policy Simulator: https://policysim.aws.amazon.com/
Dry Run
It may also be useful to test an AWS CLI command by simulating its execution. AWS CLI commands have an option for this:
- Example of simulated creation of an EC2 instance:
Because the command is run in dry-run mode, if successful, it returns DryRunOperation. If failed, it would return UnauthorizedOperation.
Message
Some AWS CLI commands return a encoded authorization message describing the problem. This message must be decoded to be understandable.
To do this, you can use the command:
AWS EC2 Instance Metadata
Instances Metadata are data relating to an EC2 instance: they are accessible from the instance and allow you not to have to use IAM Role since this data has already been loaded into the instance for its configuration or creation.
They are available at: http://169.254.169.254/latest/meta-data/
Note that this is a local address and therefore only accessible from the EC2 instance.
Examples of use
Data Types
There are 3 types of data accessible from an EC2 instance as we can see in the output of this command.
Services
You can access the instance metadata from a running instance using one of the following methods:
- Instance Metadata Service Version 1 (IMDSv1) – request/response method
- Instance Metadata Service Version 2 (IMDSv2) – session-oriented method
When using session-oriented requests (IMDSv2), you create a session token that defines the duration of the session, which must be a minimum of one second and a maximum of six hours. During the specified period, you can use the same session token for subsequent requests.
Here’s how to retrieve a session token:
You can then use it in the following commands, the time of the session:
Some instance metadata
Here is a description of some metadata of instances that may be useful:
Path de la Metadata | Description |
---|---|
ami-id | The AMI ID used to launch the instance. |
ami-launch-index | If you started more than one instance at the same time, this value indicates the order in which the instance was launched. The value 0 indicates the first instance launched. |
block-device-mapping/ami | The virtual device that contains the root/boot filesystem. |
block-device-mapping/ebs N | Virtual devices associated with any Amazon EBS volume. Amazon EBS volumes are only available in the metadata if they were present at the time of launch or when the instance was last started. The N indicates the Amazon EBS volume index (such as ebs1 or ebs2 ). |
events/recommendations/rebalance | Approximate time, UTC, at which the rebalancing recommendation notification EC2 is issued for the instance. Here is an example of metadata for this category : {"noticeTime": "2020-11-05T08:22:00Z"} . This category is only available after the notification has been issued. |
hostname | The private IPv4 DNS host name of the instance. In case of multiple network interfaces are present, this refers to the eth0 device (the device whose device number is 0). |
iam/info | If an IAM role is associated with the instance, it contains information about the last update of the instance profile, among which the date of last update up-to-date (LastUpdated), InstanceProfileArn and InstanceProfileId of the instance. Otherwise, absent. |
iam/security-credentials/ | If an IAM role is associated with the instance, role-name is the name of the role and role-name contains the temporary security identification information associated with the role. Otherwise, absent. |
instance-id | The ID of this instance. |
instance-type | The type of instance. |
kernel-id | The kernel ID launched with the instance, if applicable. |
local-hostname | The private IPv4 DNS host name of the instance. In case of multiple network interfaces are present, this refers to the eth0 device (the device whose device number is 0). |
local-ipv4 | The private IPv4 address of the instance. In case several network interfaces are present, this refers to the eth0 device (the device whose number of device is 0). |
network/interfaces/macs/ | Private IPv4 addresses that are associated with each public IP address and assigned at this interface. |
network/interfaces/macs/ | The local host name of the interface. |
network/interfaces/macs/ | Private IPv4 addresses associated with the interface. |
network/interfaces/macs/ | The public DNS of the interface (IPv4). This category is only returned if the enableDnsHostnames is defined as true . |
placement/availability-zone | The availability zone in which the instance was launched. |
placement/region | AWS region where the instance is launched. |
public-hostname | The public DNS of the proceeding. This category is only returned if the enableDnsHostnames attribute is set as true . |
public-ipv4 | The public IPv4 address. If an Elastic IP address is associated with the instance, the returned is the IP Elastic address. |
security-groups | The names of the security groups applied to the proceeding. After launch, you can change the security groups of the instances. From such changes appear here and in network/interfaces/macs/ |
AWS SDKs
An AWS SDK (Software Development Kit) is used to interact with AWS within an application. There are therefore many AWS SDKs depending on the different programming languages (Python, Java, C++, JavaScript, Ruby, PHP,…):
- The AWS CLI is itself encoded from the Python AWS SDK (also called Boto3).
- Some AWS services are only accessible by an AWS SDK: DynamoDB, Lambda Function,…
Note that if you do not have a default Region, the AWS SDKs will interact with the default Region us-east-1
.
AWS Limits and Backoff
Limits / Quotas
There are Limits or Quotas in AWS that you must be aware of:
- API Rate Limits: depending on the AWS APIs, one cannot make more than a certain number of calls per second to an API
- Service Quotas (or Service Limits): According to the AWS Services, you cannot consume more than a certain number of AWS Services (e.g. 1152 vCPU per AWS account)
Exponential Backoff
When you get ThrottlingException errors when calling AWS Services, you must use the Exponential Backoff.
It is a retry mechanism with a duration between each attempt that increases exponentially. It is described more precisely in this article https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/
- AWS SDKs already implement it, so there is nothing to do
- But if you make calls to the AWS APIs by another means, you MUST set up such a mechanism:
- In case of ThrottlingException or 5xx errors
- Not in case of 4xx errors