Ansible apt module - "unsupported parameter for module: “name" - ansible

Ansible version 2.1.2.0 (homebrew, macOS - having removed any previous versions)
ansible myserver -m apt -a “name=backup2l,state=present” --ask-pass
returns this error:
myserver | FAILED! => {
"changed": false,
"failed": true,
"msg": "unsupported parameter for module: “name"
}
This seems the correct syntax according to the examples:
# Install the package "foo"
- apt: name=foo state=present
I've tried wrapping the values for name and state in single quotes, also using a space between the parameters (it doesn't like that – "ERROR! Missing target hosts").
Any ideas?

ansible arguments are seperated by spaces like a command line, not a function call.
Try:
ansible myserver -m apt -a “name=backup2l state=present” --ask-pass

Due to using “smart quotes” rather than "regular quotes", which was caused by typing a command out in my notes application first then copying and pasting into iTerm.
NB: the error message you get depends on what you're trying to do - if you're running a single command with -a, Ansible will say "No such file or directory".
Solution for Mac users:
System Preferences > Keyboard > Text > uncheck "Use smart quotes and dashes".
Vote for this if you like: iTerm2 feature request

Related

Run mysqlsh commands in Ansible playbook

I would like to create a mysql innodb cluster. SO I want to run the mysql shell commands in ansible playbook. But getting memory error. Below are the code and error-
tasks:
- name: get cluster status from dbboxes
shell: mysqlsh test123:test123#box1:3306 -e "createCluster('test_cluster')"
Execution error as below-
The full traceback is:
Traceback (most recent call last):  File
"/tmp/ansible_command_payload__lbu2_tp/ansible_command_payload.zip/ansible/module_utils/basic.py", line 2724, in run_command    stdout += b_chunk
MemoryError
fatal: [localhost]: FAILED! => {    "changed": false,    "cmd": "/u01/mysql/8.0/bin/mysqlsh --uri 'test123:********#box1:3306' -e 'var cluster=dba.createCluster('\"'\"'test_cluster'\"'\"')'",    "invocation": {        "module_args": {            "_raw_params": "/u01/mysql/8.0/bin/mysqlsh --uri test123:test123#box1:3306 -e \"var cluster=dba.createCluster('test_cluster')\"",            "_uses_shell": true,            "argv": null,            "chdir": null,            "creates": null,            "executable": null,            "removes": null,            "stdin": null,            "stdin_add_newline": true,            "strip_empty_ends": true,            "warn": true        }    },    "msg": "",    "rc": 257
}
Kindly suggest any better approach for this

Run ansible-lint through subdirectories within a gitlab role

