How to create a directory using Ansible - directory

How do you create a directory www at /srv on a Debian-based system using an Ansible playbook?

You want the file module. To create a directory, you need to specify the option state: directory :
- name: Creates directory
file:
path: /src/www
state: directory
You can see other options at https://docs.ansible.com/ansible/latest/collections/ansible/builtin/file_module.html

You can even extend the file module and even set the owner,group & permission through it. (Ref: Ansible file documentation)
- name: Creates directory
file:
path: /src/www
state: directory
owner: www-data
group: www-data
mode: 0775
Even, you can create the directories recursively:
- name: Creates directory
file:
path: /src/www
state: directory
owner: www-data
group: www-data
mode: 0775
recurse: yes
This way, it will create both directories, if they didn't exist.

Additional for all answers here, there is lot of situations when you need to create more then one directory so it is a good idea to use loops instead creating separate task for each directory.
- name: creates multiple directories in one task
file:
path: "{{ item }}"
state: directory
loop:
- /srv/www
- /dir/foo
- /dir/bar

you can create using:
Latest version 2<
- name: Create Folder
file:
path: /srv/www/
owner: user
group: user
mode: 0755
state: directory
Older version
- name: Create Folder
file:
path=/srv/www/
owner=user
group=user
mode=0755
state=directory
Refer - http://docs.ansible.com/ansible/file_module.html

Directory can be created using file module only, as directory is nothing but a file.
# create a directory if it doesn't exist
- file:
path: /etc/some_directory
state: directory
mode: 0755
owner: foo
group: foo

- name: Create a directory
ansible.builtin.file:
path: /etc/some_directory
state: directory
mode: '0755'

- file:
path: /etc/some_directory
state: directory
mode: 0755
owner: someone
group: somegroup
That's the way you can actually also set the permissions, the owner and the group. The last three parameters are not obligatory.

You can create a directory. using
# create a directory if it doesn't exist
- file: path=/src/www state=directory mode=0755
You can also consult
http://docs.ansible.com/ansible/file_module.html
for further details regaridng directory and file system.

Just need to put condition to execute task for specific distribution
- name: Creates directory
file: path=/src/www state=directory
when: ansible_distribution == 'Debian'

