Ansible: Not able to get AMI ID of newly created AMI - amazon-web-services

I am using a playbook to create ami and trying to fetch the newly created ami id. But the debug is getting 'msg": "AMI not updated"'' Please help
- name: Create AMI
ec2_ami:
region: "{{ec2_region}}"
name: "aws-{{ec2_region}}"
state: present
instance_id: "{{ec2_info.instances.0.id}}"
wait: yes
tags:
Name: "aws-{{ec2_region}}-mr-ami"
deployment_type: "{{deployment_type}}"
pop_type: "{{pop_type}}"
register: image
- pause:
seconds: 10
- debug:
msg: "{{image}}"
- name: Set image id as fact
set_fact:
mr_ami_id: "{{image.image_id}}"
Playbook output
TASK [Create AMI]
*************************************************************************************************************************** ok: [localhost] => {
"changed": false,
"invocation": {
"module_args": {
"architecture": "x86_64",
"aws_access_key": null,
"aws_secret_key": null,
"delete_snapshot": false,
"description": "",
"device_mapping": null,
"ec2_url": null,
"image_id": null,
"instance_id": "i-065404d0d37e0acfb",
"kernel_id": null,
"launch_permissions": null,
"name": "aws-ap-southeast-2-MessageRelay",
"no_reboot": false,
"profile": null,
"region": "ap-southeast-2",
"root_device_name": null,
"security_token": null,
"state": "present",
"tags": {
"Name": "aws-ap-southeast-2-mr-ami",
"deployment_type": "dev",
"pop_type": "mgmt"
},
"validate_certs": true,
"virtualization_type": "hvm",
"wait": true,
"wait_timeout": "900"
}
},
"launch_permissions": {},
"msg": "AMI not updated" }
TASK [pause]
******************************************************************************************************************************** task path: /root/*********************/create_ami.yml:24 Pausing for 10 seconds (ctrl+C then 'C' = continue early, ctrl+C then 'A' = abort) ok: [localhost] => {
"changed": false,
"delta": 10,
"rc": 0,
"start": "2017-08-01 08:48:29.756546",
"stderr": "",
"stdout": "Paused for 10.0 seconds",
"stop": "2017-08-01 08:48:39.756843",
"user_input": "" }
TASK [debug]
******************************************************************************************************************************** task path: /root/*****************/create_ami.yml:27 ok: [localhost]
=> {
"changed": false,
"msg": {
"changed": false,
"launch_permissions": {},
"msg": "AMI not updated"
} }
TASK [Set image id as fact]
***************************************************************************************************************** task path: /root/***********/trunk/ncs/pop-deployment/********_asg/tasks/create_ami.yml:30 fatal: [localhost]: FAILED! => {
"failed": true,
"msg": "the field 'args' has an invalid value, which appears to include a variable that is undefined. The error was: 'dict object' has no attribute 'image_id'\n\nThe error appears to have been in '/root/**************************/create_ami.yml': line 30, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n- name: Set image id as fact\n ^ here\n" }
PLAY RECAP
********************************************************************************************************************************** ip-10-10-5-111.ap-southeast-2.compute.internal : ok=13 changed=9 unreachable=0 failed=0 localhost : ok=69 changed=31 unreachable=0 failed=1

This was happening because AMI with name "aws-{{ec2_region}}" was already there and hence no new ami was getting created. I deleted the old AMI and ran the playbook again without any issues.

Related