I am trying to add a validation step to a gitlab repo holding a single ansible role (with no playbook).
The structure of the role looks like :
.gitlab-ci.yml
tasks/
templates/
files/
vars/
handlers/
With the gitlab-ci looking like :
stages:
- lint
job-lint:
image:
name: cytopia/ansible-lint:latest
entrypoint: ["/bin/sh", "-c"]
stage: lint
script:
- ansible-lint --version
- ansible-lint . -x 106 tasks/*.yml
I need to skip the naming rule, thus ignoring rule 106.
Otherwise, I would like all files at the root repo to be checked. Since there is no playbook, lint has to be given the files that need to be checked... or at least, that is what I understoodd : I may have this point wrong. But anyway, if I give no name, lint does return ok but actually performs no check.
My problem is that I don't know how to tell him to check all the yaml in a recursive way, or even within a subdirectory. The above code returns an error :
ansible-lint: error: unrecognized arguments: tasks/deploy.yml tasks/localhost.yml tasks/main.yml tasks/managedata.yml tasks/psqlconf.yml
Any idea on how to check all the files from a subdirectory or through the whole role?
PS : I am using cytopia image for ansible-lint, but I have no problem using another, provided it's hosted on dockerhub.
You should certainly be able to pass multiple YAML files as arguments to ansible-lint. I have version 4.1.1a0, and I'm able to use it like this, for example:
anisble-lint -x 106 roles/*/tasks/*.yml
I notice that you seem to have placed a . before your -x 106; that looks like an error. It doesn't look like ansible-lint will accept a directory name as an argument (it doesn't cause it to fail; it just doesn't accomplish anything).
I've tried this both with a locally installed ansible-lint and using the cytopia/ansible-lint image, which appears to perform identically:
docker run --rm -v $PWD:/src -w /src cytopia/ansible-lint -x 106 roles/*/tasks/*.yml
If you want to check all the yaml files, you can use find with exec option, something like this:
find ./ -not -name ".gitlab-ci.yml" -name "*.yml" | xargs ansible-lint -x 106
However ansible-lint -x 106 ./ should work, are you sure that your role really has errors? I've tested it both on ansible-galaxy init generated roles (with meta and all that stuff) and roles which were containing only tasks directory, and it worked every time.
EDIT: I tried creating an error in existing role, replacing "present" with "latest" in package install task
$ ansible-galaxy install geerlingguy.nfs
$ cd ~/.ansible/roles/geerlingguy.nfs
$ sed -i "s/present/latest/g" tasks/setup-RedHat.yml
$ ansible-lint ./
Examining tasks/main.yml of type tasks
Examining tasks/setup-Debian.yml of type tasks
Examining tasks/setup-RedHat.yml of type tasks
Examining handlers/main.yml of type handlers
Examining meta/main.yml of type meta
[403] Package installs should not use latest
tasks/setup-RedHat.yml:2
Task/Handler: Ensure NFS utilities are installed.
and it actually worked, so you may want to run a verbose output to see if actually works, maybe individual yaml file rules are different from whole roles.
When i ran my find-based check i got a lot of extra [204] Lines should be no longer than 160 chars

Installing composer programatically working on vagrant but not on EC2 instance

I'm working on Ansible playbook.
When provisioning on a vagrant machine, it goes well, without errors.
Right now I'm on a trouble on the step where composer is installed programatically.
install-composer.sh (This script has been taken from Composer Page)
#!/bin/sh
EXPECTED_SIGNATURE="$(wget -q -O - https://composer.github.io/installer.sig)"
echo $EXPECTED_SIGNATURE;
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
ACTUAL_SIGNATURE="$(php -r "echo hash_file('sha384', 'composer-setup.php');")"
echo $ACTUAL_SIGNATURE; <- Here is empty!
if [ "$EXPECTED_SIGNATURE" != "$ACTUAL_SIGNATURE" ]
then
>&2 echo 'ERROR: Invalid installer signature'
rm composer-setup.php
exit 1
fi
php composer-setup.php --quiet
RESULT=$?
rm composer-setup.php
exit $RESULT
The EC2 is a Ubuntu 16.04 instance, on vagrant as well.
Playbook task where i'm getting the error:
- name: Download Composer
script: scripts/install_composer.sh
register: composer_setup
#when: not composer_stat.stat.exists
tags:
- deploy
And the full error with --verbose:
TASK [Download Composer] *******************************************************
fatal: [18.203.185.87]: FAILED! => {"changed": true, "failed": true,
"rc": 1, "stderr": "Shared connection to 18.203.185.87 closed.\r\n",
"stdout":
"a5c698ffe4b8e849a443b120cd5ba38043260d5c4023dbf93e1558871f1f07f58274fc6f4c93bcfd858c6bd0775cd8d1\r\n/home/ubuntu/.ansible/tmp/ansible-tmp-1566333565.4-174304924088429/install_composer.sh:
5:
/home/ubuntu/.ansible/tmp/ansible-tmp-1566333565.4-174304924088429/install_composer.sh:
php: not
found\r\n/home/ubuntu/.ansible/tmp/ansible-tmp-1566333565.4-174304924088429/install_composer.sh:
6:
/home/ubuntu/.ansible/tmp/ansible-tmp-1566333565.4-174304924088429/install_composer.sh:
php: not found\r\n\r\nERROR: Invalid installer signature\r\nrm: cannot
remove 'composer-setup.php': No such file or directory\r\n",
"stdout_lines":
["a5c698ffe4b8e849a443b120cd5ba38043260d5c4023dbf93e1558871f1f07f58274fc6f4c93bcfd858c6bd0775cd8d1",
"/home/ubuntu/.ansible/tmp/ansible-tmp-1566333565.4-174304924088429/install_composer.sh:
5:
/home/ubuntu/.ansible/tmp/ansible-tmp-1566333565.4-174304924088429/install_composer.sh:
php: not found",
"/home/ubuntu/.ansible/tmp/ansible-tmp-1566333565.4-174304924088429/install_composer.sh:
6:
/home/ubuntu/.ansible/tmp/ansible-tmp-1566333565.4-174304924088429/install_composer.sh:
php: not found", "", "ERROR: Invalid installer signature", "rm: cannot
remove 'composer-setup.php': No such file or directory"]} changed:
[192.168.33.10] => {"changed": true, "rc": 0, "stderr": "Shared
connection to 192.168.33.10 closed.\r\n", "stdout":
"a5c698ffe4b8e849a443b120cd5ba38043260d5c4023dbf93e1558871f1f07f58274fc6f4c93bcfd858c6bd0775cd8d1\r\na5c698ffe4b8e849a443b120cd5ba38043260d5c4023dbf93e1558871f1f07f58274fc6f4c93bcfd858c6bd0775cd8d1\r\n",
"stdout_lines":
["a5c698ffe4b8e849a443b120cd5ba38043260d5c4023dbf93e1558871f1f07f58274fc6f4c93bcfd858c6bd0775cd8d1",
"a5c698ffe4b8e849a443b120cd5ba38043260d5c4023dbf93e1558871f1f07f58274fc6f4c93bcfd858c6bd0775cd8d1"]}
Any idea why this line is returning empty on ec2?
"$(php -r "echo hash_file('sha384', 'composer-setup.php');")"
Thanks!
My first guess is that your EC2 instance doesn't have access to the internet. Can you verify this? The verbose logs indicate that the composer-setup.php file does not exist when you're trying to hash it. You should try downloading that file using the current copy() method, then doing something like:
TESTSTUFF="$(php -r "echo file_exists('composer-setup.php') ? 'FILE EXISTS' : 'FILE DOES NOT EXIST';")"
echo $TESTSTUFF
If the file does not exist, try to download a different file from somewhere, such as a dummy test file from here.
All of the signs point to the file not existing, which can caused by an array of issues. But, the most likely are:
No internet access on EC2 (Can you ping 8.8.8.8?)
Improper permissions to execute php
Improper permissions to write to the destination filesystem
After Trying what Aaron Said, I saw that php was not correctly installed(not installed at all)
I was executing:
ansible-playbook ansible/playbook.yml -i ansible/hosts.ini -t deploy --ask-vault-pass --verbose
Note the tag deploy, so in here it is suposed that php was installed. All had to do was remove -t deploy from my command!

Deleting multiple users with Ansible ad-hoc command

When running Ansible ad-hoc to remove users I was unable to feed multiple items to
module. Like this:
ansible -i my_inv all -m user -a"name={{ users }} state=absent" --check --extra-vars='{"users":["user1","user2"]}'
the output is:
server1 | SUCCESS => {
"changed": false,
"name": "['user1', 'user2']",
"state": "absent"
}
it seems to be not opening array correctly.
Making json file also didnt work.
{
"users":["user1","user2"]
}
Is there any way to do it without writing a role?
No.
name parameter of user module takes a string as an argument, not a list.
You need either to loop (and for that you'd need a play - not necessarily a role), or run ansible executable several times.

Is there any option to list groups in Ansible?

As far as i know, ansible has an option named --list-hosts for listing hosts. Is there any option for listing host groups? Or any other way to come through?
You can simply inspect the groups variable using the debug module:
ansible localhost -m debug -a 'var=groups.keys()'
The above is using groups.keys() to get just the list of groups. You could drop the .keys() part to see group membership as well:
ansible localhost -m debug -a 'var=groups'
Listing groups
Using tools built-in to Ansible + jq, this gives you something reasonably close:
ansible-inventory --list | jq "keys"
An advantage of this approach vs manually parsing inventory files is that it fully utilizes your ansible.cfg files (which can point to one or multiple inventory files, a directory of inventory files, etc...).
Example output on my machine (local_redis_all is a locally defined Ansible group):
[
"_meta",
"all",
"local_redis_all",
]
If you prefer it in plain-text form, use an approach like ansible-inventory --list | jq -r "keys | .[]". It will give you an output like this:
_meta
all
local_redis_all
Listing hosts
This was not part of the original question, but including it here anyway since it might be useful to some of my readers. Use the following command for JSON output (note: the command actually outputs a JSON array for each group, I haven't yet figured out a way to flatten these with jq - suggestions are welcome):
ansible-inventory --list | jq ".[].hosts | map(.)?
This gives you an output similar to this:
[
"redis-01",
"redis-02",
"redis-03"
]
Likewise, in raw text format (one host per line): ansible-inventory --list | jq -r ".[].hosts | .[]?"
This gives you an output like this:
redis-01
redis-02
redis-03
Note:- For New Ansible Users
Ansible has some special internal variables which are also known as Magic Variables.
From this link you will get full list of magic variables Magic Variables
There is magic variable called "groups" which hold the inventory group information.
we can access the value of any variable ( both user defined and Internal ) using an ansible module called debug .
I am Using Separate Inventory File
$
$ ansible -i inventory.ini all -m debug -a "var=groups"
$
centos-client.ansible.lab | SUCCESS => {
"groups": {
"all": [
"centos-client.ansible.lab",
"ubuntu-client.ansible.lab"
],
"centos": [
"centos-client.ansible.lab"
],
"ubuntu": [
"ubuntu-client.ansible.lab"
],
"ungrouped": []
}
}
ubuntu-client.ansible.lab | SUCCESS => {
"groups": {
"all": [
"centos-client.ansible.lab",
"ubuntu-client.ansible.lab"
],
"centos": [
"centos-client.ansible.lab"
],
"ubuntu": [
"ubuntu-client.ansible.lab"
],
"ungrouped": []
}
}
Method #1 - Using Ansible
If you just want a list of the groups within a given inventory file you can use the magic variables as mentioned in a couple of the other answers.
In this case you can use the groups magic variable and specifically just show the keys() in this hash (keys + values). The keys are all the names of the groups.
NOTE: By targeting the localhost we force this command to just run against a single host when processing the inventory file.
$ ansible -i inventory/rhvh localhost -m debug -a 'var=groups.keys()'
localhost | SUCCESS => {
"groups.keys()": "dict_keys(['all', 'ungrouped', 'dc1-rhvh', 'dc2-rhvh', 'dc3-rhvh', 'dc4-rhvh', 'dc5-rhvh', 'rhvh', 'dc1', 'dc2', 'dc3', 'dc4', 'dc5', 'production'])"
}
Method #2 - using grep & sed
You could of course just grep the contents of your inventory file too:
$ grep -E '^\[' inventory/rhvh
[dc1-rhvh]
[dc2-rhvh]
[dc3-rhvh]
[dc4-rhvh]
[dc5-rhvh]
[rhvh:children]
[dc1:children]
[dc2:children]
[dc3:children]
[dc4:children]
[dc5:children]
[production:children]
You're on the hook though for teasing out of the 2nd method's output or you can use sed to do it:
$ grep -E '^\[' inventory/rhvh | sed 's/:children//'
[dc1-rhvh]
[dc2-rhvh]
[dc3-rhvh]
[dc4-rhvh]
[dc5-rhvh]
[rhvh]
[dc1]
[dc2]
[dc3]
[dc4]
[dc5]
If you're not sure if the host will actually be in the inventory you can use:
ansible -i hosts/ localhost -m debug -a 'var=groups'
-i where your inventory files are kept
-m enable module debug.
-a module arguments.
It will output the group / hosts just once and not for every host in your inventory.
Same goes for just getting the list of groups in the inventory:
ansible -i hosts/ localhost -m debug -a 'var=groups.keys()'
another way to see your hosts is just to press tab after the ansible keyword.
Something like that?
cat ~/inventory/* | grep "\[.*\]"

Resources