Juniper Software upgrade faills cause of not enough space - ansible

I've tried to update a EX2300 switch from Juniper with the ansible module(juniper_junos_software) but eveytime i tried it fails cause it doesn't have enough space and i tried a bunch of stuff all from trying to SCP with other Ansible modules such as (net_put and junipernetworks.junos.junos_scp) which to no relief i can't get to work either
The Ansible code is:
- name: Install Junos OS
hosts: EX
roles:
- Juniper.junos
connection: local
gather_facts: no
vars:
OS_version: "20.4R1.12"
OS_package: "junos-arm-32-20.4R1.12.tgz"
pkg_dir: "/etc/JunOS"
log_dir: "/var/log"
netconf_port: 830
wait_time: 3600
tasks:
- name: Checking NETCONF connectivity
wait_for:
host: "{{ inventory_hostname }}"
port: "{{ netconf_port }}"
timeout: 5
- name: Clean up the device
juniper_junos_command:
commands:
- request system snapshot delete snap*
- request system software delete jweb
timeout: 200
register: response
- name: Print response from Clean up the device
debug:
var: response
- name: Install Junos OS package
juniper_junos_software:
version: "{{ OS_version }}"
local_package: "{{ pkg_dir }}/{{ OS_package }}"
cleanfs: yes
validate: no
reboot: true
logfile: "{{ log_dir }}/ansible.log"
register: sw
notify:
- wait_reboot
- name: Print response
debug:
var: response
- name: Snapshot Slice alternate
juniper_junos_command:
commands: request system snapshot slice alternate
timeout: 200
register: response
handlers:
- name: wait_reboot
wait_for:
host: "{{ inventory_hostname }}"
port: "{{ netconf_port }}"
timeout: "{{ wait_time }}"
when: not sw.check_mode
The error i get is:
"changed": true,
"check_mode": false,
"invocation": {
"module_args": {
"attempts": null,
"baud": null,
"checksum": null,
"checksum_algorithm": "md5",
"checksum_timeout": 300,
"cleanfs_timeout": 300,
"console": null,
"cs_passwd": null,
"cs_user": null,
"force_host": false,
"host": "10.15.84.100",
"issu": false,
"level": null,
"logdir": null,
"logfile": "/var/log/ansible.log",
"mode": null,
"nssu": false,
"passwd": null,
"port": 830,
"provider": null,
"ssh_config": null,
"ssh_private_key_file": "/etc/ansible/ssh-keys/id_ed25519",
"timeout": 30,
"user": "ansible",
"validate": false,
"vmhost": false
}
},
"msg": [
"Unable to install the software %s",
"\nERROR: estimate of space required: 119 Mbytes, available: 41 Mbytes\n"
]
}

"space required: 119 Mbytes, available: 41 Mbytes" indicates you need to delete some files, usually image files.

Related

Schedule deletion of unused template

