Monday, September 14, 2020

Launch an ec2 instance with a static website using awscli in 10 min (FreeTier)

The Magic Of AWS CLI v2. We have seen the movies where a person… | by  Dipaditya Das | Medium


aws cli is a strong yet easy way to automate simple repeatable tasks covering aws resources as it’s a direct, human-readable doorway to aws cloud platform. 
This tutorial will not just demonstrate how to provision a website in awscloud, but will hopefully trigger your curiosity on the numerous possibilities the Command line tool can enrich your IaC experience with. We will see how it can amplify your productivity when combined with powerful shell scripts.
Here’s a direct link to my Github repo with all the scripts : 
Here’s also a gif demo if your curious : 

I. Shell scripting to the rescue

After a similar cli experience done on Oracle (see my oci-cli post) I decided to take a shot at awscli. The journey started with a simple instance launch script and ended up with an automated website provisioning on not one, but 6 different Operating systems :) (RHEL, CENTOS, Ubuntu, amazon-linux2, SUSE, and Windows server). 5 interactive BASH scripts & userdata files were crafted. I also had to learn how auto-install and configure nginx in each mentioned OS’ (windows was the nastiest). On top of that, the code had to ensure that required network components were created if missing (route table,security group...).
It took me few days to pull out but I am glad I did as I learned more about what’s under the API hood than before. Hoping this would also give a solid intro to aws-cli for beginners.  

If you like Latino music and Dj snake you’ll be in for a treat !! (complete the lab to know more ;)) 


The following figure shows the layers involved between our workstation an AWS while running the cli commands along with the instance attributes we will be provisioning (values might change).

This image has an empty alt attribute; its file name is topology.png

CLI setup and assumptions

If your cli environment is not configured yet, go check my previous post (aws-cli installation) before continuing.  

I will assume that the below elements are present/configured in your workstation:

  • AWSCLI default profile configured with your aws credentials (Access keys). Refer to my Blog post for more details
  • $ aws configure list
    Name                    Value            Type    Location
    ----                    ---------        ----    -------- profile                 <not set> None
    access_key     ****************J2WA shared-credentials-file
    region                us-east-1      config-file    ~/.aws/config

  • ssh key pair to attach to your ec2 instance. I had to create a PEM based key pair as it’s the only one supported by  Windows instances when generating the admin password.
  • $ ssh-keygen -P "" -t rsa -b 2048 -m pem -f ~/id_rsa_aws
    Generating public/private rsa key pair.
    Your identification has been saved in /home/brokedba/id_rsa_aws.
    Your public key has been saved in /home/brokedba/
  • Run a quick API request to confirm your setup is valid
  • $ aws ec2 describe-regions --filters "Name=region-name,Values=us-west-2" --query 'Regions[]' 
    |  Endpoint                   |    OptInStatus     |  RegionName       | 
    | | opt-in-not-required|   us-west-2       |
  • Note:  My scripts were run on Linux but It can be tried on windows using Gitbash (or WSL) as bash terminal client. 

II. Clone the repository

