How to set ansible_python_interpreter variable for windows hosts? - ansible

I have to set ansible_python_interpreter variable for windows host, but when I set this as:
ansible_python_interpreter=C:\Program Files\Python310
It throws error like:
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: re.error: bad escape \P at position 3
host_name | FAILED! => {
"msg": "Unexpected failure during module execution.",
"stdout": ""
How to solve this issue?

Related

Run Ansible playbook on OVH cloud instance with Terraform Cloud

I have a Terraform+Ansible combination that sets up an OVH cloud instance, and then runs an Ansible playbook on it using provisioners. When I run this locally, I can supply the public and private keys directly via the command line (not using file paths), and the terraform apply works perfectly.
On Terraform Cloud, I create the keys as variables. When I run the Terraform plan, the remote-exec provisioner works, and connects to the instance as it should. However, the local-exec fails with a Permission denied (publickey). What am I missing?
My provisioner blocks:
# Dummy resource to hold the provisioner that runs ansible
resource "null_resource" "run_ansible" {
provisioner "remote-exec" {
inline = ["sudo apt update", "sudo apt install python3 -y", "echo Done!"]
connection {
host = openstack_compute_instance_v2.test_instance.network[0].fixed_ip_v4
type = "ssh"
user = "ubuntu"
private_key = var.pvt_key
}
}
provisioner "local-exec" {
command = "python3 -m pip install --no-input ansible; ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -u ubuntu -i '${openstack_compute_instance_v2.test_instance.network[0].fixed_ip_v4},' '--private-key=${var.pvt_key}' -e 'pub_key=${var.pub_key}' ansible/setup.yml"
}
}
Terraform cloud run error:
TASK [Gathering Facts] *********************************************************
fatal: [xx.xxx.xxx.xx]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: Warning: Permanently added 'xx.xxx.xxx.xx' (ECDSA) to the list of known hosts.\r\nno such identity: /home/tfc-agent/.tfc-agent/component/terraform/runs/run-AhaANkduM9YXJVoC/config/<<EOT\n-----BEGIN OPENSSH PRIVATE KEY-----<private-key>-----END OPENSSH PRIVATE KEY-----\nEOT: No such file or directory\r\nubuntu#xx.xxx.xxx.xx: Permission denied (publickey).", "unreachable": true}
I solved the problem by creating (sensitive) key files on the Terraform Cloud host, and passing the paths to them to Ansible instead.
The variables are still supplied via TFCloud, but without the heredoc syntax.
I had to add an extra new line \n at the end of the key to get around it being stripped. See the following issue: https://github.com/ansible/awx/issues/9082.
resource "local_sensitive_file" "key_file" {
content = "${var.pvt_key}\n"
filename = "${path.root}/.ssh/key"
file_permission = "600"
directory_permission = "700"
}
resource "local_sensitive_file" "pubkey_file" {
content = "${var.pub_key}\n"
filename = "${path.root}/.ssh/key.pub"
file_permission = "644"
directory_permission = "700"
}

Ansible - Gather Facts failed on Windows DC

I´m currently trying to create update Jobs for Windows Servers which mostly works. But on all my DCs (expect one, don´t know why this one is working) gathering facts failed with this error message:
fatal: [hostname]: FAILED! => {"ansible_facts": {}, "changed": false, "failed_modules": {"setup": {"exception": "Access denied \r\nAt line:63 char:44\r\n+ ... e_name] = $(Get-CimInstance -Namespace $namespace -ClassName $instanc ...\r\n+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r\n + CategoryInfo : PermissionDenied: (Root\\CIMV2:Win3...erConfiguration:String) [Get-CimInstance], CimException\r\n + FullyQualifiedErrorId : HRESULT 0x80041003,Microsoft.Management.Infrastructure.CimCmdlets.GetCimInstanceCommand\r\n\r\nScriptStackTrace:\r\nat Get-LazyCimInstance, <No file>: line 63\r\nat <ScriptBlock>, <No file>: line 142\r\n\r\nMicrosoft.Management.Infrastructure.CimException: Access denied \r\n at Microsoft.Management.Infrastructure.Internal.Operations.CimAsyncObserverProxyBase`1.ProcessNativeCallback(OperationCallbackProcessingContext callbackProcessingContext, T currentItem, Boolean moreResults, MiResult operationResult, String errorMessage, InstanceHandle errorDetailsHandle)", "failed": true, "msg": "Unhandled exception while executing module: Access denied "}}, "msg": "The following modules failed to execute: setup\n"}
Executing commands on those DCs are working, only gathering facts failed. On non DCs gathering facts works.
Does anyone have an idea what could be the problem?
Fixed it with update ansible to some > 2.9.
With ansible 2.10 or ansible4 it is working

Playbook is unable to create VM running into fatal error

We have a playbook which create the VM. First time when I ran the infrastructure pipeline VM is created.
After making some "sku" related changes in playbook and trying to run the pipeline again, getting below error.
2020-11-09T09:42:37.7488228Z TASK [ansible-role-adfv2-shir : Install Java Runtime Environment] **************
2020-11-09T09:42:37.7489504Z task path: /opt/ansible-roles/cloud/2020.10-212/ansible-role-adfv2-shir/tasks/install.yml:24
2020-11-09T09:42:37.7491381Z Monday 09 November 2020 04:42:37 -0500 (0:00:31.732) 0:12:49.681 *******
2020-11-09T09:42:37.8258708Z Using module file /home/cvx_admin_user/.ansible-virtualenv/lib/python2.7/site-packages/ansible/modules/windows/win_package.ps1
2020-11-09T09:42:37.8261046Z <10.71.116.128> ESTABLISH WINRM CONNECTION FOR USER: cvx_admin_user on PORT 5986 TO 10.71.116.128
2020-11-09T09:42:37.8261724Z checking if winrm_host 10.71.116.128 is an IPv6 address
2020-11-09T09:42:37.8262337Z <10.71.116.128> WINRM CONNECT: transport=ssl endpoint=https://10.71.116.128:5986/wsman
2020-11-09T09:42:37.9552112Z <10.71.116.128> WINRM OPEN SHELL: 6450AAB3-A367-49DA-B034-B197FC2A464D
2020-11-09T09:42:37.9555186Z EXEC (via pipeline wrapper)
2020-11-09T09:42:37.9558598Z <10.71.116.128> WINRM EXEC 'PowerShell' ['-NoProfile', '-NonInteractive', '-ExecutionPolicy', 'Unrestricted', '-']
2020-11-09T09:43:15.3305027Z <10.71.116.128> WINRM RESULT u'<Response code 0, out "{"stdout":"","rc":16", err "">'
2020-11-09T09:43:15.3361619Z <10.71.116.128> WINRM CLOSE SHELL: 6450AAB3-A367-49DA-B034-B197FC2A464D
**2020-11-09T09:43:15.3500563Z fatal: [corest-tsir00]: FAILED! => {
2020-11-09T09:43:15.3530075Z "changed": false,
2020-11-09T09:43:15.3560075Z "exit_code": 1618,
2020-11-09T09:43:15.3560924Z "msg": "unexpected rc from install C:\\ExeSources\\jre8u191windowsx64.exe: see rc, stdout and stderr for more details",
2020-11-09T09:43:15.3561602Z "rc": 1618,
2020-11-09T09:43:15.3562066Z "reboot_required": false,
2020-11-09T09:43:15.3562571Z "restart_required": false,
2020-11-09T09:43:15.3563039Z "stderr": "",
2020-11-09T09:43:15.3563488Z "stderr_lines": [],
2020-11-09T09:43:15.3563938Z "stdout": "",
2020-11-09T09:43:15.3564377Z "stdout_lines": []
2020-11-09T09:43:15.3564820Z }**
I am not sure why I am getting this error. Please help me out with this error.
Thanks!
Your return code for jre8u191windowsx64.exe is 1618, which means ERROR_INSTALL_ALREADY_RUNNING. The MSI error code page tells us that:
Another installation is already in progress. Complete that installation before proceeding with this install.

How to pass environment variable to sh script?

I want to create an environment variable in Jenkinsfile which will consist of current workspace (using envirnoment variable WORKSPACE). Then I want to pass this new variable to sh script in next stage.
I've tried declaring variable in the following way:
environment {
artefact_path = "${env.WORKSPACE}/temp/unzipped/${artefact_name}/dev"
}
But after passing it to sh script:
sh "ansible-playbook -i inventory playbook.yml -e \"artefact_path=${env.artefact_path}\""
I get the following output:
+ ansible-playbook -i inventory playbook.yml -e 'artefact_path=C:\nowy_dir\workspace\something/temp/unzipped/something/dev'
PLAY [play] **************************************************************
TASK [task] *********************************************************
fatal: [host]: FAILED! => {"changed": false, "dest": "D:/inetpub/something", "msg": "Get-AnsibleParam: Parameter 'src' has an invalid path 'C:\nowy_dir\\workspace\\something/temp/unzipped/something/dev' specified.", "src": "C:\nowy_dir\\workspace\\something/temp/unzipped/something/dev"}
to retry, use: --limit #/etc/ansible/ansible-scripts/playbook.retry
As you can see the variable is passed with two \ instead of one. How can I prevent this from happening?
EDIT 1
I decided to change the way in which I declare the variable to:
def get_deploy_path() {
def site = get_site()
def wspace = "${env.WORKSPACE}"
def deploy_path = wspace.toString() + "\\temp\\snapshot\\" + site + "\\"
return deploy_path
}
environment {
deploy_path = get_deploy_path()
}
Now I have a problem with workspace. I'm operating on two agents (first is Windows and the second is Linux based). I need the path to be the same both in stages on Windows and on Linux. Any idea how I can make it happen?

How do I pass a dictionary to an ansible ad-hoc command?

If I have an ansible ad-hoc command that wants a dictionary or list valued argument, like the queries argument to postgresql_query, how do I invoke that in ansible ad-hoc commands?
Do I have to write a one-command playbook? I'm looking for a way to minimise the numbers of layers of confusing quoting (shell, yaml/json, etc) involved.
The ansible docs mention accepting structured forms for variables. So I tried the yaml and json syntax for the arguments:
ansible -m postgresql_query -sU postgres -a '{"queries":["SELECT 1", "SELECT 2"]}'
... but got ERROR! this task 'postgresql_query' has extra params, which is only allowed in the following modules: ....
the same is true if I #include a file with yaml or json contents like
cat > 'query.yml' <<'__END__'
queries:
- "SELECT 1"
- "SELECT 2"
__END__
ansible -m postgresql_query -sU postgres -a #queries.yml
You can define a dictionary in a JSON variable to pass it as parameter next:
ansible -m module_name -e '{"dict": {"key": "value"}}' -a "param={{ dict }}"
(parameters positions are arbitrary)
I have most of a solution - a way to express something like a shell script or query payload without extra quoting. But it's ugly:
ansible hostname -m postgresql_query -sU postgres -a 'query="{{query}}"' -e #/dev/stdin <<'__END__'
query: |
SELECT 'no special quotes needed' AS "multiline
identifier works fine" FROM
generate_series(1,2)
__END__
Not only is that shamefully awful, but it doesn't seem to work for lists (arrays):
ansible hostname -m postgresql_query -sU postgres -vvv -a 'query="{{query}}"' -e #/dev/stdin <<'__END__'
queries:
- |
SELECT 1
- |
SELECT 2
__END__
fails with
hostname | FAILED! => {
"changed": false,
"err": "syntax error at or near \"<\"\nLINE 1: <bound method Templar._query_lookup of <ansible.template.Tem...\n ^\n",
"invocation": {
"module_args": {
"autocommit": false,
"conninfo": "",
"queries": null,
"query": "<bound method Templar._query_lookup of <ansible.template.Templar object at 0x7f72531c61d0>>"
}
},
"msg": "Database query failed"
}
so it looks like some kind of lazy evaluation is breaking things.

Resources