How to use ec2-modify-instance-attribute command from Ansible? - amazon-ec2

I am trying to modify an AWS instance from within ansible.
My playbook is designed to compile and install ixgbevf driver on a running AWS instance then shuts it down so that a ec2-modify-instance-attribute command can be run.
Everything up to the last part of the equation works.
My final role stanza looks like this:
- name: Turn on enhanced networking on on the AMI host
local_action: ec2-modify-instance-attribute the_instance_id={{ my_instance_id }} --sriov simple --region us-west-2
with_items: ec2_info.instances
ignore_errors: yes
When the role runs I get the following errror:
fatal: [10.11.31.48 -> 127.0.0.1] => module ec2-modify-instance-attribute not found in configured module paths
FATAL: all hosts have already failed -- aborting
Is there actually a way to use the ec2-modify-instance-attribute command from within Ansible?

Try using this CLI workaround
local_action:
module: >
shell
aws ec2 modify-instance-attribute --instance-id "{{ ec2_id }}"
--groups "{{ec2_security_group_ids}}" "{{newgroup.group_id}}"
when: newgroup.group_id not in ec2_security_group_ids

I ended up with the following which worked:
- name: "Stop the AWS instance"
local_action:
module: ec2
state: stopped
aws_access_key: "{{ aws.ec2.access_key_id }}"
aws_secret_key: "{{ aws.ec2.secret_access_key }}"
instance_ids: "{{ ansible_ec2_instance_id }}"
region: "{{ ansible_ec2_placement_region }}"
wait: True

Related

Ansible ec2_instance_facts

I have a basic Ansible playbook creating an ec2 instance in aws, its working fine, i want to pick the public ip from the created instance to do furthers task on it, i am using the following section:
- name: get-facts
ec2_instance_facts:
region: eu-west-1
aws_access_key: xxxxxxxxx
aws_secret_key: xxxxxxx
filters:
"tag:Name": docker-server
register: ec2
- debug: var=ec2.instances
But i want to get just the ip address, according to the documentation public_ip
is a string, but i cannot call it when i use ec2.instances.public_ip i get error:
"VARIABLE IS NOT DEFINED!"
what can i do to get the public ip for my created ec2 instance ? thanks.
It is ec2.instances.public_ip_address and public_ip
See: https://docs.ansible.com/ansible/2.9/modules/ec2_instance_info_module.html#return-instances/public_ip_address
ec2_instance_facts deprecated, ansible offer to use ec2_instance_info
See: https://docs.ansible.com/ansible/2.9/modules/ec2_instance_facts_module.html
UPDATE:
- name: Print info
debug: var="ec2.instances[0].public_ip_address"
- name: Loop instances
debug:
var: item.public_ip_address
with_items: "{{ ec2.instances }}"
Thank you for your support and clarification, its finally worked like this:
- name: get-facts
ec2_instance_info:
region: xxxxx
aws_access_key: xxxxxxxxxxx
aws_secret_key: xxxxxxxxxxx
filters:
"tag:Name": docker-server
register: ec2
- debug: var="ec2.instances[0].public_ip_address"

How to extract individual ips of ec2 instances launch using ansible when count is more than 1

I am launching aws ec2 2 instances using ansible using count:2 please check below playbook
- name: Create an EC2 instance
ec2:
aws_access_key: "{{ access_key }}"
aws_secret_key: "{{ key }}"
key_name: "{{ keypair }}"
region: "{{ region }}"
group: "{{ security_group }}"
instance_type: "{{ instance_type }}"
image: "{{ image }}"
wait: yes
count: 2
vpc_subnet_id: "{{ vpc_subnet_id }}"
assign_public_ip: "{{ assign_public_ip }}"
register: ec2
- name: Add the newly created 1 EC2 instance(s) to webserver group
lineinfile: dest=inventory
insertafter='^\[webserver\]$'
line="{{ item.private_ip }} {{hoststring}}"
state=present
with_items: "{{ ec2.instances }}"
- name: add newly created remaining ec2 instance to db group
lineinfile: dest=inventory
insertafter='^\[db-server\]$'
line="{{ item.private_ip }} {{hoststring}}"
state=present
with_items: "{{ ec2.instances }}"
Here i want to add one ip to webserver host group & remaining to db host group but its not working with above playbook please help me to achieve same?
i dont wnt to use add_host here.
Since you are using AWS, have you considered using the aws_ec2 plugin for dynamic inventory?
As long as you are tagging your instances correctly, and you set up the yaml file, it would do what you want it.
Otherwise, your register: ec2 has two elements in it. The way (if it worked) you are looping through ec2 would add both to each group. You would need to add a when condition to match the something like the tag/subnet/cidr to know which server to add to which group.
One way to help see what the return is would be do print out the ec2 variable:
- debug: var=ec2

resize type of ec2 with ansible

I want to resize a ec2 type from ansible.
This is my code:
- name: resize the instance
ec2:
aws_access_key: "{{ aws_access_key_var }}"
aws_secret_key: "{{ aws_secret_key_var }}"
region: "{{ region }}"
instance_ids:
- "{{ instance_id }}"
instance_type: "{\"Value\": \"t2.small\"}"
wait: True
register: ec2_result_file
But I get this error:
fatal: [localhost]: FAILED! => {"changed": false, "msg": "image parameter is required for new instance"}
I try with command line all good
aws ec2 modify-instance-attribute --region reg --instance-id i-xx --instance-type "{\"Value\": \"t2.small\"}
Regards,
How to arrive at the solution:
Ansible tells you it wants to create "a new instance", but you already provided an existing instance ID.
Go to the docs for the ec2 module and check the argument in which you provided the ID of the current instance:
instance_ids list of instance ids, currently used for states: absent, running, stopped
Check what state you specified - you did not, so it's the default.
Check the same docs what is the default for state argument: it is present.
present is not listed in the instance_ids description, so the instance_ids is completely ignored.
Ansible thinks you really wanted to create a new instance.
Solution:
Add state: running to the ec2 module arguments.

