Friday, July 9, 2021

Ansible Playbook for provisioning a new EC2 instance in AWS | Create new EC2 instance in AWS cloud using Ansible Playbook

We will learn how to create Ansible Playbook for provisioning a new EC2 instance in AWS cloud. Please follow the below steps in the machine where you have installed Ansible.


Watch here for YouTube Video:

Pre-requisites:


Steps to create EC2 instance using Ansible:

Login to EC2 instance using Git bash or ITerm/putty where you installed Ansible. Execute the below command:

Create an Inventory file first

sudo mkdir /etc/ansible

Edit Ansible hosts or inventory file
sudo vi /etc/ansible/hosts
Add the below two lines in the end of the file:
[localhost]
local


cd ~
mkdir playbooks  
cd playbooks

Create Ansible playbook
sudo vi create_ec2.yml 
(copy the below content in green color)
edit the create_jenkins_ec2.yml to make sure you update the key which is red marked below:

---
 - name:  provisioning EC2 instances using Ansible
   hosts: localhost
   connection: local
   gather_facts: False
   tags: provisioning

   vars:
     keypair: myJan2024Key
     instance_type: t2.small
     image: ami-007855ac798b5175e
     wait: yes
     group: webserver
     count: 1
     region: us-east-1
     security_group: my-jenkins-security-grp
   
   tasks:

     - name: Task # 1 - Create my security group
       local_action: 
         module: ec2_group
         name: "{{ security_group }}"
         description: Security Group for webserver Servers
         region: "{{ region }}"
         rules:
            - proto: tcp
              from_port: 22
              to_port: 22
              cidr_ip: 0.0.0.0/0
            - proto: tcp
              from_port: 8080
              to_port: 8080
              cidr_ip: 0.0.0.0/0
            - proto: tcp
              from_port: 80
              to_port: 80
              cidr_ip: 0.0.0.0/0
         rules_egress:
            - proto: all
              cidr_ip: 0.0.0.0/0
       register: basic_firewall
     - name: Task # 2 Launch the new EC2 Instance
       local_action:  ec2 
                      group={{ security_group }} 
                      instance_type={{ instance_type}} 
                      image={{ image }} 
                      wait=true 
                      region={{ region }} 
                      keypair={{ keypair }}
                      count={{count}}
       register: ec2
     - name: Task # 3 Add Tagging to EC2 instance
       local_action: ec2_tag resource={{ item.id }} region={{ region }} state=present
       with_items: "{{ ec2.instances }}"
       args:
         tags:
           Name: MyTargetEc2Instance


now execute the ansible playbook by
ansible-playbook create_ec2.yml



If everything is good, you should see the new instance created on AWS console. make sure you are able to connect to that instance.

That's it!! That is how you create a new EC2 instance using Ansible.

