Ansible | AWS Parameter Store | Integration - amazon-web-services

I have ansible task in which I am passing the password value hard coded.
Ansible script:-
- name: Airflow
rabbitmq_user:
user: airflow
password: password
state: present
force: yes
become: yes
become_method: sudo
become_user: root
register: airflow_dbsetup
notify:
- restart rabbitmq-server
Now I have created AWS parameter store like below. How can I pass these values inside my ansible script.

Take a look at the aws_ssm plugin for ansible.
Example:
- name: Airflow
rabbitmq_user:
user: "{{ lookup('aws_ssm', 'rabbitmq_user', region='us-east-1') }}"
password: "{{ lookup('aws_ssm', 'rabbitmq_password', region='us-east-1') }}
state: present
force: yes
become: yes
become_method: sudo
become_user: root
register: airflow_dbsetup
notify:
- restart rabbitmq-server

Related

Use of module "sts_assume_role" under community.aws or amazon.aws collection

Getting below error while running a playbook by making use of module "sts_assume_role" under community.aws or amazon.aws collection which is already installed on ansible server.
# Note: These examples do not set authentication details, see the AWS Guide for details.
name: testing assume role
user: ec2-user
hosts: localhost
gather_facts: true
collections:
community.aws.sts_assume_role
tasks:enter code here
Name: assume role
local_action:
sts_assume_role:
role_arn: "arn:aws:iam::123456789:role/test_iam_role"
role_session_name: "MySession"
register: assumed_role
run_once: True
Use the assumed role above to tag an instance in account 123456789
- name: sts token
local_action:
sts_assume_role:
aws_access_key: "{{ assumed_role.sts_creds.access_key }}"
aws_secret_key: "{{ assumed_role.sts_creds.secret_key }}"
security_token: "{{ assumed_role.sts_creds.session_token }}"
run_once: True
- Name: check current assume role
shell: aws sts get-caller-identity
PLease find attached picture for error.
Additional info:
Ansible version: 2.9.10
Boto3 version: 1.16.0
botocore version: 1.19.63
python version: 3.6.8

Using aws_secret in ansible

I'm trying to retrieve password from aws secret manager using ansible 2.8 using lookup.
Below things are not working for me:
In .bashrc, I have exported region
Ansible Environment Variables in task
Setting up ansible variables in pre_tasks
- hosts: StagingApps
remote_user: staging
gather_facts: false
tasks:
- debug:
var: "{{ lookup('aws_secret', 'staging_mongodb_pass', region='us-east-1') }}"
msg: "{{ query('aws_secret', 'staging_mongodb_pass', region='us-east-1') }}"
environment:
region: 'us-east-1'
Error Message:
FAILED! => {"msg": "An unhandled exception occurred while running the lookup plugin 'aws_secret'. Error was a , original message: 'Requested entry (plugin_type: lookup plugin: aws_secret setting: region ) was not defined in configuration.'"}
below playbook has worked for me
- name: "register mongodb from secretsmanager"
shell: "aws secretsmanager get-secret-value --secret-id staging_mongodb"
register: mongodb_pass
delegate_to: 127.0.0.1
- set_fact:
mongodb_pass_dict: "{{ mongodb_pass.stdout | from_json | json_query('SecretString') }}"
- set_fact:
mongodb_pass_list: "{{ ['staging_mongodb'] | map('extract', mongodb_pass_dict) | list }}"
- set_fact:
mongodb_pass: "{{ mongodb_pass_list[0] }}"
- template:
src: application.properties.j2
dest: application.properties
mode: 0644
backup: yes
It looks like Ansible released this lookup plugin in a broken state. They have an issue and a PR open to fix it:
https://github.com/ansible/ansible/issues/54790
https://github.com/ansible/ansible/pull/54792
Very disappointing, as I've been waiting for this plugin for many months.

Ansible add EC2 with add_host but connection gives missing Python error