Ansible Filter String Output in Variable without ("

I want to use Ansible to backup license files from Swichten. But I have a problem. The idea is to write the output into a variable with ls *.lic. With this variable I want to copy a copy from the switch via tftp server to a computer. Everything should run fully automated so I try to do the same. I post below the playbook and the output. Then it will probably be clearer. Many thanks in advance.
I want to be clarify that i only want the output: (D3456234.lic) and not (
[
"D3456234.lic.lic"
]
as you can see below in the logs.
Playbook:
- name: copy license in home dir
os10_command:
commands:
- system "cp /mnt/license/*.lic /home/admin"
- name: create var
os10_command:
commands:
- "system ls"
register: licensevar
- debug:
var: licensevar
- name: backup license
os10_command:
commands:
- copy home://{{ licensevar.stdout }} tftp://10.x.x.xx/Sicherung/lizenz/{{
licensevar.stdout }}
-vvv ansible playbook run:
TASK [debug] *******************************************************************
ok: [hostname] => {
"licensevar.stdout": [
"DTH67C3.lic"
]
}
redirecting (type: action) dellemc.os10.os10_command to dellemc.os10.os10
TASK [backup license] **********************************************************
<10.0.0.81> ANSIBLE_NETWORK_IMPORT_MODULES: Result: {'changed': False, 'stdout': ["copy home://['D3456234.lic'] tftp://10.0.0.43/Sicherung/lizenz/['D3456234.li\x1bEc']\nFailed parsing URI filename"], 'stdout_lines': [["copy home://['D3456234.lic'] tftp://10.0.0.43/Sicherung/lizenz/['D3456234.li\x1bEc']", 'Failed parsing URI filename']], 'invocation': {'module_args': {'commands': ["copy home://['D3456234.lic'] tftp://10.0.0.43/Sicherung/lizenz/['D3456234.lic']"], 'match': 'all', 'retries': 10, 'interval': 1, 'wait_for': None, 'provider': None}}, '_ansible_parsed': True}
ok: [hostname] => {
"changed": false,
"invocation": {
"module_args": {
"commands": [
"copy home://['D3456234.lic'] tftp://10.0.0.43/Sicherung/lizenz/['D3456234.lic']"
],
"interval": 1,
"match": "all",
"provider": null,
"retries": 10,
"wait_for": null
}
},
"stdout": [
"copy home://['D3456234.lic'] tftp://10.0.0.43/Sicherung/lizenz/['D3456234.li\u001bEc']\nFailed parsing URI filename"
],
"stdout_lines": [
[
"copy home://['D3456234.lic'] tftp://10.0.0.43/Sicherung/lizenz/['D3456234.li\u001bEc']",
"Failed parsing URI filename"
]
]
}
META: ran handlers
META: ran handlers
I think it can be solve with regex.

Saving debug msg into variables list