You can use the statement
- name: webfolder - Creates web folder
file: path=/srv/www state=directory owner=www-data group=www-data mode=0775`

enter code here
- name: creating directory in ansible
file:
path: /src/www
state: directory
owner: foo
you can refer to ansible documentation

If you want to create a directory in windows:
- name: create folder in Windows
win_file:
path: C:\Temp\folder\subfolder
state: directory
See the win_file module for more information.

to create directory
ansible host_name -m file -a "dest=/home/ansible/vndir state=directory"

We have modules available to create directory , file in ansible
Example
- name: Creates directory
file:
path: /src/www
state: directory

you can use the "file" module in this case, there are so many arguments that you can pass for a newly created directory like the owner, group, location, mode and so on.....
please refer to this document for the detailed explanation on the file module...
https://docs.ansible.com/ansible/latest/modules/file_module.html#file-module
remember this module is not just for creating the directory !!!

To check if directory exists and then run some task (e.g. create directory) use the following
- name: Check if output directory exists
stat:
path: /path/to/output
register: output_folder
- name: Create output directory if not exists
file:
path: /path/to/output
state: directory
owner: user
group: user
mode: 0775
when: output_folder.stat.exists == false

You can do it as one of the following ways:
Example 1: If Parent Directory already exists:
- name: Create a new directory www at given path
ansible.builtin.file:
path: /srv/www/
state: directory
mode: '0755'
Example 2: If Parent Directory does not exist:
- name: Create a new directory www at given path recursively
ansible.builtin.file:
path: /srv/www/
state: directory
mode: '0755'
recurse: yes
Here in Example 2, it will recursively create both directories if they are not present.
You can see the Official Documentation for further info on file_module

You can directly run the command and create directly using ansible
ansible -v targethostname -m shell -a "mkdir /srv/www" -u targetuser
OR
ansible -v targethostname -m file -a "path=/srv/www state=directory" -u targetuser

---
- hosts: all
connection: local
tasks:
- name: Creates directory
file: path=/src/www state=directory
Above playbook will create www directory in /src path.
Before running above playbook. Please make sure your ansible host connection should be set,
"localhost ansible_connection=local"
should be present in /etc/ansible/hosts
for more information please let me know.

Use file module to create a directory and get the details about file module using command "ansible-doc file"
Here is an option "state" that explains:
If directory, all immediate subdirectories will be created if they do not exist, since 1.7 they will be created with the supplied permissions.
If file, the file will NOT be created if it does not exist, see the [copy] or [template] module if you want that behavior.
If link, the symbolic link will be created or changed. Use hard for hardlinks.
If absent, directories will be recursively deleted, and files or symlinks will be unlinked.
Note that file will not fail if the path does not exist as the state did not change.
If touch (new in 1.4), an empty file will be created if the path does not
exist, while an existing file or directory will receive updated file
access and modification times (similar to the way touch works from
the command line).

Easiest way to make a directory in Ansible.
name: Create your_directory if it doesn't exist.
file:
path: /etc/your_directory
OR
You want to give sudo privileges to that directory.
name: Create your_directory if it doesn't exist.
file:
path: /etc/your_directory
mode: '777'

Hello good afternoon team.
I share the following with you.
- name: Validar Directorio
stat:
path: /tmp/Sabana
register: sabana_directorio
- debug:
msg: "Existe"
when: sabana_directorio.stat.isdir == sabana_directorio.stat.isdir
- name: Crear el directorio si no existe.
file:
path: /tmp/Sabana
state: directory
when: sabana_directorio.stat.exists == false
With which you can validate if the directory exists before creating it

I see lots of Playbooks examples and I would like to mention the Adhoc commands example.
$ansible -i inventory -m file -a "path=/tmp/direcory state=directory ( instead of directory we can mention touch to create files)

You need to use file module for this case. Below playbook you can use for your reference.
---
- hosts: <Your target host group>
name: play1
tasks:
- name: Create Directory
files:
path=/srv/www/
owner=<Intended User>
mode=<Intended permission, e.g.: 0750>
state=directory

here is easier way.
- name: create dir
command: mkdir -p dir dir/a dir/b

Related

Where to place .Renviron file when deploying shiny app with shinyproxy?

I'm learning how to use shinyproxy to deploy R shiny applications but I can't figure out where to place my .Renviron file which contains global variables used to access a database.
The docker image builds without any errors but when I start the container using:
docker run -it -p 3838:3838 shinyproxy-template .
It doesn't find the env variables in the .Renviron file and I end up getting an error on the part of the R code that requires the global variables.
My current folder structure is as follows:
shinyproxy-template/
|- app-folder/
|- .gitignore
|- Dockerfile
|- README.md
|- app.Rproj
|- Rprofile.site
|- .Renviron
I tried placing the .Renviron file inside the app-folder/ then built the docker image again but the global variables were still inaccessible.
Where should I place the .Renviron so that the global variables are accessed by the app?
There are multiple options:
Put .Renviron file to the expected location inside the container
You can add a COPY command to the Dockefile to copy your .Renviron file to the expected location - i.e. either a home directory of the user or the WORKDIR location if defined in the Dockerfile. In case of the root user it would be:
COPY .Renviron /root/
Add environment variables from .Renviron to the Dockerfile
Add lines like:
ENV VAR1="value1"
ENV VAR2="value2"
to your Dockerfile
Add environment variables from .Renviron to the shinyproxy configuration
You can define environment variables in the application.yaml configuration file by either using
container-env:
VAR1: VALUE1
VAR2: VALUE2
or
container-env-file: /path/to/.Renviron
for your app specification. Note that the path here is on the host and not inside the container.
For docker run
When you do a docker run outside of shinyproxy you can use argument --env-file with something like:
docker run -it -p 3838:3838 shinyproxy-template --env-file /path/to/shinyproxy-template/.Renviron
Releant documentation links:
https://www.shinyproxy.io/documentation/configuration/#apps
https://docs.docker.com/engine/reference/commandline/run/#set-environment-variables--e---env---env-file
Edit: Have a look at #Max's solution. We posted at nearly the same time but his instructions are clearer.
After lots of trial and error I finally got a solution.
First, starting the container outside shinyproxy to check if the shiny app runs normally? Use docker's --env-file flag to specify the .Renviron filepath. In my case since both the Dockerfile and .Renviron are in the same folder so I'd do:
docker run -it --env-file .Renviron -p 3838:3838 shinyproxy-template .
The app will now recognize env vars defined in the .Renviron file and no errors!
I then changed into the directory where I had shinyproxy-2.6.1.jar file and ran it again using java -jar shinyproxy-2.6.1.jar. There was an error when I tried to start my shinyapp. It couldn't find the env vars.
So I resorted to adding them directly in the application.yml which is in the same location as shinyproxy-2.6.1.jar:
- id: app-folder
display-name: My App
description: My App's title
container-cmd: ["R", "-e", "shiny::runApp('/root/app-folder')"]
container-image: openanalytics/shinyproxy-template
container-env:
ENV1: ENV1-VALUE
ENV2: ENV2-VALUE
ENV3: ENV3-VALUE
access-groups: scientists
Replace the necessary parts of the yml section with the corresponding one's on your side depending on your case. The same applies to the env vars.
In fact let me just provide a prototype of my whole application.yml file, have a look at the last app I added "wca":
proxy:
title: Open Analytics Shiny Proxy
logo-url: https://www.openanalytics.eu/shinyproxy/logo.png
landing-page: /
# hide nav bar:
hide-navbar: true
heartbeat-rate: 10000
heartbeat-timeout: 60000
port: 8080
authentication: ldap
admin-groups: scientists
# Example: 'simple' authentication configuration
users:
- name: jack
password: password
groups: scientists
- name: jeff
password: password
groups: mathematicians
# Example: 'ldap' authentication configuration
ldap:
url: ldap://ldap.forumsys.com:389/dc=example,dc=com
user-dn-pattern: uid={0}
group-search-base:
group-search-filter: (uniqueMember={0})
manager-dn: cn=read-only-admin,dc=example,dc=com
manager-password: password
# Docker configuration
docker:
url: http://localhost:2375
port-range-start: 20000
specs:
- id: 01_hello
display-name: Hello Application
description: Application which demonstrates the basics of a Shiny app
container-cmd: ["R", "-e", "shinyproxy::run_01_hello()"]
container-image: openanalytics/shinyproxy-demo
access-groups: [scientists, mathematicians]
- id: 06_tabsets
container-cmd: ["R", "-e", "shinyproxy::run_06_tabsets()"]
container-image: openanalytics/shinyproxy-demo
access-groups: scientists
- id: euler
display-name: Euler's number
description: Adding another app to shinyproxy
container-cmd: ["R", "-e", "shiny::runApp('/root/euler')"]
container-image: openanalytics/shinyproxy-template
access-groups: scientists
- id: wca
display-name: Wasanii
description: WhatsApp Chat Analysis
container-cmd: ["R", "-e", "shiny::runApp('/root/wca')"]
container-image: wca
container-env:
FIREBASE_API_KEY: myfirebaseapikey
FIREBASE_PROJECT_ID: myfirebaseprojectid
FIREBASE_AUTH_DOMAIN: myfirebaseauthdomain
FIREBASE_STORAGE_BUCKET: myfirebasestoragebucket
FIREBASE_APP_ID: myfirebaseappid
FIREBASE_DATABASE_URL: myfirebasedatabaseurl
access-groups: scientists
logging:
file:
shinyproxy.log
There's obviously a better solution to refer to the .Renviron file directly but since I can't figure it out this will do.

How assign user to group in ansible?

What module do I need to use of Ansible to perform this action?
chown -R vmail:vmail /var/mail
Thanks!
Use file module and make sure to set
state: directory
, because recurse: yes
"Recursively set the specified file attributes on directory contents.
This applies only when state is set to directory."
- file:
state: directory
path: /var/mail
recurse: yes
owner: vmail
group: vmail
You need to use the file module, more information on Ansible file module documentation
The example from there :
- name: Recursively change ownership of a directory
file:
path: /etc/foo
recurse: yes
owner: foo
group: foo

How do you copy files from a Salt master and execute them on a Salt minion?

I want to copy a directory from my Salt master to my Salt Minion. All the files are executable. I want to then execute the files on my Salt minion.
I want to achieve this using a Salt state. This is what I have so far:
copy_scripts:
file.recurse:
- name: /root/scripts
- source: salt://files/scripts
- user: root
- group: root
- file_mode: 744
This puts the files on my Salt minion. How can I execute all the scripts inside?
You can do this with cmd.script. cmd.script will copy the file (script?) to the minion and run it in a single state.
https://docs.saltstack.com/en/latest/ref/states/all/salt.states.cmd.html#salt.states.cmd.script
You'd need a state for every script you wanted to run.
bonus points: You can use Jinja to loop through a list to generate the states automatically https://docs.saltstack.com/en/latest/topics/tutorials/states_pt3.html
After copying the directory to the desired path, you can use cmd.run to execute these scripts.

Decrypting ansible vault files before rsyncing

I encrypted a bunch of files (certificates) using the following script
for i in $(find . -type f); do ansible-vault encrypt $i --vault-password-file ~/.vault && echo $i encrypted ; done
During rsyncing I run something like this
- name: Copy letsencrypt files
synchronize:
src: "{{ path }}/letsencrypt/"
dest: /etc/letsencrypt/
rsync_path: "sudo rsync"
rsync_opts:
- "--delete"
- "--checksum"
- "-a"
notify:
- Reload Nginx
The problem I’ve faced is that the files that moved still remained encrypted. I thought ansible was smart enough to detect if it was encrypted and decrypt like how I do here
- name: Copy deploy private key
copy:
content: "{{ private_key_content }}"
dest: "/home/deploy/.ssh/id_rsa"
owner: deploy
group: deploy
mode: 0600
no_log: true
Back to the earlier question, how do I make sure the files in the folder/files are decrypted before rsyncing?
Edit:
I tried using the copy module since it is encryption aware but the module seems to be hanging. Noticed some issues with copy module for directories on ansible github and I am back to synchronize.
I also tried the with_fileglob approach but that flattens the directory structure.
Edit 2:
I got encryption, decryption to work with the copy module but its horribly slow.
There is already an issue https://github.com/ansible/ansible/issues/45161 at the ansible site open and the conclusion is:
Synchronize is a wrapper around rsync, I doubt that you can hook into the
process like that. You might want to implement a custom module doing this
or use something, which supports it.

Simple dotfiles install in zsh

How do I symlink all dotfiles on a dir to my home dir using zsh? i.e. I have a dir with .gitconfig in it, and I'd like to symlink it to ~/.gitconfig.
Thanks!
If you want the sym-links at your local dir to your home dir:
cd my-own-local-dir
for ifile in .*(.); do # notice the '(.)' matching only normal files
# rm -fv $ifile # COMMENTED OUT, removing the original...
ln -vs ~/$ifile $ifile # sym-links to your home dir...
done
You should try dotbot. It supports to manage dotfiles by using a yaml file. Easy for mapping :D
For example:
- link:
~/.config/terminator:
create: true
path: config/terminator
~/.vim: vim
~/.vimrc:
relink: true
path: vimrc
~/.zshrc:
force: true
path: zshrc

Resources