Login to created Windows instance using Ansible

I am creating a Windows instance using Ansible. Once the instance got created I need to install IIS on that created instance automatically.
How to login to the newly created instance automatically?
What are the parameters I need to mention in the host (inventory) file to login?
To connect to ec2 instances you will first need to retrieve the password using the ec2_win_password module
Example:
- ec2_win_password:
instance_id: i-xxxxxxx
region: us-west-2
key_file: "/.ssh/yourPEM.pem"
aws_access_key: "{{ aws_access_key }}"
aws_secret_key: "{{ aws_secret_key}}"
security_token: "{{ session_token }}"
key_passphrase: "1122355"
register: result
- debug : msg="{{ result }}"
The result can be used as your ansible_password

Ansible Amazon EC2. The key pair does not exist

I would like to create and provision Amazon EC2 machines with a help of Ansible.
Now, I get the following error:
fatal: [localhost]: FAILED! => {"changed": false, "failed": true, "msg": "Instance creation failed => InvalidKeyPair.NotFound: The key pair '~/.keys/EC2-Kibi-Enterprise-Deployment.pem' does not exist"}
But the .pem key exists:
$ ls -lh ~/.keys/EC2-Kibi-Enterprise-Deployment.pem
-r-------- 1 sergey sergey 1.7K Apr 6 09:56 /home/sergey/.keys/EC2-Kibi-Enterprise-Deployment.pem
And it was created in EU (Ireland) region.
Here is my playbook:
--
- name: Setup servers on Amazon EC2 machines
hosts: localhost
gather_facts: no
tasks:
- include_vars: group_vars/all/ec2_vars.yml
### Create Amazon EC2 instances
- name: Amazon EC2 | Create instances
ec2:
count: "{{ count }}"
key_name: "{{ key }}"
region: "{{ region }}"
zone: "{{ zone }}"
group: "{{ group }}"
instance_type: "{{ machine }}"
image: "{{ image }}"
wait: true
wait_timeout: 500
#vpc_subnet_id: "{{ subnet }}"
#assign_public_ip: yes
register: ec2
- name: Amazon EC2 | Wait for SSH to come up
wait_for:
host: "{{ item.public_ip }}"
port: 22
delay: 10
timeout: 60
state: started
with_items: "{{ ec2.instances }}"
- name: Amazon EC2 | Add hosts to the kibi_servers in-memory inventory group
add_host: hostname={{ item.public_ip }} groupname=kibi_servers
with_items: "{{ ec2.instances }}"
### END
### Provision roles
- name: Amazon EC2 | Provision new instances
hosts: kibi_servers
become: yes
roles:
- common
- java
- elasticsearch
- logstash
- nginx
- kibi
- supervisor
### END
And my var file:
count: 2
region: eu-west-1
zone: eu-west-1a
group: default
image: ami-d1ec01a6
machine: t2.medium
subnet: subnet-3a2aa952
key: ~/.keys/EC2-Kibi-Enterprise-Deployment.pem
What is wrong with the .pem file here?
The key parameter for the ec2 module is looking for the key pair name that has been already uploaded to AWS, not a local key.
If you want to get Ansible to upload a public key you can use the ec2_key module.
So your playbook would look like this:
--
- name: Setup servers on Amazon EC2 machines
hosts: localhost
gather_facts: no
tasks:
- include_vars: group_vars/all/ec2_vars.yml
### Create Amazon EC2 key pair
- name: Amazon EC2 | Create Key Pair
ec2_key:
name: "{{ key_name }}"
region: "{{ region }}"
key_material: "{{ item }}"
with_file: /path/to/public_key.id_rsa.pub
### Create Amazon EC2 instances
- name: Amazon EC2 | Create instances
ec2:
count: "{{ count }}"
key_name: "{{ key_name }}"
...
Do not specify extension for the key. So that key name should be " EC2-Kibi-Enterprise-Deployment " only. Ansible doesn't care if your key is on your local machine at this stage. It verifies if it exists on your AWS account. Go to 'EC2 > Key Pairs' section in your AWS account and you'll see keys are listed without file extensions.
The solution has been found. EC2 doesn't like when you put a full path for the .pem key file.
So, I moved EC2-Kibi-Enterprise-Deployment.pem into ~/.ssh, added it to the authentication agent with ssh-add using:
ssh-add ~/.ssh/EC2-Kibi-Enterprise-Deployment.pem
And corrected the key line in my var file to key: EC2-Kibi-Enterprise-Deployment.pem
The same if you use EC2 cli tools, don't specify a full path to the key file.
ec2-run-instances ami-d1ec01a6 -t t2.medium --region eu-west-1 --key EC2-Kibi-Enterprise-Deployment.pem
While providing Key in variable don't give file extension (.pem). Just give file name.
For example: akshay.pem is my key then in vars filoe just provide akshay as key.

Resources