I want to create multiple aws accounts at once and to save different output list into variables.
I tried with debug msg but maybe is not the proper option.
The idea is the following:
-
name: Create accounts.
hosts: localhost
vars_prompt:
- name: "tag_start"
prompt: "Please set the starting number for the account"
private: no
- name: "tag_end"
prompt: "Please set the ending number for the account"
private: no
tasks:
- name: "Emails"
debug:
msg: "test+{{item}}#gmail.com"
with_sequence: start={{ tag_start }} end={{ tag_end }}
register: email
- name: "Account name"
debug:
msg: "account{{item}}"
with_sequence: start={{ tag_start }} end={{ tag_end }}
register: account_name
- name: "Emails list"
debug:
msg: "{{email}}"
- name: "Account names"
debug:
msg: "{{account_name}}"
- name: Create AWS account
shell: >
aws organizations create-account --email "{{ item[0] }}" \
--account-name "{{ item[1] }}" \
--role-name admin \
--iam-user-access-to-billing ALLOW \
--profile default
with_together:
- "{{ email }}"
- "{{ account_name }}"
The point is that first and second task seems to work as expected showing only what I need like:
TASK [Emails] ********************************************************************************************************************************************************************************************************************************************************************************************************
task path: /Users/me/repos/create_aws_account.yaml:15
ok: [localhost] => (item=46) => {
"msg": "test+46#gmail.com"
}
ok: [localhost] => (item=47) => {
"msg": "test+47#gmail.com"
}
TASK [Account name] **************************************************************************************************************************************************************************************************************************************************************************************************
task path: /Users/me/create_aws_account.yaml:21
ok: [localhost] => (item=46) => {
"msg": "account46"
}
ok: [localhost] => (item=47) => {
"msg": "account47"
}
But when I check the output with another debug msg of the variables saved I get the following:
TASK [Emails] ********************************************************************************************************************************************************************************************************************************************************************************************************
task path: /Users/me/create_aws_account.yaml:27
ok: [localhost] => {
"msg": {
"changed": false,
"msg": "All items completed",
"results": [
{
"_ansible_ignore_errors": null,
"_ansible_item_label": "46",
"_ansible_item_result": true,
"_ansible_no_log": false,
"_ansible_verbose_always": true,
"changed": false,
"failed": false,
"item": "46",
"msg": "test+46#gmail.com"
},
{
"_ansible_ignore_errors": null,
"_ansible_item_label": "47",
"_ansible_item_result": true,
"_ansible_no_log": false,
"_ansible_verbose_always": true,
"changed": false,
"failed": false,
"item": "47",
"msg": "test+47#gmail.com"
}
]
}
}
TASK [Account names] *************************************************************************************************************************************************************************************************************************************************************************************************
task path: /Users/me/create_aws_account.yaml:31
ok: [localhost] => {
"msg": {
"changed": false,
"msg": "All items completed",
"results": [
{
"_ansible_ignore_errors": null,
"_ansible_item_label": "46",
"_ansible_item_result": true,
"_ansible_no_log": false,
"_ansible_verbose_always": true,
"changed": false,
"failed": false,
"item": "46",
"msg": "account46"
},
{
"_ansible_ignore_errors": null,
"_ansible_item_label": "47",
"_ansible_item_result": true,
"_ansible_no_log": false,
"_ansible_verbose_always": true,
"changed": false,
"failed": false,
"item": "47",
"msg": "account47"
}
]
}
}
So what can I do to save only the msg or stdout?
I tried also with set_fact but it seems to does not work either.
An option would be to create lists with set_fact
vars:
email: []
account_name: []
tasks:
- set_fact:
email: "{{ email }} + [ 'test{{ item }}#gmail.com' ]"
account_name: "{{ account_name }} + [ 'account{{ item }}' ]"
with_sequence: start="{{ tag_start }}" end="{{ tag_end }}"
Finally found what I was exactly looking for, and found it here, it is a reply from the user KaffeeKiffer. (The second reply).
Link
At the end is the following:
- set_fact:
emails: "{{ email.results | map(attribute='msg') | list }}"
- set_fact:
account_names: "{{ account_name.results | map(attribute='msg') | list }}"
For completeness sake: | list is required, because map will always return an iterator.

Ansible instance not appearing on AWS console

So I'm using Ansible on my MBP to try create key_pair and create/provision EC2 instances. Playbook runs fine with no error but when I check AWS console there is no new key and no new instance... Ping to supposedly created Public IP times out so I am thinking something failed. Ansible definitely hit AWS since if I disable the AWS access key then Ansible errors out, and not using the Ansible created key in the second task also fails so a key must have been created, just not uploaded to AWS?
Can you spot anything I did wrong?
Playbook yaml content:
- name: Create a sandbox instance
hosts: localhost
gather_facts: False
vars:
instance_type: t2.micro
image: ami-d1315fb1
region: us-west-1
tasks:
- name: Generate key
ec2_key:
name: ansible_key
region: "{{ region }}"
aws_access_key: #my_key
aws_secret_key: #my_key
state: present
- name: Launch instance
ec2:
key_name: ansible_key
group: default
instance_type: "{{ instance_type }}"
image: "{{ image }}"
wait: true
region: "{{ region }}"
aws_access_key: #my_key
aws_secret_key: #my_key
register: ec2
- name: Print all ec2 variables
debug: var=ec2
Playbook runs fine with output being:
PLAY [Create a sandbox instance] ***********************************************
TASK [Generate key] ************************************************************
ok: [localhost]
TASK [Launch instance] *********************************************************
changed: [localhost]
TASK [Print all ec2 variables] *************************************************
ok: [localhost] => {
"ec2": {
"changed": true,
"instance_ids": [
"i-0898f09f8d3798961"
],
"instances": [
{
"ami_launch_index": "0",
"architecture": "x86_64",
"block_device_mapping": {
"/dev/sda1": {
"delete_on_termination": true,
"status": "attached",
"volume_id": "vol-04e9c4c4f5d85e60d"
}
},
"dns_name": "ec2-54-215-253-115.us-west1.compute.amazonaws.com",
"ebs_optimized": false,
"groups": {
"sg-778b5711": "default"
},
"hypervisor": "xen",
"id": "i-0898f09f8d3798961",
"image_id": "ami-d1315fb1",
"instance_type": "t2.micro",
"kernel": null,
"key_name": "ansible_key",
"launch_time": "2017-08-16T16:57:09.000Z",
"placement": "us-west-1b",
"private_dns_name": "ip-172-31-29-166.us-west1.compute.internal",
"private_ip": "172.31.29.166",
"public_dns_name": "ec2-54-215-253-115.us-west1.compute.amazonaws.com",
"public_ip": "54.215.253.115",
"ramdisk": null,
"region": "us-west-1",
"root_device_name": "/dev/sda1",
"root_device_type": "ebs",
"state": "running",
"state_code": 16,
"tags": {},
"tenancy": "default",
"virtualization_type": "hvm"
}
],
"tagged_instances": []
}
}
PLAY RECAP *********************************************************************
localhost : ok=3 changed=1 unreachable=0 failed=0
Here are the few things:
- sure, you have selected the N.California(us-west-1) region from the console
- For private part of the key to store inside the .ssh under your username, do the following steps:
- name: Create an EC2 key
ec2_key:
name: "ansible_key"
region: "us-west-1"
aws_access_key: #my_key
aws_secret_key: #my_ke
register: ec2_key
- name: save private key
copy:
content: "{{ ec2_key.key.private_key }}"
dest: "/Users/{{lookup('env', 'USER')}}/.ssh/aws-private.pem"
mode: 0600
when: ec2_key.changed
Note: Run this playbook from the scratch to create new key and save it into your ~/.ssh directory.

