CVS checkout with ansible playbook - ansible

I'm trying to define an ansible playbook to checkout several sources from CVS, just similarly to what I do with the git module (http://docs.ansible.com/ansible/git_module.html). Unfortunately there's no cvs module as far as I can tell.
Is there any recommended way to go about it?

If you could use SSH for login this is more or less an example to get you started:
- name: Remove cvs mirror host key
shell: ssh-keygen -R {{ openbsd_cvs_mirror }}
- name: Add cvs mirror host key
shell: ssh-keyscan -H {{ openbsd_cvs_mirror }} >> /root/.ssh/known_hosts
- name: Get OpenBSD cvs src
shell: cvs -qd anoncvs#{{ openbsd_cvs_mirror }}:/cvs checkout -P src
args:
chdir: /usr/cvs_current
creates: /usr/cvs_current/src

Related

How should I install Splunk from remote tgz package?

Im trying to perform an additional task on the output of stdout_lines.
Here is the playbook:
- name: Change to Splunk user
hosts:
sudo: yes
sudo_user: splunk
gather_facts: true
tasks:
- name: Run WGET & install SPLUNK
command: wget -O splunk-9.0.2-17e00c557dc1-Linux-x86_64.tgz https://download.splunk.com/products/splunk/releases/9.0.2/linux/splunk-9.0.2-17e00c557dc1-Linux-x86_64.tgz
- name: run 'ls' to get SPLUNK_PACKAGE_NAME
shell: 'ls -l'
register: command_output
- debug:
var: command_output.stdout_lines
I am using wget to download Splunk on the server and I need the Splunk package name so that I can extract the file in the next task.
For that, I tried to register ls -l as command_output.
Now, I need to untag it (tar xvzf splunk_package_name.tgz -C/opt), but I dont know how I can use the stdout_lines output in my tar command.
In Ansible, your use case should resume to one single task, using the unarchive module, along with the remote_src parameter set to true and the src one to your URL.
As described in the documentation:
If remote_src=yes and src contains ://, the remote machine will download the file from the URL first.
So, you end up with this single task:
- name: Install Splunk from remote archive
unarchive:
src: "https://download.splunk.com/products/splunk/releases/9.0.2\
/linux/splunk-9.0.2-17e00c557dc1-Linux-x86_64.tgz"
remote_src: true
## with this, you will end up with Splunk installed in /opt/splunk
dest: /opt

Chown Not Permitted, Has full Sudo Access?

I have an Ansible role which I'm trying to migrate to macOS.
The following step fails:
- name: get go user details
command: sh -c 'echo $HOME'
become: true
become_user: "{{ go_user }}"
become_flags: -Hi
changed_when: false
register: go_user_check
The error emitted is:
TASK [default : get go user details] *******************************************
fatal: [127.0.0.1]: FAILED! => {"msg": "Failed to set permissions on the temporary files Ansible needs to create when becoming an unprivileged user (rc: 1, err: chown: /var/tmp/ansible-tmp-1533765311.28-97292171123102/: Operation not permitted\nchown: /var/tmp/ansible-tmp-1533765311.28-97292171123102/command.py: Operation not permitted\n}). For information on working around this, see https://docs.ansible.com/ansible/become.html#becoming-an-unprivileged-user"}
This same step works just fine on all the Linux distributions
I'm testing against. When I execute sudo -Hiu username sh -c 'echo $HOME', I get what I would expect: /Users/travis.
When I execute the following:
ansible -i 127.0.0.1, -c local --become --become-user travis \
-m command -a 'sh -c "echo $HOME"' all
I get exactly what I'd expect, /Users/travis.
I'm reading the documentation linked to by Ansible but I'm not seeing a workaround.
Is there a different way I should be executing this on OSX?
I was able to get it to proceed with the following modification:
diff --git a/tasks/discover/go.yml b/tasks/discover/go.yml
index 090ce7d..f0c2b89 100644
--- a/tasks/discover/go.yml
+++ b/tasks/discover/go.yml
## -3,9 +3,10 ##
command: sh -c 'echo $HOME'
become: true
become_user: "{{ go_user }}"
- become_flags: -Hi
changed_when: false
register: go_user_check
+ vars:
+ ansible_ssh_pipelining: true
- name: set go user home
set_fact: go_user_home="{{ go_user_check.stdout_lines[0] }}"
Pipelining appears to dodge the file modification that is failing. Unfortunately, I don't have the answer as to why it's failing, so other answers are still welcome as I'd like to get to what is actually happening.
There appear to be a lot of caveats to using Ansible on macOS, so I will probably have to have my tasks diverge completely based on whether it's Linux or macOS.