13 comments:

  1. An exception occurred during task execution. To see the full traceback, use -vvv. The error was: botocore.exceptions.NoCre
    dentialsError: Unable to locate credentials
    fatal: [local -> localhost]: FAILED! => {"boto3_version": "1.20.30", "botocore_version": "1.23.30", "changed": false, "msg
    ": "Error in describe_security_groups: Unable to locate credentials"}


    Getting this error while use yoyr above script

    ReplyDelete
    Replies
    1. Did you attach your IAM role to Ansible machine ?

      Delete
    2. Unabe to locate credentials mean no IAM Role has been attached to the ec2 created, Attach an IAM Role with Full Access policy and try again

      Delete
  2. TASK [Task] *******************************************************************************************************************************************
    fatal: [localhost]: FAILED! => {"msg": "The module ec2\n was not found in configured module paths"}

    ReplyDelete
  3. Below is the error I'm getting; can you please help?

    fatal: [local -> localhost]: FAILED! => {"changed": false, "msg": "Failed to import the required Python library (botocore or boto3) on ip-172-31-30-99.ec2.internal's Python /usr/bin/python3.8. Please read the module documentation and install it in the appropriate location. If the required library is installed, but Ansible is using the wrong Python interpreter, please consult the documentation on ansible_python_interpreter"}

    ReplyDelete
    Replies
    1. i got the same error, did u found any solution, tony?

      Delete
    2. J'ai eu la même erreur, avez-vous trouvé une solution?

      Delete
    3. Hi, it means that the path to the Python interpreter is incorrect or your virtual environment is not being used correctly.
      P.S: Please ensure you're working from a virtual environment before taking the below steps

      Run this command:
      Step 1: Set the Python Interpreter in Ansible Configuratio
      Edit the Ansible configuration file to specify the Python interpreter:

      $ sudo vi /etc/ansible/ansible.cfg

      Add the following line under the `[defaults]` section:

      [defaults]
      interpreter_python = /usr/bin/python3

      Your ansible.cfg file should look like this:

      # Since Ansible 2.12 (core):
      # To generate an example config file (a "disabled" one with all default settings, commented out):
      # $ ansible-config init --disabled > ansible.cfg
      #
      # Also you can now have a more complete file by including existing plugins:
      # ansible-config init --disabled -t all > ansible.cfg

      # For previous versions of Ansible you can check for examples in the 'stable' branches of each version
      # Note that this file was always incomplete and lagging changes to configuration settings

      # for example, for 2.9: https://github.com/ansible/ansible/blob/stable-2.9/examples/ansible.cfg

      [defaults]
      interpreter_python = /usr/bin/python3


      2. Save Changes with command :wq! & enter: Save and close the file.

      AND edit your playbook by adding the ansible_interpreter line in your "vars" section
      ---
      - name: provisioning EC2 instances using Ansible
      hosts: localhost
      gather_facts: no
      vars:
      security_group: my_security_group
      tasks:
      - name: Launch instance
      amazon.aws.ec2_instance:
      key_name: my_key
      instance_type: t2.micro
      image_id: ami-0abcdef1234567890
      security_group: "{{ security_group }}"
      wait: yes
      region: us-east-1
      vars:
      ansible_python_interpreter: /usr/bin/python3
      ``
      save and exit file

      Step 3: Verify the Python Virtual Environment
      Ensure you are using the correct virtual environment. If you are not using the virtual environment, deactivate and reactivate it:

      $ deactivate
      $ source ~/mvenv/bin/activate

      Step 4: Run the Playbook
      Now, try running the playbook again:

      $ sudo ansible-playbook create_ec2.yml

      This should resolve the issue with the Python interpreter. If the error persists, please check if the path to your Python interpreter is correct by running

      $ which python3

      Ensure that the path matches the interpreter specified in the configuration (ansible.cfg) and playbook (sudo vi create_ec2.yml).
      If it differs, update the `ansible_python_interpreter` variable accordingly.

      If you have issues with attributes , let me know

      Delete
  4. Hi. I am new to devops.
    i tried to provide ec2 instalce through playbook. but i got below error
    Python, ansible, pip, boto, boto3 and botocore are installed here.
    Can you please advice me?

    root@test-my-test () ~ # ansible-playbook ec2.yml
    [WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'

    PLAY [provisioning EC2 instances using Ansible] *********************

    TASK [Task] ********************************************************
    ok: [localhost -> localhost]

    TASK [Task] ************************************************
    *fatal: [localhost -> localhost]: FAILED! => {"changed": false, "msg": "boto required for this module”}*

    PLAY RECAP ******************************************************
    localhost : ok=1 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0

    root@test-my-test () ~ # pip list | grep boto
    boto 2.49.0
    boto3 1.26.3
    botocore 1.29.3
    root@test-maltesh-test () ~ #

    root@test-my-test () ~ # python -c "import botocore"
    root@test-my-test () ~ # python -c "import boto"

    root@test-my-test () ~ # ansible --version
    ansible 2.9.27
    config file = /etc/ansible/ansible.cfg
    configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
    ansible python module location = /usr/lib/python2.7/site-packages/ansible
    executable location = /usr/bin/ansible
    python version = 2.7.18 (default, May 25 2022, 14:30:51) [GCC 7.3.1 20180712 (Red Hat 7.3.1-15)]
    root@test-my-test () ~ # python --version
    Python 3.7.10

    ReplyDelete
  5. Here's a REVISED AND UPDATED PLAYBOOK

    ---
    - name: provisioning EC2 instances using Ansible
    hosts: localhost
    connection: local
    gather_facts: False
    tags: provisioning

    vars:
    ansible_python_interpreter: /home/ubuntu/mvenv/bin/python3
    keypair: myKey
    instance_type: t2.small
    image_id: ami-0123456789
    wait: yes
    group: webserver
    count: 1
    region: us-east-1
    security_group: my-jenkins-security-grp

    tasks:
    - name: Task #1 - Create my security group
    amazon.aws.ec2_security_group:
    name: "{{ security_group }}"
    description: "Security Group for webserver Servers"
    region: "{{ region }}"
    rules:
    - proto: tcp
    from_port: 22
    to_port: 22
    cidr_ip: "0.0.0.0/0"
    - proto: tcp
    from_port: 8080
    to_port: 8080
    cidr_ip: "0.0.0.0/0"
    - proto: tcp
    from_port: 80
    to_port: 80
    cidr_ip: "0.0.0.0/0"
    rules_egress:
    - proto: all
    cidr_ip: "0.0.0.0/0"
    register: basic_firewall

    - name: Task #2 - Launch the new EC2 Instance
    amazon.aws.ec2_instance:
    security_group: "{{ security_group }}"
    instance_type: "{{ instance_type }}"
    image_id: "{{ image_id }}"
    wait: "{{ wait }}"
    region: "{{ region }}"
    key_name: "{{ keypair }}"
    count: "{{ count }}"
    register: ec2

    - name: Task #3 - Add Tagging to EC2 instance
    amazon.aws.ec2_tag:
    resource: "{{ item.instance_id }}"
    region: "{{ region }}"
    state: present
    tags:
    Name: MyTargetEc2Instance
    loop: "{{ ec2.instances }}"

    ReplyDelete
  6. Here's an updated playbook:

    ---
    - name: Provisioning EC2 instances using Ansible
    hosts: localhost
    connection: local
    gather_facts: false
    tags: provisioning

    vars:
    keypair: EC2 key
    instance_type: t2.micro
    image_id: ami-0866a3c8686eaeeba
    wait: yes
    group: webserver
    count: 1
    region: us-east-1
    security_group: my-jenkins-security-grp

    tasks:
    - name: Task #1 - Create my security group
    amazon.aws.ec2_security_group:
    name: "{{ security_group }}"
    description: "Security Group for webserver Servers"
    region: "{{ region }}"
    rules:
    - proto: tcp
    from_port: 22
    to_port: 22
    cidr_ip: "0.0.0.0/0"
    - proto: tcp
    from_port: 8080
    to_port: 8080
    cidr_ip: "0.0.0.0/0"
    - proto: tcp
    from_port: 80
    to_port: 80
    cidr_ip: "0.0.0.0/0"
    rules_egress:
    - proto: all
    cidr_ip: "0.0.0.0/0"
    register: basic_firewall

    - name: Task #2 - Launch the new EC2 Instance
    amazon.aws.ec2_instance:
    security_group: "{{ security_group }}"
    instance_type: "{{ instance_type }}"
    image_id: "{{ image_id }}"
    wait: "{{ wait }}"
    region: "{{ region }}"
    key_name: "{{ keypair }}"
    count: "{{ count }}"
    register: ec2

    - name: Task #3 - Add Tagging to EC2 instance
    amazon.aws.ec2_tag:
    resource: "{{ item.instance_id }}"
    region: "{{ region }}"
    state: present
    tags:
    Name: MyTargetEc2Instance
    loop: "{{ ec2.instances }}"

    ReplyDelete

  7. PLEASE HELP ME FOR BELOW ERROR:

    TASK [Task] **********************************************************************************************************
    fatal: [local -> localhost]: FAILED! => {"msg": "The module ec2 was redirected to amazon.aws.ec2, which could not be loaded."}

    PLAY RECAP ***********************************************************************************************************
    local

    ReplyDelete

What is GitHub Advanced Security for Azure DevOps | Configure GitHub Advanced Security for Azure DevOps

GitHub Advanced Security for Azure DevOps brings the  secret scanning, dependency scanning  and  CodeQL code scanning  solutions already ava...