How to get the access key with iam_module of Ansible?

I am using Ansible to create AWS users. One of the features of Ansible is to create a user with access key. I am wondering how could I get the access key after the user was successfully created.
http://docs.ansible.com/ansible/iam_module.html
tasks:
- name: Create two new IAM users with API keys
iam:
iam_type: user
name: "{{ item }}"
state: present
password: "{{ temp_pass }}"
access_key_state: create
with_items:
- user
I tried in 2.0.1.0. Should work in 2.0.0.2.
tasks:
- iam:
iam_type: user
name: foo
state: present
access_key_state: create
register: credentials
- debug: var=credentials
Output
[debug] *******************************************************************
ok: [127.0.0.1] => {
"credentials": {
"changed": false,
"groups": null,
"keys": {
"AKIAXXXXXXXXXXTTGFXX": "Active"
},
"user_name": "foo"
}
}
It is not possible to get the secret as of Ansible 2.0.1.0. It is a bug. See iam module not very useful for managing access keys
In the meantime (I am using Ansible 2.3.2.0) that issue was successfully fixed:
- name: Create restricted bot user to access S3
iam:
iam_type: user
name: blubaa
state: present
access_key_state: create
connection: local
register: credentials
- debug: var=credentials
Output:
ok: [XXXXXXXXXX] => {
"credentials": {
"changed": true,
"groups": null,
"keys": [
{
"access_key_id": "AKIAJXXXXXXXXXXZX6GQ",
"create_date": "2017-08-26T01:04:05Z",
"status": "Active",
"user_name": "blubaa"
}
],
"user_meta": {
"access_keys": [
{
"access_key_id": "AKIAJXXXXXXXXXXZX6GQ",
"access_key_selector": "XXXX",
"create_date": "2017-08-26T01:04:05.720Z",
"secret_access_key": "wPwd2H0XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXkHB08Elo",
"status": "Active",
"user_name": "blubaa"
}
],
"created_user": {
"arn": "arn:aws:iam::30XXXXXXXXXX:user/blubaa",
"create_date": "2017-08-26T01:04:05.557Z",
"path": "/",
"user_id": "AIDAXXXXXXXXXXOYT7M",
"user_name": "blubaa"
},
"password": null
}
}
}

ansible add host to route53