Use the response from shell inside yml for Ansible playbook

I want to install MongoDB via Ansible playbook, I am following the instruction in:
https://www.howtoforge.com/tutorial/install-mongodb-on-ubuntu-16.04/
For the step about "Step 2 - Create source list file MongoDB"
I should use:
echo "deb http://repo.mongodb.org/apt/ubuntu "$(lsb_release -sc)"/mongodb-org/3.2 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.2.list
while it get the ubuntu version with the following command:
$(lsb_release -sc)
How can I do it via yml file and run it via ansible palybook?
I used the below yml command but it is not working and gives me error since I use shell command "$(lsb_release -sc)" inside my script
- name: Create source list file MongoDB
sudo: yes
lineinfile: >
line="deb http://repo.mongodb.org/apt/ubuntu "$(lsb_release -sc)"/mongodb-org/3.2 multiverse"
dest=/etc/apt/sources.list.d/mongodb-org-3.2.list
state=present
create=yes
There is apt_repository module in Ansible:
- apt_repository:
repo: deb http://repo.mongodb.org/apt/ubuntu {{ ansible_distribution_release | lower }}/mongodb-org/3.2 multiverse
state: present
You can register the result of one task, including its stdout, as a variable then use it in later tasks:
- name: Work out the distribution
command: lsb_release -sc
register: result
- name: Create source list file MongoDB
sudo: yes
lineinfile: >
line="deb http://repo.mongodb.org/apt/ubuntu {{ result.stdout }}/mongodb-org/3.2 multiverse"
dest=/etc/apt/sources.list.d/mongodb-org-3.2.list
state=present
create=yes

How to run a shell function as a command in Ansible?

I'm using nvm (https://github.com/creationix/nvm), which is essentially a shell script that you source into your shell and then call, for example, nvm install [version]. But no matter how I try and call that function, ansible can't seem to find it.
I've tried using the command and shell modules. I've tried using become and become_user. I've tried using sudo -iu like in https://github.com/leonidas/ansible-nvm/blob/master/tasks/main.yml, but it doesn't work for me. It must be possible though since it works in that file.
How can I run any shell function in Ansible? In this case I've got a source nvm.sh in my .zshrc which allows me to execute nvm commands from the interactive shell fine.
You'll need to use the shell module, because you want to run shell commands, and you'll need to source in the nvm script into that environment. Something like:
- shell: |
source /path/to/nvm
nvm install ...
Whether or not you use become depends on whether or not you want to run the commands as root (or another user).
Here is my playbook for this:
- hosts: all
vars:
# https://github.com/nvm-sh/nvm/releases
nvm_version: "0.34.0"
# https://github.com/nodejs/node/releases
# "node" for latest version, "--lts" for latest long term support version,
# or provide a specific version, ex: "10.16.3"
node_version: "--lts"
tasks:
- name: Get_nvm_install_script | {{ role_name | basename }}
tags: Get_nvm_install_script
get_url:
url: https://raw.githubusercontent.com/nvm-sh/nvm/v{{ nvm_version }}/install.sh
dest: "{{ ansible_user_dir }}/nvm_install.sh"
force: true
- name: Install_or_update_nvm | {{ role_name | basename }}
tags: Install_or_update_nvm
command: bash {{ ansible_user_dir }}/nvm_install.sh
- name: Install_nodejs | {{ role_name | basename }}
tags: Install_nodejs
shell: |
source {{ ansible_user_dir }}/.nvm/nvm.sh
nvm install {{ node_version }}
args:
executable: /bin/bash
Note the use of executable: /bin/bash, as source command is not available in all shells, so we specify bash because it includes source
As an alternative to source you can use the dot:
- name: Install_nodejs | {{ role_name | basename }}
tags: Install_nodejs
shell: |
. {{ ansible_user_dir }}/.nvm/nvm.sh
nvm install {{ node_version }}

How do I pass username and password while using Ansible Git module?

