This post was originally published at thbe.org.
As promised in the previous post Harmonize basic set up with Ansible, part 1 I would like to dig deeper into the details about the common role. This is how it looks like in the filesystem:
roles
└── common
├── files
│ └── user
│ ├── alias.plugin.zsh
│ ├── docker.plugin.zsh
│ ├── functions.plugin.zsh
│ ├── git.plugin.zsh
│ ├── jekyll.plugin.zsh
│ ├── nerd.plugin.zsh
│ ├── puppet.plugin.zsh
│ └── ruby.plugin.zsh
├── tasks
│ ├── localtime.yml
│ ├── main.yml
│ ├── motd.yml
│ ├── networking.yml
│ ├── repositories.yml
│ ├── tools.yml
│ ├── upgrade.yml
│ └── user.yml
└── templates
├── ifcfg-interface.j2
├── motd.j2
├── network.j2
└── route-interface.j2
The most important file is the main.yml file. This file defines which tasks will be executed in which order when the common role is called. So we need one file that calls the role (in my case common.yml):
---
# Common playbook needs to executed first
- name: Common configuration shared for all nodes
hosts: all
remote_user: root
gather_facts: true
roles:
- common
Once the role is called, it first calls the file main.yml:
---
# Main playbook for common configuration
#- include: networking.yml
- include: motd.yml
- include: localtime.yml
- include: repositories.yml
- include: upgrade.yml
- include: tools.yml
- include: user.yml
Based on the fact that this is only a demonstration I've deactivated the network part. This part expects at least three network devices attached to different network segments like internal, backup, MPLS and so on and so forth. As all nodes of this demonstration only have one network interface, this configuration won't work anyway. So let's go through the tasks that are active and that will work. First of all, I'll set the message of the day:
---
- name: Message of the day setup
template:
src: motd.j2
dest: /etc/motd
owner: root
group: root
mode: 0644
This is a pretty simple task, it takes the motd.j2
template (all templates end with j2 because of all are Jinja2 templates) which is stored in the template directory of the common role. This template will be stored on the target node under /etc/motd
with the access rights 0644
. Let's have a look at a slightly more complex example, the user configuration. The task itself looks like:
---
# Create all users defined in local_user (group_vars/all.yml)
- name: Create personal user account
user:
name: "{{ item }}"
password: "!"
shell: /usr/bin/zsh
groups: wheel
generate_ssh_key: yes
ssh_key_bits: 2048
ssh_key_file: .ssh/id_rsa
loop: "{{ local_user }}"
# Add local public rsa key to authorized_keys for all users defined in local_user (group_vars/all.yml)
# This one needs to be reworked for multiple named users)
- name: Add remote authorized key to allow future password-less logins
authorized_key:
user: "{{ item }}"
key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
loop: "{{ local_user }}"
# Add all users defined in local_user (group_vars/all.yml) to sudo administration group
- name: Add personal user to sudoers
lineinfile:
path: /etc/sudoers
regexp: "{{ item }} ALL"
line: "{{ item }} ALL=(ALL) NOPASSWD: ALL"
state: present
validate: "/usr/sbin/visudo -cf %s"
loop: "{{ local_user }}"
# Install oh-my-zsh for all users defined in local_user (group_vars/all.yml)
- name: Download oh-my-zsh installer
get_url:
url: https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh
dest: /srv/oh-my-zsh-install.sh
- name: Make oh-my-zsh-install.sh executable for all
file:
path: /srv/oh-my-zsh-install.sh
mode: 0755
- name: Execute the zsh-installer.sh
command:
cmd: /srv/oh-my-zsh-install.sh
creates: /home/{{ item }}/.oh-my-zsh
become: yes
become_user: "{{ item }}"
loop: "{{ local_user }}"
- name: Remove oh-my-zsh-install.sh
file:
path: /srv/oh-my-zsh-install.sh
state: absent
# Install typewritten for all users defined in local_user (group_vars/all.yml)
- name: Deploy typewritten theme to oh-my-zsh using git
git:
repo: https://github.com/thbe/typewritten.git
dest: /home/{{ item }}/.oh-my-zsh/custom/themes/typewritten
loop: "{{ local_user }}"
# Deploy zsh configuration file to all users defined in local_user (group_vars/all.yml)
- name: Deploy local zsh user configuration - .zshrc
copy:
src: user/.zshrc
dest: /home/{{ item }}/.zshrc
owner: "{{ item }}"
group: "{{ item }}"
mode: 0640
loop: "{{ local_user }}"
# Deploy plugin configuration files to all users defined in local_user (group_vars/all.yml)
- name: Create .profile.d directory
file:
path: /home/{{ item }}/.profile.d
state: directory
owner: "{{ item }}"
group: "{{ item }}"
mode: 0750
loop: "{{ local_user }}"
- name: Deploy local zsh user configuration - alias.plugin.zsh
copy:
src: user/alias.plugin.zsh
dest: /home/{{ item }}/.profile.d/alias.plugin.zsh
owner: "{{ item }}"
group: "{{ item }}"
mode: 0640
loop: "{{ local_user }}"
- name: Deploy local zsh user configuration - docker.plugin.zsh
copy:
src: user/docker.plugin.zsh
dest: /home/{{ item }}/.profile.d/docker.plugin.zsh
owner: "{{ item }}"
group: "{{ item }}"
mode: 0640
loop: "{{ local_user }}"
- name: Deploy local zsh user configuration - functions.plugin.zsh
copy:
src: user/functions.plugin.zsh
dest: /home/{{ item }}/.profile.d/functions.plugin.zsh
owner: "{{ item }}"
group: "{{ item }}"
mode: 0640
loop: "{{ local_user }}"
- name: Deploy local zsh user configuration - git.plugin.zsh
copy:
src: user/git.plugin.zsh
dest: /home/{{ item }}/.profile.d/git.plugin.zsh
owner: "{{ item }}"
group: "{{ item }}"
mode: 0640
loop: "{{ local_user }}"
- name: Deploy local zsh user configuration - jekyll.plugin.zsh
copy:
src: user/jekyll.plugin.zsh
dest: /home/{{ item }}/.profile.d/jekyll.plugin.zsh
owner: "{{ item }}"
group: "{{ item }}"
mode: 0640
loop: "{{ local_user }}"
- name: Deploy local zsh user configuration - nerd.plugin.zsh
copy:
src: user/nerd.plugin.zsh
dest: /home/{{ item }}/.profile.d/nerd.plugin.zsh
owner: "{{ item }}"
group: "{{ item }}"
mode: 0640
loop: "{{ local_user }}"
- name: Deploy local zsh user configuration - puppet.plugin.zsh
copy:
src: user/puppet.plugin.zsh
dest: /home/{{ item }}/.profile.d/puppet.plugin.zsh
owner: "{{ item }}"
group: "{{ item }}"
mode: 0640
loop: "{{ local_user }}"
- name: Deploy local zsh user configuration - ruby.plugin.zsh
copy:
src: user/ruby.plugin.zsh
dest: /home/{{ item }}/.profile.d/ruby.plugin.zsh
owner: "{{ item }}"
group: "{{ item }}"
mode: 0640
loop: "{{ local_user }}"
What does this task do? First, it creates user IDs in a loop. Therefore it looks up local_user
which is defined in the group_vars all.yml
configuration file:
---
# Users that should be available on all target nodes
local_user:
- ansible
- thbe
Each user is transferred into the item
variable and process one by one. The user will be created, the password disabled (we'll use SSH keys instead), the primary shell is set to ZSH, the SSH keys for the users are created and the users are added to the administrator group.
The next step is that my local public key will be added to the authorized_keys
of each user so I can log in without a password. The users will be included in the /etc/sudoers
configuration and finally, oh-my-zsh will be installed as well as my preferred theming and last but not least, my personal functions and aliases.
Top comments (0)