i am using ansible to provision servers on ec2, after creating the server i would like to create a host entry on route53 zone
---
- hosts: all
connection: local
tasks:
- name: create ec2 instance
action:
module: ec2
zone: "{{ zone }}"
image: "{{ image }}"
instance_type: "{{instance_type}}"
region: "{{ region }}"
vpc_subnet_id: "{{ subnet }}"
group: "{{ security_group }}"
key_name: "{{ sshkey }}"
instance_tags:
Name: "{{inventory_hostname}}"
Environment: "{{ Environment }}"
Date: "{{ Date}}"
Noderole: "{{ NodeRole }}"
ConfigurationGroup: "{{ ConfigurationGroup}}"
Backups: "{{ Backups }}"
count_tag:
Name: "{{inventory_hostname}}"
exact_count: 1
- name: Ensure DNS entry exists
action:
module: route53
command: create
overwrite: "yes"
record: "{{ inventory_hostname }}.{{ server_zone }}"
type: A
zone: "{{ server_zone }}"
value: "{{ item.private_ip }}"
with_items: "ec2.instances"
the attributes, "inventory_hostname" , "server_zone" are defined in the inventory files for the hosts so they work when the EC2 instance is created.
[kshk:~/testing/ansible-ec2] master* ± ansible-playbook -i inventory/development/devcm_q/inventory.ini create-ec2-instance.yml --limit dcm-jmp-09 -v
PLAY [all] ********************************************************************
GATHERING FACTS ***************************************************************
ok: [dcm-jmp-09]
TASK: [create ec2 instance] ***************************************************
changed: [dcm-jmp-09] => {"changed": true, "instance_ids": ["i-7c9e89f1"], "instances": [{"ami_launch_index": "0", "architecture": "x86_64", "dns_name": "", "ebs_optimized": false, "groups": {"sg-0bf7d96f": "dev-jumpbox"}, "hypervisor": "xen", "id": "i-7c9e89f1", "image_id": "ami-33734044", "instance_type": "t2.micro", "kernel": null, "key_name": "bootstrap", "launch_time": "2016-02-21T04:28:38.000Z", "placement": "eu-west-1c", "private_dns_name": "ip-172-31-8-55.eu-west-1.compute.internal", "private_ip": "172.31.8.55", "public_dns_name": "", "public_ip": null, "ramdisk": null, "region": "eu-west-1", "root_device_name": "/dev/sda1", "root_device_type": "ebs", "state": "pending", "state_code": 0, "tags": {}, "tenancy": "default", "virtualization_type": "hvm"}], "tagged_instances": [{"ami_launch_index": "0", "architecture": "x86_64", "dns_name": "", "ebs_optimized": false, "groups": {"sg-0bf7d96f": "dev-jumpbox"}, "hypervisor": "xen", "id": "i-7c9e89f1", "image_id": "ami-33734044", "instance_type": "t2.micro", "kernel": null, "key_name": "bootstrap", "launch_time": "2016-02-21T04:28:38.000Z", "placement": "eu-west-1c", "private_dns_name": "ip-172-31-8-55.eu-west-1.compute.internal", "private_ip": "172.31.8.55", "public_dns_name": "", "public_ip": null, "ramdisk": null, "region": "eu-west-1", "root_device_name": "/dev/sda1", "root_device_type": "ebs", "state": "pending", "state_code": 0, "tags": {}, "tenancy": "default", "virtualization_type": "hvm"}]}
TASK: [Ensure DNS entry exists] ***********************************************
fatal: [dcm-jmp-09] => One or more undefined variables: 'unicode object' has no attribute 'private_ip'
FATAL: all hosts have already failed -- aborting
PLAY RECAP ********************************************************************
to retry, use: --limit #/home/kshk/create-ec2-instance.retry
dcm-jmp-09
however, when the playbook is run, it throws up the error "no attribute 'private_ip"
any ideas?
You are not registering ec2. How do you expect ec2.instances to contain private_ip?
- name: create ec2 instance
action:
module: ec2
zone: "{{ zone }}"
.....
exact_count: 1
register: ec2
- name: Ensure DNS entry exists
action:
module: route53
....
zone: "{{ server_zone }}"
value: {{ item.private_ip }}
with_items: ec2.instances