Create a file in ansible inside a directory - ansible

I need to create the file kubernetes.list inside the directory /etc/apt/sources.list.d/
but this directory does not exist - So I want ansible to create the directory and touch the file as well.
This is the current setup I have and it throws the error
No such file or directory
- name: create the file
file:
path: path=/etc/apt/sources.list.d/kubernetes.list
state: touch
can someone please help me?

You can create the folder before creating the file:
- hosts: all
tasks:
- name: create folder if not exists
become: true
file:
path: /etc/apt/sources.list.d
state: directory
owner: root
group: root
mode: 0775
- name: create file
become: true
file:
path: /etc/apt/sources.list.d/kubernetes.list
state: touch

Related

Ansible copies a dedicate file to a namesake directory first as opposed to copying in an existing directory

Problem
Ansible Version: 2.12.10~ppa:focal
I am using packer to provision a qemu image using packer and its ansible-local provisioner (I already have an base image in which ansible is installed).
I am trying to copy a file to a destination directory (already exists) but ansible keeps creating a directory of the filename and then copies is the file to the image
Current result
/home/admin/stack/app/libsomething.so.0.5.0/libsomething.so.0.5.0
Desired result
/home/admin/stack/app/libsomething.so.0.5.0
Structure
My directory structure is as follows:
stack/
├── appstack # here is the role to be called
├── common-docs
└── common-software # here is the file to be copied
|--- bootstap.yml
the libsomething.so.0.5.0 exists in common-software/license/ directory
Role
tasks/main.yml
---
- name: create app directory and copy some previous files
copy:
src: "{{ item }}"
dest: "{{ core_directory }}/"
loop: "{{ core_services }}"
- name: app add Licensing related files to app Directory
copy:
src: "{{ playbook_dir }}/common-software/license/libsomething.so.0.5.0"
dest: "{{ core_directory }}/app/"
when: ansible_facts['architecture'] == "x86_64"
defaults/main.yml
core_directory: /home/admin/stack
core_services:
- app
there are certain files already existing under files/app which will be copied to image first and then I use another task to move the libsomething.so.0.5.0
boostrap.yml
---
- hosts: 127.0.0.1
connection: local
roles:
- appstack
Query
where am I going wrong here with a simple task of just copying the file to the destination in an already existing directory beforehand. I went through the documentation and if I remove the / from the dest parameter I get the following error:
[Errno 21] Is a directory

How can I manage groups in inventory?