In Ansible Tower, is there a possibility to create a scheduled task that checks if a template has not been executed for one year and if so, deletes it?
The short answers is: yes, of course. The long answer is: someone has to create such task. To do so, one may getting familiar with the Ansible Tower REST API, in detail Job Templates - List Jobs for a Job Template.
In example, a call for Jobs of a Job Template which was never executed
curl --silent --user ${ACCOUNT}:${PASSWORD} https://${TOWER_URL}/api/v2/job_templates/${ID}/jobs/ --write-out "\n%{http_code}\n"| jq .
would result into an output of
{
"count": 0,
"next": null,
"previous": null,
"results": []
}
200
A call for Jobs of a Job Template which is executed daily would result into an output of
{
"count": 70,
"next": "/api/v2/job_templates/<id>/jobs/?page=2",
"previous": null,
"results": [
{
"id": <id>,
<snip>
"created": "2022-06-10T05:57:18.976798Z",
"modified": "2022-06-10T05:57:19.666354Z",
"name": "<name>",
"description": "<description>",
"unified_job_template": <id>,
"launch_type": "manual",
"status": "successful",
"failed": false,
"started": "2022-06-10T05:57:19.870208Z",
"finished": "2022-06-10T05:57:33.752072Z",
"canceled_on": null,
"elapsed": 13.882,
"job_explanation": "",
"execution_node": "<executionNode>",
"controller_node": "",
"job_type": "run",
"inventory": <id>,
"project": <id>,
"playbook": "<path>",
"scm_branch": "",
"forks": 0,
"limit": "<hostgroup>",
"verbosity": 0,
"extra_vars": "{\"if_there_any\": \"false\"}",
"job_tags": "check",
"force_handlers": false,
"skip_tags": "",
"start_at_task": "",
"timeout": 0,
"use_fact_cache": false,
"organization": <id>,
"job_template": <id>,
"passwords_needed_to_start": [
"ssh_password"
],
"allow_simultaneous": false,
"artifacts": {},
"scm_revision": "<rev>",
"instance_group": 1,
"diff_mode": false,
"job_slice_number": 0,
"job_slice_count": 1,
"webhook_service": "",
"webhook_credential": null,
"webhook_guid": ""
}
]
}
200
Since the goal is to execute it via Ansible Engine, as well schedule via Ansible Tower, a sample rest.yml playbook
---
- hosts: localhost
become: false
gather_facts: false
vars:
TOWER_API_URL: "<tower_url>/api/v2"
FILTER: ".version"
ID: "<id>"
tasks:
- name: Example REST API call
shell:
cmd: curl --silent -u '{{ ansible_user }}:{{ ansible_password }}' --location {{ TOWER_API_URL }}/ping | jq {{ FILTER }}
warn: false
register: result
failed_when: result.rc != 0
changed_when: false
check_mode: false
- name: Show result
debug:
msg: "{{ result.stdout }}"
- name: List Jobs for a Job Template
uri:
url: "https://{{ TOWER_API_URL }}/job_templates/{{ ID }}/jobs/"
user: "{{ ansible_user }}"
password: "{{ ansible_password }}"
force_basic_auth: true
method: GET
validate_certs: yes
return_content: yes
status_code: 200
body_format: json
check_mode: false
register: result
- name: Show result
debug:
msg: "{{ result.json.results }}" # list of jobs
which can be called from CLI via
sshpass -p ${PASSWORD} ansible-playbook --user ${ACCOUNT} --ask-pass rest.yml
Please take note that the "count": 70 is greater than the result set result.json.results | length of 25 and there is a next page mentioned "next": "...?page=2". The result.json.results | last therefore does not contain the most recent execution. This is because of Pagination.
Depending on the setup and actual configuration of Ansible Tower one may need to adjust the page_size. In example to get the most recent result
...
url: "https://{{ TOWER_API_URL }}/job_templates/{{ ID }}/jobs/?page_size=100"
...
msg: "{{ result.json.results | last }}"

Create a dynamic list of vmware datastore using Ansible playbook