While doing clone, push or pull of a private git repository hosted internally (e.g. on a GitLab instance) with Ansible's Git module, how do I specify username and password to authenticate with the Git server?
I don't see any way to do this in the documentation.
You can use something like this:
---
- hosts: all
gather_facts: no
become: yes
tasks:
- name: install git package
apt:
name: git
- name: Get updated files from git repository
git:
repo: "https://{{ githubuser | urlencode }}:{{ githubpassword | urlencode }}#github.com/privrepo.git"
dest: /tmp
Note: {{ githubpassword | urlencode }} is used here, if your password also contains special characters #,#,$ etc
Then execute the following playbook:
ansible-playbook -i hosts github.yml -e "githubuser=arbabname" -e "githubpassword=xxxxxxx"
Note: Make sure you put the credentials in ansible vaults or pass it
secure way
Improving on Arbab Nazar's answer, you can avoid exposing your password in the terminal by prompting for the credentials.
playbook.yml
---
- name: ANSIBLE - Shop Installation
hosts: '{{ target }}'
vars_prompt:
- name: "githubuser"
prompt: "Enter your github username"
private: no
- name: "githubpassword"
prompt: "Enter your github password"
private: yes
[...]
And in the task reference the variables.
task.yml
- name: Get updated files from git repository
git:
repo=https://{{ githubuser | urlencode }}:{{ githubpassword | urlencode }}#github.com/privrepo.git
dest=/tmp
This will save the password as clear text in .git/config as url of remote "origin".
The following task can be used to remove it.
- name: Ensure remote URL does not contain credentials
git_config:
name: remote.origin.url
value: https://github.com/privrepo.git
scope: local
repo: /tmp
Taken from: Clone a private git repository with Ansible (using password prompt)
While Arbab's and F. Santiago's answers are correct, there is an important caveat: With https://{{ githubuser | urlencode }}:{{ githubpassword | urlencode }}#github.com/privrepo.git as the checkout URL, Git will store your password in plaintext inside the .git/ folder. This has been mentioned in a comment, but I think it deserves more attention. You might want to do away the Git module and use raw Git, e.g.:
vars_prompt:
- name: "githubuser"
prompt: "Enter your github username"
private: no
- name: "githubpassword"
prompt: "Enter your github password"
private: yes
tasks:
- name: Git clone
expect:
command: git clone https://github.com/privrepo.git /tmp
responses:
Username: "{{ githubuser }}" # Username is a regex
Password: "{{ githubpassword }}" # Password is a regex
no_log: true
All of the answers here made it a bit too easy to leak the username/password into a log or error message, which seemed undesirable even if in my case it's a read-only deployment token.
Here's an alternative:
- name: Configure Git credential storage
command: "git config --global credential.helper store"
- name: Populate the Git credential store
template:
src: files/git_credentials.j2
dest: /home/appuser/.git-credentials
owner: appuser
group: appuser
mode: u=rw,g=,o=
no_log: true
The template looks like this:
https://{{ gitlab_username|urlencode }}:{{ gitlab_password|urlencode }}#gitlab.example.org
If you prefer non-interactive mode, there are (at least) two options:
Temporarily upload .netrc
$ cat ~/.netrc
machine github.com login martin.pilka password PASSWORD
$ cat playbook.yaml
...
- name: Temporarily copy .netrc so "git clone" below works without asking for password
ansible.builtin.copy:
src: ~/.netrc
dest: ./
mode: "u=rw,g=rw,o="
- name: Clone repo so remote changes can be easily committed
ansible.builtin.git:
repo: https://martin.pilka#github.com/dNationCloud/kubernetes-monitoring
dest: git/kubernetes-monitoring/
clone: yes
update: yes
- name: Securely delete .netrc
command: shred --iterations=1 --remove ~/.netrc
args:
removes: ~/.netrc
Use Ansible Vault
$ cat playbook.yaml
...
- name: Clone repo so remote changes can be easily committed
vars:
# Encrypted URL including password:
# https://martin.pilka:PASSWORD#github.com/dNationCloud/kubernetes-monitoring
repo: !vault |
$ANSIBLE_VAULT;1.1;AES256
...
ansible.builtin.git:
repo: "{{ repo }}"
dest: git/kubernetes-monitoring/
clone: yes
update: yes
- name: Remove credentials from GIT URL
ansible.builtin.git_config:
name: remote.origin.url
value: https://martin.pilka#github.com/dNationCloud/kubernetes-monitoring
scope: local
repo: git/kubernetes-monitoring/
Notes:
Option 1 is simpler - no need to use Ansible Vault related commands/parameters (when encoding secret and playing book)
Unfortunately both options temporarily store password on remote side in plain text (in .netrc or .git/config) - same is true for all other solutions listed here

Resources