I have a common playbook (task) but in my last task I want to do an action on a group of hosts and when it is finished, do the same action on another group (for my test I simply empty a folder):
- name: test clean folder on hosts
ansible.builtin.file:
path: /testJO
when: inventory_hostname in groups['c_hosts']
- name: test clean folder on master
ansible.builtin.file:
path: /testJO
when: inventory_hostname in groups['master’]
I have issue with my inventory file :
/root/ansible_Folder/inventories/inventories.yml :
all:
hosts:
children:
master:
hosts:
dem-master:
c_hosts:
hosts:
dem-host:
Who knows how I can manage my inventories file please?
EDIT :
I tried your solution which seems to me coherent but i have this error message :
ERROR! conflicting action statements: hosts, tasks
The error appears to be in '/root/ansible-cortex-lab/playbooks/roles/cortex/tasks/main.yml': line 1, column 3, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
- hosts: c_hosts
^ here
I just copy past both config file you gave to me.
Do you know why I have this behaviour please ?
Separate the plays, e.g.
- hosts: c_hosts
tasks:
- name: test remove folder
ansible.builtin.file:
path: /testJO
state: absent
- name: test create folder
ansible.builtin.file:
path: /testJO
state: directory
- hosts: master
tasks:
- name: test remove folder
ansible.builtin.file:
path: /testJO
state: absent
- name: test create folder
ansible.builtin.file:
path: /testJO
state: directory
The module file can't simply clean a folder. Instead, remove a folder and create it again.
To fix the inventory, remove the 2nd line hosts:. See Inventory basics: formats, hosts, and groups
all:
children:
master:
hosts:
dem-master:
c_hosts:
hosts:
dem-host:

Why I can't create a file with ansible by accordding to the ansible-doc?

Below is the error information:
ansible-file is absent, cannot continue, path:/webdev
I created a file with the following code:
---
- name: create webfile
hosts: dev
tasks:
- file:
path: /webdev
group: webdev
mode: '2775'
But it can't create the file while the official example is:
- name: Change file ownership, group and permissions
file:
path: /etc/foo.conf
owner: foo
group: foo
mode: '0644'
My code didn't raise any error about who the file belongs to, so I think the error is raised because I don't have the owner entry.
Can you help me fix this error?

Ansible: Handling temporary file idempotently and securely

In Ansible (RHEL 8 if it matters), I need to create a temporary file from a template with sensitive content. After a few other tasks are completed, it should be deleted. The temporary file is an answerfile for an installer that will run as a command. The installer needs a user name and password.
I can't figure out if there is a way to do this easily in Ansible.
The brute-force implementation of what I'm looking for would look similar to this:
- name: Create answer file
template:
src: answerfile.xml.j2
dest: /somewhere/answer.xml
owner: root
group: root
mode: '0600'
- name: Install
command: /somewhere/myinstaller --answerfile /somewhere/answer.xml
creates: /somewhereelse/installedprogram
- name: Delete answerfile
file:
path: /somewhere/answer.xml
state: absent
Of course, this code is not idempotent - the answer file would get created and destroyed on each run.
Is there a better way to do this?
Test the existence of the file. If it exists skip the block. For example
- stat:
path: /somewhereelse/installedprogram
register: st
- block:
- name: Create answer file
template:
src: answerfile.xml.j2
dest: /somewhere/answer.xml
owner: root
group: root
mode: '0600'
- name: Install
command: /somewhere/myinstaller --answerfile /somewhere/answer.xml
- name: Delete answerfile
file:
path: /somewhere/answer.xml
state: absent
when: not st.stat.exists
(not tested)
Taking the task "Delete answerfile" out of the block will make the code more secure. It will always make sure the credentials are not stored in the file. The task won't fail if the file is not present.
- stat:
path: /somewhereelse/installedprogram
register: st
- block:
- name: Create answer file
template:
src: answerfile.xml.j2
dest: /somewhere/answer.xml
owner: root
group: root
mode: '0600'
- name: Install
command: /somewhere/myinstaller --answerfile /somewhere/answer.xml
when: not st.stat.exists
- name: Delete answerfile
file:
path: /somewhere/answer.xml
state: absent
(not tested)
I think that this solution potentially represents a slight improvement on your solution.
With this solution the tasks which create and delete the answerfile will be skipped (rather than always run and reporting changed) if the program you're targeting is already installed.
I still don't love this solution as I don't really like skips.
# Try call the installedprogram. --version is arbitrary here.
# --help, or a simple `which installedprogram` could be alternatives.
- name: Try run installedprogram
command: '/somewhereelse/installedprogram --version'
register: installedprogram_exists
ignore_errors: yes
changed_when: False
# Only create answer file if installedprogram is not installed
- name: Create answer file
template:
src: answerfile.xml.j2
dest: /somewhere/answer.xml
owner: root
group: root
mode: '0600'
when: installedprogram_exists.rc != 0
- name: Install
command: /somewhere/myinstaller --answerfile /somewhere/answer.xml
creates: /somewhereelse/installedprogram
# Only delete answer file if installedprogram is not installed
- name: Delete answerfile
file:
path: /somewhere/answer.xml
state: absent
when: installedprogram_exists.rc != 0

ansible create user: no default .bashrc created?

I am creating users with these tasks:
- name: ensure home directory
sudo: yes
file: path={{item.home}} state=directory
with_items: users
- name: create user {{item.name}}
sudo: yes
user: name={{item.name}} home={{item.home}} shell=/bin/bash group={{item.group}} groups={{item.groups}} password={{item.password}} state=present
with_items: users
but it seems that a ~/.bashrc per user is not created in their home directory.
Is there a way to create a default basic .bashrc file?
Thanks
Starting from Ansible 2.0, you can pass along a skeleton option:
Optionally set a home skeleton directory. Requires createhome option!
This works for me:
- name: "Create deployment user"
user:
name: "foobar"
groups: "sudo"
append: yes
skeleton: "/etc/skel"
createhome: yes
I used a specific path for the home folders (different than the traditionnal /home/user1 folder): /specific/path/home/user1
Since I had an error that the path /specific/path/home/user1 could not be created when I was creating the user1, I then created the home folders before creating the users.
However if the home folder already exists when a user is created, the default .bashrc is not copied.
You have to add append=yes at the end of the user command
user:
- name: Add users
add_user:
name: '{{item.name}}'
home: '{{item.home}}'
shell: /bin/bash
group: '{{item.group}}'
groups: '{{item.groups}}'
password: '{{item.password}}'
state: present
append: yes
with_items: users

Resources