I have used Ansible to create 1 AWS EC2 instance using the examples in the Ansible ec2 documentation. I can successfully create the instance with a tag. Then I temporarily add it to my local inventory group using add_host.
After doing this, I am having trouble when I try to configure the newly created instance. In my Ansible play, I would like to specify the instance by its tag name. eg. hosts: <tag_name_here>, but I am getting an error.
Here is what I have done so far:
My directory layout is
inventory/
staging/
hosts
group_vars/
all/
all.yml
site.yml
My inventory/staging/hosts file is
[local]
localhost ansible_connection=local ansible_python_interpreter=/home/localuser/ansible_ec2/.venv/bin/python
My inventory/staging/group_vars/all/all.yml file is
---
ami_image: xxxxx
subnet_id: xxxx
region: xxxxx
launched_tag: tag_Name_NginxDemo
Here is my Ansible playbook site.yml
- name: Launch instance
hosts: localhost
gather_facts: no
tasks:
- ec2:
key_name: key-nginx
group: web_sg
instance_type: t2.micro
image: "{{ ami_image }}"
wait: true
region: "{{ region }}"
vpc_subnet_id: "{{ subnet_id }}"
assign_public_ip: yes
instance_tags:
Name: NginxDemo
exact_count: 1
count_tag:
Name: NginxDemo
exact_count: 1
register: ec2
- name: Add EC2 instance to inventory group
add_host:
hostname: "{{ item.public_ip }}"
groupname: tag_Name_NginxDemo
ansible_user: centos_user
ansible_become: yes
with_items: "{{ ec2.instances }}"
- name: Configure EC2 instance in launched group
hosts: tag_Name_NginxDemo
become: True
gather_facts: no
tasks:
- ping:
I run this playbook with
$ cd /home/localuser/ansible_ec2
$ source .venv/bin/activate
$ ansible-playbook -i inventory/staging site.yml -vvv`
and this creates the EC2 instance - the 1st play works correctly. However, the 2nd play gives the following error
TASK [.....] ******************************************************************
The authenticity of host 'xx.xxx.xxx.xx (xx.xxx.xxx.xx)' can't be established.
ECDSA key fingerprint is XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.
Are you sure you want to continue connecting (yes/no)? yes
fatal: [xx.xxx.xxx.xx]: FAILED! => {"changed": false, "module_stderr":
"Shared connection to xx.xxx.xxx.xx closed.\r\n", "module_stdout": "/bin/sh:
1: /usr/bin/python: not found\r\n", "msg": "MODULE FAILURE", "rc": 127}
I followed the instructions from
this SO question to create the task with add_hosts
here to set gather_facts: False, but this still does not allow the play to run correctly.
How can I target the EC2 host using the tag name?
EDIT:
Additional info
This is the only playbook I have run to this point. I see this message requires Python but I cannot install Python on the instance as I cannot connect to it in my play Configure EC2 instance in launched group...if I could make that connection, then I could install Python (if this is the problem). Though, I'm not sure how to connect to the instance.
EDIT 2:
Here is my Python info on the localhost where I am running Ansible
I am running Ansible inside a Python venv.
Here is my python inside the venv
$ python --version
Python 2.7.15rc1
$ which python
~/ansible_ec2/.venv/bin/python
Here are my details about Ansible that I installed inside the Python venv
ansible 2.6.2
config file = /home/localuser/ansible_ec2/ansible.cfg
configured module search path = [u'/home/localuser/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /home/localuser/ansible_ec2/.venv/local/lib/python2.7/site-packages/ansible
executable location = /home/localuser/ansible_ec2/.venv/bin/ansible
python version = 2.7.15rc1 (default, xxxx, xxxx) [GCC 7.3.0]
Ok, so after a lot of searching, I found 1 possible workaround here. Basically, this workaround uses the lineinfile module and adds the new EC2 instance details to the hosts file permanently....not just for the in-memory plays following the add_host task. I followed this suggestion very closely and this approach worked for me. I did not need to use the add_host module.
EDIT:
The line I added in the lineinfile module was
- name: Add EC2 instance to inventory group
- lineinfile: line="{{ item.public_ip }} ansible_python_interpreter=/usr/bin/python3" insertafter=EOF dest=./inventory/staging/hosts
with_items: "{{ ec2.instances }}"

Installing Apache through Ansible

I am attempting to install Apache on an EC2 instance through Ansible. My playbook looks like this:
# Configure and deploy Apache
- hosts: localhost
connection: local
remote_user: ec2-user
gather_facts: false
roles:
- ec2_apache
- apache
The 'ec2_apache' role provisions an EC2 instance and the first task within the apache/main.yml looks like this:
- name: confirm using the latest Apache server
become: yes
become_method: sudo
yum:
name: httpd
state: latest
However, I am getting the following error:
"module_stderr": "sudo: a password is required\n"
I did take a look at: How to switch a user per task or set of tasks? but it did not seem to resolve my problem.
Because the configuration of the Ec2 instance is in one role and the installation of Apache is in another, did I hork up the security in some way?
The issue you've got is that your playbook that runs both roles is targeting localhost so your Apache role is trying to run sudo yum install httpd locally rather than on the target EC2 instance.
As the ec2 module docs example shows you need to use the add_host module to add your new EC2 instance(s) to a group that you can then target with a further play.
So your playbook might look something like this:
# Configure and deploy Apache
- name: provision instance for Apache
hosts: localhost
connection: local
remote_user: ec2-user
gather_facts: false
roles:
- ec2_apache
- name: install Apache
hosts: launched
remote_user: ec2-user
roles:
- apache
And then, as per the example in the ec2 module docs, just do something like this in your ec2_apache role:
- name: Launch instance
ec2:
key_name: "{{ keypair }}"
group: "{{ security_group }}"
instance_type: "{{ instance_type }}"
image: "{{ image }}"
wait: true
region: "{{ region }}"
vpc_subnet_id: subnet-29e63245
assign_public_ip: yes
register: ec2
- name: Add new instance to host group
add_host: hostname={{ item.public_ip }} groupname=launched
with_items: ec2.instances
- name: Wait for SSH to come up
wait_for: host={{ item.public_dns_name }} port=22 delay=60 timeout=320 state=started
with_items: ec2.instances
As an aside you can see quickly that your ec2_apache role is actually pretty generic and you could turn this into a generic ec2_provision role that all sorts of other things could use, helping you re-use your code.
This is what I did to install apache.
Based on #ydaetskcoR suggestion, all I added was connection: local to fix the following problems.
Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password,keyboard-interactive).", "unreachable": true}
See code below
---
- name: Install Apache and other packages
hosts: localhost
become: yes
connection: local
gather_facts: false
tasks:
- name: Install a list of packages with a list variable
yum:
name: "{{ packages }}"
state: latest
vars:
packages:
- httpd
- httpd-tools
- nginx
register: result
you also have to run your code as follows: -K stands for --ask-become-pass
ansible-playbook -i hosts.ini startapache.yml -K -vvv
Are you sure you are using ansible correctly and are you provindig a password for sudo on the remote host?
Just use --ask-become-pass when you execute the playbook. You should be prompted for the password.

Ansible Dynamic Inventory fails to get the latest ec2 information

I am using ec2.py dynamic inventory for provisioning with ansible.
I have placed the ec2.py in /etc/ansible/hosts file and marked it executable.
I also have the ec2.ini file in /etc/ansible/hosts.
[ec2]
regions = us-west-2
regions_exclude = us-gov-west-1,cn-north-1
destination_variable = public_dns_name
vpc_destination_variable = ip_address
route53 = False
all_instances = True
all_rds_instances = False
cache_path = ~/.ansible/tmp
cache_max_age = 0
nested_groups = False
group_by_instance_id = True
group_by_region = True
group_by_availability_zone = True
group_by_ami_id = True
group_by_instance_type = True
group_by_key_pair = True
group_by_vpc_id = True
group_by_security_group = True
group_by_tag_keys = True
group_by_tag_none = True
group_by_route53_names = True
group_by_rds_engine = True
group_by_rds_parameter_group = True
Above is my ec2.ini file
---
- hosts: localhost
connection: local
gather_facts: yes
vars_files:
- ../group_vars/dev_vpc
- ../group_vars/dev_sg
- ../hosts_vars/ec2_info
vars:
instance_type: t2.micro
tasks:
- name: Provisioning EC2 instance
local_action:
module: ec2
region: "{{ region }}"
key_name: "{{ key }}"
instance_type: "{{ instance_type }}"
image: "{{ ami_id }}"
wait: yes
group_id: ["{{ sg_npm }}", "{{sg_ssh}}"]
vpc_subnet_id: "{{ PublicSubnet }}"
source_dest_check: false
instance_tags: '{"Name": "EC2", "Environment": "Development"}'
register: ec2
- name: associate new EIP for the instance
local_action:
module: ec2_eip
region: "{{ region }}"
instance_id: "{{ item.id }}"
with_items: ec2.instances
- name: Waiting for NPM Server to come-up
local_action:
module: wait_for
host: "{{ ec2 }}"
state: started
delay: 5
timeout: 200
- include: ec2-configure.yml
Now the configuring script is as follows
- name: Configure EC2 server
hosts: tag_Name_EC2
user: ec2-user
sudo: True
gather_facts: True
tasks:
- name: Install nodejs related packages
yum: name={{ item }} enablerepo=epel state=present
with_items:
- nodejs
- npm
However when the configure script is called, the second script results into no hosts found.
If I execute the ec2-configure.yml just alone and if the EC2 server is up & running then it is able to find it and configure it.
I added the wait_for to make sure that the instance is in running state before the ec2-configure.yml is called.
Would appreciate if anyone can point my error. Thanks
After researching I came to know that the dynamic inventory doesnt refresh between playbook calls, it will only refresh if you are executing the playbook seprately.
However I was able to resolve the issue by using add_host command.
- name: Add Server to inventory
local_action: add_host hostname={{ item.public_ip }} groupname=webserver
with_items: webserver.instances
With ansible 2.0+, you refresh the dynamic inventory in the middle of the playbook as the task like this:
- meta: refresh_inventory
To extend this a bit, If you are getting problem with the cache in your playbook, then you can use it like this:
- name: Refresh the ec2.py cache
shell: "./inventory/ec2.py --refresh-cache"
changed_when: no
- name: Refresh inventory
meta: refresh_inventory
where ./inventory is the path to your dynamic inventory, please adjust it accordingly.
Hope this will help you.
Configure EC2 server play can't find any hosts from EC2 dynamic inventory because the new instance was added in the first play of the playbook - during the same execution. Group tag_Name_EC2 didn't exist in the inventory when the inventory was read and thus can't be found.
When you run the same playbook again Configure EC2 server should find the group.
We have used the following workaround to guide users in this kind of situations.
First, provision the instance:
tasks:
- name: Provisioning EC2 instance
local_action:
module: ec2
...
register: ec2
Then add a new play before ec2-configure.yml. The play uses ec2 variable that was registered in Provisioning EC2 instance and will fail and exit the playbook if any instances were launched:
- name: Stop and request a re-run if any instances were launched
hosts: localhost
gather_facts: no
tasks:
- name: Stop if instances were launched
fail: msg="Re-run the playbook to load group variables from EC2 dynamic inventory for the just launched instances!"
when: ec2.changed
- include: ec2-configure.yml
You can also refresh the cache:
ec2.py --refresh-cache
Or if your using as the Ansible host file:
/etc/ansible/hosts --refresh-cache