III. Deployment

  • Although awscli leverages JMSPATH to query the JSON based cloud resource data , it can get hard to avoid mistakes with IDs and lookups syntax when running these commands. That’s where “Shell scripts” come handy
  • Note : My profile’s default region is us-east-1 and the default output is table (cue the tabular display).


    • As said before, all these scripts are interactive. Here, you can change or choose default values for the VPC Name and CIDR block. I also added checks on the IP/CIDR format. Scripts are also clickable so you can see the content.
    • You will notice a security group menu that offers to open few pots (22,80) needed for our instance launch
      brokedba@ ./
        Enter the VPC name you wish to create [CLI-VPC]: 
        selected VPC name : CLI-VCN
        Enter the VPC CIDR to assign '/16-To-/28' []:
        == VCN information ===
        VPC name = CLI-VPC
        CIDR =
        ==== Created VPC details ==== +----------------+--------+----------------------+-------------+ | CIDR | Name | VPC_ID | association | +----------------+--------+----------------------+-------------+ | | CLI-VPC| vpc-0091141e28608813c| associated | +----------------+--------+----------------------+-------------+ Note : the last octet is always zeroed even if you specify a non zero value
      ************ Security Group ! ************
      1) SSH port Only             3) SSH ,HTTP,RDP, and HTTPS
      2) SSH, HTTP, and HTTPS

      Select a security group ingress rule and press Enter: 2
      ******************* Security Group detail  ******************
      |      Description      | Protocol  | SourceCIDR  | ToPort  | fromport   |
      |  Inbound HTTP access  |  tcp      |  |  80     |  80        |
      |  Inbound SSH access   |  tcp      |  |  22     |  22        |

      SG delete command  ==> aws ec2 delete-security-group --group-id sg-a38937a4d75361
      VPC delete command ==> aws ec2 delete-vpc --vpc-id vpc-0091141e28608813c

      Tip: click on the script to see its cli .

      A delete command is also included in each script so you could destroy/repeat without using the Web Console.


    • You can pick the right VPC name then choose both a new subnet name and CIDR Block.
    • This will also Auto-assign a public IP address to future instance launched in this subnet
    • My CIDR checker won't validate any complex subnetting. If you want to choose a custom CIDR block make sure it's contained in the VPC and doesn’t overlap with any existing subnet (of the same VPC).

      brokedba@ ./ +----------------+--------+----------------------+-------------+ | CIDR | Name | VPC_ID | association | +----------------+--------+----------------------+-------------+ | | CLI-VPC| vpc-0091141e28608813c| associated | +----------------+--------+----------------------+-------------+ Select the VPC Name you wish to attach your subnet to []: CLI-VPC Selected VCN name : CLI-VPC Enter the subnet name you wish to create [CLI-SUB]: CLI-SUB Selected SUBNET name : CLI-SUB ============ SUBNET CIDR ========================== Subnet CIDR must be contained in its VPC CIDR block  =================================================== Enter the VCN network CIDR to assign []: == Subnet information ===
        VPC name = CLI-VPC
        VPC CIDR =
        SUBNET name = CLI-SUB
        SUBNET CIDR =

      ==== Created SUBNET details ====
      ------------------------------------------ |             DescribeSubnets            |
      |  AZ       |  us-east-1f                |
      |  AutoIP   |  False                     |
      |  CIDR     |           |
      |  IP_COUNT |  251                       |
      |  Name     |  CLI-SUB                   |
      |  SUB_id   |  subnet-017a7233422dbec22  |
      |  VPC_id   |  vpc-0091141e28608813c     |
      --> Auto-assign Public IP enabled for CLI-SUB
      Delete command ==>
      aws ec2 delete-subnet --subnet-id subnet-017a7233422dbec22

      Note: The script still checks if the entered subnet CIDR has a prefix that is between the VPC’s CIDR prefix and /28.


    • This is pretty straightforward but I managed to tuck in a little check that exits if a gateway already exists.
      brokedba@ ./
      +----------------+--------+----------------------+-------------+ | CIDR | Name | VPC_ID | association | +----------------+--------+----------------------+-------------+ | | CLI-VPC| vpc-0091141e28608813c| associated | +----------------+--------+----------------------+-------------+
      select the VPC you wish to add the I-Gateway to []:
      selected VPC name : CLI-VPC Creating a New Internet gateway ... Enter the Internet gateway name you wish to create [CLI-IGW]: CLI-IGW
      ==== Created Internet gateway Details ====

      |         Igw_id         |  Name    |   State    |         Vpc_id          |
      igw-0003fea32eb918944 |  CLI-IGW |  available |  vpc-0091141e28608813c  |

      Detach command ==> aws ec2 detach-internet-gateway --internet-gateway-id igw-00xx --vpc-id vpc-0091xxx Delete command ==> aws ec2 delete-internet-gateway --internet-gateway-id igw-00xx


    • A VPC list prompted at the beginning of the output(omitted here) will let you choose the VPC before asking to enter the subnet. If both subnet and internet gateway exist the route table is then set.

      brokedba@ ./

      Select the VPC you wish to set the route table for []: CLI-VPC
      selected VPC name : CLI-VPC Internet gateway exists => checking the subnet availability ...
      |             DescribeSubnets            |
      |  AZ       |  us-east-1f                |
      |  CIDR     |           | |  IP_COUNT |  251                       |
      |  Name     |  CLI-SUB                   |
      |  SUB_id   |  subnet-017a7233422dbec22  |
      |  VPC_id   |  vpc-0091141e28608813c     |
      select the subnet Name you wish to set the route table for []: CLI-SUB
      Internet gateway and subnet exist => Setting up the new Route table
      Create Route Table
      Create new route to Internet Gateway for Route Table ID 'rtb-062ff0c3c7069c885'.
      Associate 'CLI-SUB' Subnet with the Route Table.

      ==== Custom Route table entries for CLI-VPC ==== ----------------------------------------------------------------------------------- | DescribeRouteTables | +--------+---------------+---------------------------+----------------------------+ | Main | Name | Vpc_id | rt_id | +--------+---------------+---------------------------+----------------------------+ | False | rt_CLI-SUB | vpc-0091141e28608813c | rtb-062ff0c3c7069c885 | +--------+---------------+---------------------------+----------------------------+ || Routes || |+----------------------+-------------------------+--------------------+---------+| || DestinationCidrBlock | GatewayId | Origin | State || |+----------------------+-------------------------+--------------------+---------+| || | local | CreateRouteTable | active || || | igw-0003fea32eb918944 | CreateRoute | active || |+----------------------+-------------------------+--------------------+---------+|
      Detach route command ==>  aws ec2 disassociate-route-table --association-id rtbassoc-
      Delete route command ==>  aws ec2 delete-route --route-table-id rtb-69c885 --destination-cidr-block
      delete route-table command ==> aws ec2 delete-route-table --route-table-id rtb-062

             Delete commands are added at the end to get familiar with the delete syntax and know more about the underlying tasks.

    • Below menu returns the last available image per OS type. This will help you decide which OS to choose for your instance
      brokedba@ ./ 
      ******* AWS Image Selecta ! ************
      Choose your Destiny ||{**}||
      1) Oracle-Linux     3) Amazon Linux 2         5) Windows    7) Exit?  
      2) CentOS           4) Ubuntu                 6) Suse   
      Select an option and press Enter: 5 ------------------------------------------------------------------------------------- | DescribeImages | +--------------+--------------------+---------------------------------------+-------+ | Ami | Created | Name | SizeGb| +--------------+--------------------+---------------------------------------+-------+ | ami-06f6f331| 2020-09-09T06:26:58| Windows_Server-2016-English-Full-Base-| 30 | +--------------+--------------------+---------------------------------------+-------+


    • Awesome, all the network resources are set, we can now launch a our new instance.The script’s default instance type is free tier eligible (t2.micro) and there are 6 different OS’ to pick from .You’ll be asked to retry if the VPC and Subnet don’t match.
    • I chose Windows in this example because it has additional requirements that make it tricky but you can spin any of the available options 

    brokedba@ ./
    ******* Oci instance launch ! ************ Choose your Shape ||{**}|| Note: t2.Micro is the default FreeTier elligible instance type used here Enter the Path of your ssh key [~/]: Enter the name of your new Instance [Demo-Cli-Instance]: Demo-Win2016 ----- selected Instance name : Demo-Win2016 selected public key: /home/brokedba/ The Instance Type will be the most recent FreeTier Elligible : t2.micro ------------------------------------------ | DescribeInstanceTypes | +-----+------------+---------+-----------+ | Ghz | Instance | Memory | VirType | +-----+------------+---------+-----------+ | 2.5| t2.micro | 1024 | hvm | +-----+------------+---------+-----------+
    ********** Network *********** ----------------------------------------------------------------------- | DescribeVpcs | +-----------------+----------+-------------------------+--------------+ | CIDR | Name | VPCID | association | +-----------------+----------+-------------------------+--------------+ | | CLI-VPC | vpc-0091141e28608813c | associated | +-----------------+----------+-------------------------+--------------+ select the VPC Name for your new instance []: CLI-VPC selected VPC name : CLI-VPC 1. Internet gateway check
    Internet gateway exists => checking the subnet availability
    ... ------------------------------------------------------------------------------------- | DescribeSubnets | +--------+---------+------------------+-----------+----------+----------------------- | AZ | AutoIP | CIDR | IP_COUNT | Name | SUB_id | +------------+---------+------------------+-----------+----------+------------------- | us-east-1f| True | | 251 | CLI-SUB | subnet-2dbec22 | +------------+---------+------------------+-----------+----------+------------------- Select The Subnet for your new instance []: CLI-SUB selected subnet name : CLI-SUB Internet gateway and subnet exist => checking the Route table ... ...Route Table check The vpc has a route table with a route across an internet gateway. checking the association with CLI-SUB subnet. ... 2. Route is associated with CLI-SUB subnet. Checking the Security Group ... ... Checking the availability of a security Group with SSH/HTTP ingress rule .
    3. dedicated security Group ingress rules exists PORT (22,80). ... Creating the instance with the below SG . ---------------------------------------------------------------------------- | DescribeSecurityGroups | +---------------+----------------------------+-----------------------------+ | Name | SG_id | Vpc_id | +---------------+----------------------------+-----------------------------+ | sg_CLI-VPC | sg-0e8a38937a4d75361 | vpc-0091141e28608813c | +---------------+----------------------------+-----------------------------+ || Rules || |+-----------------------+-----------+-------------+---------+------------+| || Description | Protocol | SourceCIDR | ToPort | fromport || |+-----------------------+-----------+-------------+---------+------------+| || Inbound HTTP access | tcp | | 80 | 80 || || Inbound SSH access | tcp | | 22 | 22 || |+-----------------------+-----------+-------------+---------+------------+|
    4. Choose your Image ||{**}|| 1) RHEL 3) amazon Linux 2 5) Windows 7) Exit? 2) CentOS 4) Ubuntu 6) Suse Select an option and press Enter: 5 ------------------------------------------------------------------------------------- | DescribeImages | +-------------+------------------+---------------------------------------+----------+ | Ami | Created | Name | SizeGb | +-------------+------------------+---------------------------------------+----------+ | ami-06f6f3*| 2020-09-09T06:26 |Windows_Server-2016-English-Full-Base | 30 | +-------------+------------------+---------------------------------------+----------+ >> opening port 3389
    ===== Instance Deployment Detail ======== selected Subnet name : CLI-SUB selected Instance name : Demo-Win2016 selected instance Type: t2.micro selected public key: /home/brokedba/ selected Security Group: sg-0e8a38937a4d75361 selected OS : Windows ... Importing/checking the key pair to/from AWS key-pair exists .. ==================================== Check the status of the new Instance ==================================== The compute instance is being created. This will take few minutes ... ------------------------------------------- | DescribeInstances | +------------+----------------------------+ | AZ | us-east-1f | | Hostname | | | ID | i-04b8144695dd402b0 | | Name | Demo-Win2016 | | Platform | windows | | PrivIP | | | Public_IP | | | Subnet | subnet-017a7233422dbec22 | | Type | t2.micro | | VPCID | vpc-0091141e28608813c | | image | ami-06f6f33114d2db0b1 | | status | running | +------------+----------------------------+ Password is being generated... please wait Windows User = Administrator Password => y=L6J&SrQ;kMnNB2z66Od(oYZtgyaZca Generated password can be retreived using :
    aws ec2 get-password-data --instance-id xxx --priv-launch-key ~/id_rsa_aws
    Your website is ready at this IP :)
    Termination command ==> aws ec2 terminate-instances --instance-ids i-04b8144695dd402b0

      - Below is the instance view  on your AWS console once the instance is provisioned.


    • Grab the public IP and password displayed above and connect to the windows instance using MSTSC as admin

      This image has an empty alt attribute; its file name is image-10.png

    • Type the Public IP in your browser & check the Homepage we customized with our user-data script during bootstrap
      and voilĂ !  =>

    • Note: All other Linux based instances must be accessed using ssh as ec2-user (except for ubuntu which uses “ubuntu” and CENTOS which has “centos” as default user). 
      $ ssh –i ~/id_rsa_aws ec2-user@Public_ip


    Now what if I’m lazy (like most of us :p) and don’t want to pre-create the route table, internet gateway or other security group rules for my instance?! Well In that case, the create_instance script got you covered as it does just that for you. All you need to create is the VPC and Subnet, nothing else. From there, the instance script will check and create any missing network piece for you (internet gateway, Security group, opening HTTP ports,routes ..etc) .             



      • AWSCLI and bash can perfectly fit in with Cloud practitioners’ daily activities, so long as we take the time to refine and strengthen the logic of our scripts. Moreover, the painful handling of long IDs and JMSPATH query syntax errors are here eliminated.
      • This took some time to build but it’s definitely the most direct and simple way to interact with your AWS infrastructure (no SDK). You could even use the learned awscli practice and port it to other SDK supported languages later.  
      • Feel free to fork the repository and adapt your own version of these scripts
      • Improvement : Add additional menus to choose among resources with duplicate names (using the  id) 

    Thanks for reading!

    Thursday, September 3, 2020

    AWS CLI installation in 10 minutes


    Almost every Cloud provider has a Command Line Interface (CLI) which is a unified tool to manage cloud resources. In previous post I described how to configure Oracle Cloud infrastructure CLI. This time my focus is its AWS equivalent as I intend to explore different ways of provisioning instances in all major Cloud shops (OCI,AWS,Azure,GCP),  and since my next article will depend on AWS-CLI, I will start with the configuration piece which I found easier than for oci-cli.

    Context: This is part of a series of 4 articles that will build quick hands-on experiences on AWS provisioning.

    1. Install and configure aws-cli.
    2. Launch an instance using aws-cli.
    3. Launch an Instance using Terraform.
    4. Launch an instance using  aws ansible modules.


    Whether you install aws cli on windows or on Linux the basic install will always require 2 elements:

    I. AWS CLI Installation (version1)

    • Windows

      1- Download and execute the following aws-cli installer
      2- Follow the on-screen instructions. The AWS CLI version 1 will automatically install the correct version as follows
          C:\Program Files\Amazon\AWSCLI
        for 64-bit system
          C:\Program Files (x86)\Amazon\AWSCLI for a 32-bit system
      3- Open Environment Variable window and add the bin directory to the PATH variable
                ==> ”C:\Program Files\Amazon\AWSCLI\bin”

      - Run the version command to confirm that AWS CLI was installed correctly.

      C:\Users\kosse> aws --version
      aws-cli/1.18.130 Python/3.6.0 Windows/10 botocore/1.17.53 

      C:\Users\kosse> where aws C:\Program Files\Amazon\AWSCLI\bin\aws.exe
    • Linux/MacOS (bundled installer) 

      I also had aws-cli installed on my windows subsystem for Linux (WSL) where the installation was done as follows :
      brokedba~$ curl "" -o ""
      brokedba~$ unzip
      brokedba~$ sudo ./awscli-bundle/install -i /usr/local/aws -b /usr/local/bin/aws
      --- Run the version command to confirm it was installed correctly. brokedba~$ aws --version aws-cli/1.18.130 Python/2.7.12 Linux/4.4.0-18362-Microsoft botocore/1.17.53
    • Installation using Python Package manager (pip) :

      You might also install aws cli using if the following pip command (already installed for 2.7.9+) .
    • brokedba~$ pip --version
      pip 20.2.2 from /home/brokedba/.local/lib/python2.7/site-packages/pip (python 2.7) 
      brokdba:~$ pip install awscli
      --- Run the version command to confirm it was installed correctly. brokedba~$ aws --version aws-cli/1.18.130 Python/2.7.12 Linux/4.4.0-18362-Microsoft botocore/1.17.53
      brokedba@brokdba:~$ which aws

    II. Configure AWS CLI

    Once your AWS free Tier account is created, python and aws cli installed you will need to gather the required credentials as shown in the below setup tasks:

    • Create the Access Key
      AWS-CLI will need the access key to make API calls to AWS.
      On your Console, go to the profile menu on the top right of the page and click on My security Credentials.
                                                                             AWS Credentials
    • Click Create Access Keys under "Access keys" section. You have the right to 2 Access keys as a Free Tier user

                                                  Create access key
    • Download the Access key
      Click Download Key file as it's only available at creation and not later. The csv file will contain the key Id and secret key.

                                                                New access key
    Note: You can always delete keys to recreate new ones if you reach the max amount of access keys or lost the key file.    

    • Run AWS configure

      Now that you have installed aws cli along with the access key info gathered in your csv file, you can finally configure your aws-cli with just the key id and the access key (region and output format are not credentials).To do so run the following:
      $ aws configure 
      Access Key ID:
      Secret Access Key:
      Default region name [us-east-1]:
      Default output format [table]:
      You can also add a profile when you have multiple aws accounts to manage
      $ aws configure --profile brokedba
      Access Key ID:
      Secret Access Key:
      Default region name [us-east-1]:
      Default output format [table]:

    • - Below are few information related to the current configuration and the files that were updated during setup:
        Config files :
        ==> Supported by all SDKs and contain credentials only
           ~/.aws/config          ==> Supported by CLI only and can contain credentials

      $ aws configure list
            Name                    Value             Type    Location
            ----                    -----             ----    --------
         profile                             None    None
      access_key     ****************J2WA shared-credentials-file
      secret_key     ****************H5Bn shared-credentials-file
          region                us-east-1      config-file    ~/.aws/config
      $ cat ~/.aws/credentials [default] aws_access_key_id = AKIXXXXXXXXXXXXXXXXXJ2WA aws_secret_access_key = DsXXXXXXXXXXXXXX5Bn [brokedba] aws_access_key_id = AKIXXXXXXXXXXXXXXXXXJ2WA aws_secret_access_key = DsXXXXXXXXXXXXXX5Bn $ cat ~/.aws/config [default] output = table region = us-east-1 [profile brokedba] output = table region = us-east-1

    III.Test your first API request

    Few notions worth reminding before hitting the terminal with your favorite  aws-cli requests :    
    A. Command structure : is based on the below components

      $ aws <AWS service> <operation to perform> [one or more options & parameters]   

            Will be followed by their values, for example when specifying an instance id we want to describe or defining a name for a created
            key- pair. The value type can also vary (string, integer, JSON, list, binary,…)

    •  Options :
      1- “-- output” : will format AWS CLI output into Json, yaml, Table, or text (raw).
                 2- “-- query” : Allows to choose the list of fields to return in the response. It can be used  to do some simple filtering.
                 3- “ -- filters” : Is the condition used to specify which resources you want described or listed.

    B. Filters vs Query
    The --query option relies on JMSPath and its filtering is done at client side while --filters does it at server level which is way faster and more efficient. I personally use filters to narrow my research and query to specify which field I want to display.

    - To demonstrate the nuance, here’s an example where we filter an aws region using each option (filters and query)

      $ aws ec2 describe-regions --query 'Regions[?RegionName==`us-west-2`]' 
      $ aws ec2 describe-regions --filters "Name=region-name,Values=us-west-2"


    There are few requests that you can run to test your connectivity and practice with aws-cli. Below describe-* commands are good examples to start with.

    • Describe and list aws regions using describe-regions subcommand and --query option
      $ aws ec2 describe-regions --query 'Regions[]'
      |                               DescribeRegions                               |
      |             Endpoint              |      OptInStatus      |   RegionName    |
      |     |  opt-in-not-required  |  eu-north-1     |
      |     |  opt-in-not-required  |  ap-south-1     |
      |      |  opt-in-not-required  |  eu-west-3      |
      |      |  opt-in-not-required  |  eu-west-2      |
      |      |  opt-in-not-required  |  eu-west-1      |
      | |  opt-in-not-required  |  ap-northeast-2 |
      | |  opt-in-not-required  |  ap-northeast-1 |
      |      |  opt-in-not-required  |  sa-east-1      |
      |   |  opt-in-not-required  |  ca-central-1   |
      | |  opt-in-not-required  |  ap-southeast-1 |
      | |  opt-in-not-required  |  ap-southeast-2 |
      |   |  opt-in-not-required  |  eu-central-1   |
      |      |  opt-in-not-required  |  us-east-1      |
      |      |  opt-in-not-required  |  us-east-2      |
      |      |  opt-in-not-required  |  us-west-1      |
      |      |  opt-in-not-required  |  us-west-2      |
    • List the access keys for an aws account :
      $ aws iam list-access-keys --query  "AccessKeyMetadata"
      |                            ListAccessKeys                            |
      |      AccessKeyId      |      CreateDate        | Status  | UserName  |
      |  AXXXXXXXXXXXXXXXXXWA |  2020-06-25T07:13:44Z  |  Active |  brokedba |
      |  AXXXXXXXXXXXXXXXXZOA |  2020-09-02T00:24:17Z  |  Active |  brokedba |
    • List the existing buckets within the s3 account:
    • $ aws s3 ls
      2020-06-07 01:51:08 brokebucket
      2020-06-13 20:01:06 brokereportbucket
    • Describe existing instances in the default region and give a custom name for each field inside the braces:

    • $ aws ec2 describe-instances --query 'Reservations[].Instances[].{VPCID:VpcId,Subnet:SubnetId,image:ImageId,Rootdev:RootDeviceName,AZ:Placement.AvailabilityZone,PrivIP:PrivateIpAddress}'
      ----------------------------------------- | DescribeInstances | +----------+----------------------------+ | AZ | us-east-1a | | PrivIP | | | Rootdev | /dev/sda1 | | Subnet | subnet-08b49f9682c5da2b6 | | VPCID | vpc-096b461ebe9d06ff3 | | image | ami-01861c2f0a2adfdb7 | +----------+----------------------------+
    • Note: If you don’t like the table output you can always go for a text or Json  layout using --output option


    AWS has made a CLI alias repository available in their GitHub.Some of them can help get a grasp of common queries like describing security groups, open public ports,running instances etc. You can quickly install it by running the below commands:
    $ git clone
    $ mkdir -p ~/.aws/cli 
    $ cp awscli-aliases/alias ~/.aws/cli/alias

    IV. Upgrade to Version 2

    AWS CLI version 2 is available since last February and is the recommended version. The upgrade to v2 is unfortunately not direct as the existing v1 has to be uninstalled first but the configuration will still be in place after upgrading (No pip install possible in v2).
    You can quickly upgrade by following the bellow steps:

    • Windows

      - Uninstall aws-cli v1: Type appwiz.cpl in your cmd box and & hit uninstall for the entry named “AWS Command Line Interface”
      - Download & Run awscli v2 installer (64bits only): 
      • C:\Users\kosse>  aws --version
        aws-cli/2.0.45 Python/3.7.7 Windows/10 exe/AMD64
    • Linux
      • 1-– uninstall v1
        sudo rm -rf /usr/local/aws
        $ sudo rm /usr/local/bin/aws
        2-- install v2
        $ curl "" -o ""
        $ unzip
        $ sudo ./aws/install -i /usr/local/aws-cli -b /usr/local/bin

        3-- Run the version command to confirm v2 was installed correctly

        $ aws --version
        aws-cli/2.0.45 Python/3.7.3 Linux/4.4.0-18362-Microsoft exe/x86_64.ubuntu.16
    • Enable autocomplete (v2)
      • $ complete -C aws_completer aws
    • Explore awscli wizard (v2)


    In this tutorial we learned how to install and configure aws-cli v1 which took 5 minutes then upgraded to v2 that took,well... few more ;). We also described the command syntax and tried few describe requests using aws-cli.
    The new features of aws-cli version2 (interactivity,SSO,autocomplete,wizards…) seem to bring more value to the tool which makes it worth a try.   
    Just remember to use --filters as a condition and --query as a select to reduce the overhead/response time on your cli requests. Finally, feel free to consult AWS CLI Command Reference for more details and examples on aws-cli requests.