I'm trying to create a list of vmware datastores using Ansible playbook and later use it to create a VM . I'm new to Ansible playbook. Appreciate any help!
I'm getting the info using vmware_datastore_info as shown below.
"info.datastores": [
{
"accessible": true,
"capacity": 4397778075648,
"datastore_cluster": "N/A",
"freeSpace": 4192023347200,
"maintenanceMode": "normal",
"multipleHostAccess": true,
"name": "DDA-san010-L10",
"provisioned": 219122982172,
"type": "VMFS",
"uncommitted": 13368253724,
},
{
"accessible": true,
"capacity": 4397778075648,
"datastore_cluster": "N/A",
"freeSpace": 4134386270208,
"maintenanceMode": "normal",
"multipleHostAccess": true,
"name": "DDA-san011-L11",
"provisioned": 279761501112,
"type": "VMFS",
"uncommitted": 16369695672,
},
{
.......................
}
now I need to capture the above info in a list of dictionary items so that I can use the name of the datastore using the freespace to allocate the datastore for a new vm.
the playbook that I'm using to gather the info is give below
---
- name: Gather info from standalone ESXi server having datacenter as 'LAB'
hosts: localhost
gather_facts: false
vars_files:
- /data/password.yml
- /data/windows/lab_vars.yml
tasks:
- name: Collect info regarding datastore
vmware_datastore_info:
hostname: '{{ vcenter_server }}'
username: '{{ username }}'
password: '{{ password }}'
datacenter_name: '{{ datacenter_name }}'
validate_certs: false
delegate_to: localhost
register: info
- debug: var=info.datastores
I was able to figure this out. Below is the additional code.
set_fact:
datastore: "{{ datastore + [{ 'Name': item.name, 'Cluster': item.datastore_cluster, 'Capacity': item.capacity, 'Freespace': item.freeSpace, 'Provisioned': item.provisioned , 'Accessible': item.accessible }] }}"
with_items:
- "{{ info.datastores }}"
Now the next step is to find the datastore that has the least amount of space to fit the server.

Creating IAM users with Ansible - getting the CLI credentials

I am create usernames with the iam module, and I am using the access_key_state: create option.
However, I want my playbook to output the Access Key and the Secret Access Key for each user.
playbook.yml:
---
- name: "Starting the tasks: Creates IAM Policy, group, Role and User"
hosts: localhost
connection: local
gather_facts: False
vars_files:
- vars/aws-credentials.yml
tasks:
- include: tasks/create-user.yml
tags: user
- include: tasks/create-group.yml
tags: group
tasks/create-user.yml:
---
# Create the IAM users with Console and API access
- name: Create new IAM users with API keys and console access
iam:
iam_type: user
name: "{{ item }}"
state: present
password: "{{ lookup('password', 'passwordfile chars=ascii_letters') }}"
access_key_state: create
update_password: on_create
no_log: true
register: newusers
loop:
- johna
- mariab
- carlosc
- name: test
debug:
msg: "{{ credentials.results }}"
The debug message "{{ credentials.results }}" gives me the Access Key, but not the Secret Access Key:
{
"ansible_loop_var": "item",
"changed": true,
"created_keys": [],
"failed": false,
"groups": null,
"invocation": {
"module_args": {
"access_key_ids": null,
"access_key_state": "create",
"aws_access_key": null,
"aws_secret_key": null,
"debug_botocore_endpoint_logs": false,
"ec2_url": null,
"groups": null,
"iam_type": "user",
"key_count": 1,
"name": "carol.v",
"new_name": null,
"new_path": null,
"password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
"path": "/",
"profile": null,
"region": null,
"security_token": null,
"state": "present",
"trust_policy": null,
"trust_policy_filepath": null,
"update_password": "always",
"validate_certs": true
}
},
"item": "carlosc",
"keys": {
"AK_________FV": "Active"
},
"user_meta": {
"access_keys": [
{
"access_key_id": "AK_________FV",
"status": "Active"
}
]
},
"user_name": "carlosc"
}
How to get the Secret Access Key for each user?
Update 09 May 2020: For further reference.
Bad news; it appears they are purposefully throwing the secret_access_key in the trash: https://github.com/ansible/ansible/blob/v2.9.7/lib/ansible/modules/cloud/amazon/iam.py#L238-L241
It appears the only way around that is to set key_count: 0 in your iam: and then use awscli or a custom ansible module to make that same iam.create_access_key call and preserve the result
- name: create access key for {{ item }}
command: aws iam create-access-key --user-name {{ item }}
environment:
AWS_REGION: '{{ the_region_goes_here }}'
AWS_ACCESS_KEY_ID: '{{ whatever_you_called_your_access_key }}'
AWS_SECRET_ACCESS_KEY: '{{ your_aws_secret_access_key_name_here }}'
register: user_keys
with_items:
- johna
- mariab
- carlosc
Feel free to file an issue, although you'll likely have to file it against the new amazon.aws collection since that iam.py is no longer present in the devel branch
You can use community.aws.iam:
- name: Create IAM User with API keys
community.aws.iam:
iam_type: user
name: some_dummy_user
state: present
access_key_state: create
register: new_user
- debug:
var: new_user
You'll be able to get your access and secret keys at:
new_user.user_meta.access_keys[0].access_key_id
new_user.user_meta.access_keys[0].secret_access_key
I have mine getting loaded into Secrets Manager and will eventually have them rotated with a lambda function.

Error in ovirt_disk module via ansible AWX

I'm getting below wired error when trying to add disk to RHVM. I have checked in the documentation. all parameters seems legit to me. I need extra eye to valiate this case. thank you in-advanced
error msg as follows
"msg": "Unsupported parameters for (ovirt_disk) module: activate Supported parameters include: auth, bootable, description, download_image_path, fetch_nested, force, format, id, image_provider, interface, logical_unit, name, nested_attributes, openstack_volume_type, poll_interval, profile, quota_id, shareable, size, sparse, sparsify, state, storage_domain, storage_domains, timeout, upload_image_path, vm_id, vm_name, wait"
}
Parameters in the role as follows
"module_args": {
"vm_name": "Jxyxyxyxy01",
"activate": true,
"storage_domain": "Data-xxx-Txxx",
"description": "Created using Jira ticket CR-329",
"format": "cow",
"auth": {
"timeout": 0,
"url": "https://xxxxxx.com/ovirt-engine/api",
"insecure": true,
"kerberos": false,
"compress": true,
"headers": null,
"token": "xxcddsvsdvdsvsdvdEFl0910KES84qL8Ff5NReA",
"ca_file": null
},
"state": "present",
"sparse": true,
"interface": "virtio_scsi",
"wait": true,
"size": "20GiB",
"name": "Jxyxyxyxy01_123"
}
Playbook as follows.
- name: Create New Disk size of {{ disk_size }} on {{ hostname }} using storage domain {{ vm_storage_domain }}
ovirt_disk:
auth: "{{ ovirt_auth }}"
description: "Created using Jira ticket {{ issueKey }}"
storage_domain: "{{ vm_storage_domain }}"
name: "{{ hostname }}_123" # name of the disk
vm_name: "{{ hostname }}" #name of the virtual machine
interface: "virtio_scsi"
size: "{{ disk_size }}GiB"
sparse: yes
format: cow
activate: yes
wait: yes
state: present
register: vm_disk_results
The activate parameter was added in ansible 2.8.
Upgrade your ansible installation or drop that parameter.

Cant get the private ip from an EC2 result

Trying to create a playbook that will let me choose if i want spot or On-demand EC2 with passing external var, all going fine except the part of getting the private ip from the result and settings it as fact for further usage.
i've tried different paths like item.instances[0].private_ip
and just cant seems to get the right one.
---
- hosts: localhost
tasks:
- name: when true
ec2:
region: us-east-1
instance_type: t2.nano
key_name: test_key
instance_type: t2.micro
image: ami-0aec0138b2*****
wait: yes
count: 1
vpc_subnet_id: subnet-00fdda1452d****
assign_public_ip: no
spot_price: 1
register: ci_ec2_true
when: var == "true"
- name: when false
ec2:
region: us-east-1
instance_type: t2.nano
key_name: test_key
instance_type: t2.micro
image: ami-0aec0138b2****
wait: yes
count: 1
vpc_subnet_id: subnet-00fdda1452d0****
assign_public_ip: no
register: ci_ec2_false
when: var == "false"
- name: ci_ec2_true
debug:
msg: "{{ ci_ec2_true }}"
- name: Spot / On-demand var router
set_fact:
ci_ec2: "{{ ci_ec2_true if ci_ec2_false is skipped else ci_ec2_false }}"
- name: debug ci_ec2
debug:
msg: "{{ ci_ec2 }}"
- name: ec2_prov - set fact for all ci_machine_ips
set_fact: private_ips="{{ item.instances[0].private_ip }}"
with_items: "{{ ci_ec2 }}"
register: ci_ec2_ip_results
- debug:
msg: "{{ ci_ec2_ip_results }}"
The expected result should be the private ip value, instead im getting this error:
TASK [ec2_prov - set fact for all ci_machine_ips] ******************************
**********
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: 'ansible.vars.unsafe_proxy.AnsibleUnsafeText object' has no attribute 'instances'\n\nThe error appears to have been in '/root/test/when-create.yml': line 50, column 5, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n - name: ec2_prov - set fact for all ci_machine_ips\n ^ here\n"}
the command used to run the playbook is:
ansible-playbook when-create.yml -e var=true
TASK [debug ci_ec2] ************************************************************
ok: [localhost] => {
"msg": {
"changed": true,
"instance_ids": [
"i-0485794cd8a299b27"
],
"instances": [
{
"ami_launch_index": "0",
"architecture": "x86_64",
"block_device_mapping": {
"/dev/xvda": {
"delete_on_termination": true,
"status": "attached",
"volume_id": "vol-0cd42f8696aef9bbd"
}
},
"dns_name": "",
"ebs_optimized": false,
"groups": {
"sg-07c7177c": "default"
},
"hypervisor": "xen",
"id": "i-0485794cd8a299b27",
"image_id": "ami-0aec0138b2a5****",
"instance_type": "t2.micro",
"kernel": null,
"key_name": "test_Key",
"launch_time": "2019-05-11T16:41:10.000Z",
"placement": "us-east-1a",
"private_dns_name": "ip-10-220-129-224.ec2.internal",
"private_ip": "10.220.129.224",
"public_dns_name": "",
"public_ip": null,
"ramdisk": null,
"region": "us-east-1",
"root_device_name": "/dev/xvda",
"root_device_type": "ebs",
"state": "running",
"state_code": 16,
"tags": {
"Created_By": "InstanceLaunch"
},
"tenancy": "default",
"virtualization_type": "hvm"
}
],
"tagged_instances": []
}
}
so eventually i found the way...
- name: ec2_prov - set fact for all ci_machine_ips
set_fact: private_ips="{{ item.private_ip }}"
with_items: "{{ ci_ec2.instances }}"
register: ci_ec2_ip_results

Resources