Encrypt your files by Ansible Vault

So, in previous blog I have given you a brief description about ansible roles. In this blog I am going to discuss about another very important topic that is ansible vault.

Why we need encryption?

We write our ansible playbook, jinja templates and other files in normal unencrypted format but we can’t keep our crucial information such as password in unencrypted format so that’s why we need encryption.

How we can encrypt?

Just like we use ansible-playbook to run our ansible playbooks we have a option called ansible-vault to do our encryption and decryption work. Here below some important and useful commands –

  • we use ansible-vault create a_file to create a encrypted file
$ ansible-vault create a_file
New Vault password: 
Confirm New Vault password:
  • we use ansible-vault encrypt a_existing_file to encrypt a existing file
$ ansible-vault encrypt a_existing_file 
New Vault password: 
Confirm New Vault password: 
Encryption successful
  • we use ansible-vault view a_file to view the encrypted file
$ ansible-vault view a_file 
Vault password: 
You are reading Aniruddha's Blog ;)
  • we use ansible-vault decrypt a_file to decrypt any encrypted file
$ ansible-vault decrypt a_file 
Vault password: 
Decryption successful

What is vault ID?

A vault ID is an identifier for one or more vault secrets. Vault IDs, you must provide an ID of your choosing and a source to obtain it’s password (either prompt or a file path). We use --vault-id to provide the ID. Here below examples how we do –

  • We encrypt a file with ID
$ ansible-vault encrypt --vault-id id1@prompt a_file 
New vault password (id1): 
Confirm vew vault password (id1): 
Encryption successful
  • we view a file with ID
$ ansible-vault view --vault-id id1@prompt a_file 
Vault password (id1): 
You are reading Aniruddha's Blog ;)
  • we decrypt a file with ID
$ ansible-vault decrypt --vault-id id1@prompt a_file 
Vault password (id1): 
Decryption successful

Thank you 🙂

Customize your vim like any other IDE

So, almost 2 years ago I heard about C programming language from my close friend and I thought I should give it a try and I asked “how can I start with it?” and he gave me some notes and said just install turboC++ and start writing code. So, I installed it and started with C language and eventually I got demotivated and quit programming after some time. Actually it was not fun and engaging with that environment. After one year in my college their was a seminar of network security and the guest speaker said that everyone should try python once and it is really amazing language. And I went home and searched for the python in the YouTube and found lots of tutorial on it and picked up one and that tutorial is using VSCode after that I loved that text editor and still I use it in my daily work.

In my recent days I got to know about a new text editor called vim and I recently installed and start using it. The most funny thing is when I first open a file with it I was not able to exit from it :p. Now I use it in most of the time while writing code. When you will first install it then it will look something below like this

The vim allow us to customize it however we want and we customize it by writing some code in the ~/.vimrc and if the file is not there you can add it by doing touch ~/.vimrc command. Now add below line to your file first.

syntax enable

set shell=/bin/bash

set tabstop=4
set shiftwidth=4
set expandtab
set number
set autoindent
set ruler
set showcmd
set hlsearch
set wrap
set linebreak
set noswapfile
set incsearch
set nohlsearch
set ignorecase
set smartcase
set showmatch
set showmode
set cursorline
set title
set clipboard=unnamedplus
set encoding=UTF-8

set nocompatible

set background=dark
set termguicolors

Now we will add some plugins in this file and then we are going to install it.There are couple of ways to install plugins and the way i like is by Vundle And the section below shows how to add plugins .

set rtp+=~/.vim/bundle/Vundle.vim
call vundle#begin()

Plugin 'VundleVim/Vundle.vim'
Plugin 'scrooloose/nerdTree' "Documents tree
Plugin 'davidhalter/jedi-vim' "python autocompletion
Plugin 'scrooloose/syntastic' "code syntaxis
Plugin 'Raimondi/delimitMate' "automatic closing of quotes, parenthesis...
Plugin 'yggdroot/indentline' "Show indent lines (useful for loops)
Plugin 'vim-airline/vim-airline'
Plugin 'vim-airline/vim-airline-themes'
Plugin 'ervandew/supertab' "<Tab> for code completion
Plugin 'jistr/vim-nerdtree-tabs'
Plugin 'ntpeters/vim-better-whitespace'
Plugin 'sjl/badwolf'
Plugin 'python/black'
Plugin 'andviro/flake8-vim'
Plugin 'fatih/vim-go'
Plugin 'tpope/vim-commentary'
Plugin 'airblade/vim-gitgutter'
Plugin 'jreybert/vimagit'
Plugin 'ryanoasis/vim-devicons'

call vundle#end()

autocmd BufWritePre *.py execute ':Black'
let g:black_linelength = 79

let g:PyFlakeOnWrite = 1
let g:PyFlakeCheckers = 'pep8,mccabe,frosted'
let g:PyFlakeDefaultComplexity=10
let g:PyFlakeDisabledMessages = 'E1101,C0111,E1136,W0703,C0103,C0330,W504'
let g:PyFlakeAggressive = 0
let g:PyFlakeCWindow = 6
let g:PyFlakeSigns = 1
let g:PyFlakeSignStart = 1
let g:PyFlakeForcePyVersion = 3

filetype plugin indent on

colorscheme badwolf

" Go syntax highlighting
let g:go_highlight_fields = 1
let g:go_highlight_functions = 1
let g:go_highlight_function_calls = 1
let g:go_highlight_extra_types = 1
let g:go_highlight_operators = 1

" Go preview disable
set completeopt-=preview

" Auto formatting and importing
let g:go_fmt_autosave = 1
let g:go_fmt_command = "goimports"

" Status line types/signatures
let g:go_auto_type_info = 1

" Run :GoBuild or :GoTestCompile based on the go file
function! s:build_go_files()
  let l:file = expand('%')
  if l:file =~# '^\f\+_test\.go$'
    call go#test#Test(0, 1)
  elseif l:file =~# '^\f\+\.go$'
    call go#cmd#Build(0)

" Map keys for most used commands.
" Ex: `\b` for building, `\r` for running and `\b` for running test.
autocmd FileType go nmap <leader>b :<C-u>call <SID>build_go_files()<CR>
autocmd FileType go nmap <leader>r  <Plug>(go-run)
autocmd FileType go nmap <leader>t  <Plug>(go-test)

au filetype go inoremap <buffer> . .<C-x><C-o>

" NERDTree setup
map <C-z> :NERDTreeToggle<CR> “ Toggle side window with `CTRL+z`.
let g:NERDTreeDirArrowExpandable = '▸'
let g:NERDTreeDirArrowCollapsible = '▾'
let NERDTreeShowHidden=1 " Show hidden files

" Vim airline
let g:airline_powerline_fonts=1
let g:airline#extensions#tabline#enabled = 1
let g:airline#extensions#tabline#left_sep = ' '
let g:airline#extensions#tabline#left_alt_sep = '|'
let g:airline#extensions#tabline#formatter = 'default'

" Git Gutter
" Use fontawesome icons as signs
let g:gitgutter_sign_added = '+'
let g:gitgutter_sign_modified = '>'
let g:gitgutter_sign_removed = '-'
let g:gitgutter_sign_removed_first_line = '^'
let g:gitgutter_sign_modified_removed = '<'

let g:gitgutter_override_sign_column_highlight = 1
highlight SignColumn guibg=bg
highlight SignColumn ctermbg=bg

set updatetime=250

nmap <Leader>gn <Plug>GitGutterNextHunk  " git next
nmap <Leader>gp <Plug>GitGutterPrevHunk  " git previous
nmap <Leader>ga <Plug>GitGutterStageHunk  " git add (chunk)
nmap <Leader>gu <Plug>GitGutterUndoHunk   " git undo (chunk)

" Open vimagit pane
nnoremap <leader>gs :Magit<CR>       " git status

" Move between buffers
map gn :bn<cr>
map gp :bp<cr>
map gd :bd<cr>

" Move line up and down
nnoremap K :m .-2<CR>==
nnoremap J :m .+1<CR>==
vnoremap K :m '<-2<CR>gv=gv
vnoremap J :m '>+1<CR>gv=gv

" Set Ctrl+h for highlight search
nnoremap <c-h> :set hlsearch!<cr>

" Disable K for documentation of go and py
let g:go_doc_keywordprg_enabled = 0
let g:jedi#documentation_command = 0

That’s how we add Plugins to the vim by writing Plugin and after that what plugin we want to install. Now to install plugins first type Esc then : and after that type PluginInstall then press enter and all the plugins will install one by one.

Now vim is looks something like blow image.

Thank you 🙂

Reusable playbooks, Ansible roles

So, in this blog I have told you about “what is Ansible, playbooks, hosts?” now it is the time to go further with roles. In the world of programming we have a principle called DRY which is “Don’t repeat yourself” means don’t do any work again and again. For that we try to make a process that we have to write the code one time and we can use it again and again without rewriting the whole code again and again.

In the era of automation Ansible also gives us a certain technique that if we need a part of playbook multiple files then we can write it inside a role and use it again and again. It also helps us to reduce the complexity of the code like it is always better to break down a big playbook in a small parts and use it.

Basically for the role we define it inside a roles directory. inside this directory we define or every role and inside the role their will be multiple directories below you can see it –

$ tree .
├── roles
│   └── webservers
│       ├── defaults
│       ├── files
│       ├── handlers
│       ├── meta
│       ├── tasks
│       ├── templates
│       └── vars
└── web.yml

Roles expect files to be in certain directory names. Roles must include at least one of these directories, however it is perfectly ok to exclude any which are not being used. When in use, each directory must contain a main.yml file, which contains the relevant content:

  • tasks – contains the main list of tasks to be executed by the role.
  • handlers contains handlers which may be used by the roles or elsewhere in the code.
  • defaults contains variables for the roles.
  • vars contains other variables for the roles.
  • files contains files which will deploy by the roles.
  • templates contains templates which can be deployed via roles.
  • meta contains meta data.

So, now see by example how roles helps us in the various aspects of automation. Below the code is without roles –

- hosts: webservers
  gather_facts: yes
  remote_user: root
  become: true
    - name: Ensure group {{ item }} exist
      name: "{{ item }}"
      state: present
      - mozilla
      - dgplug
  - name: add several users to several group
      name: "{{ item.name }}"
      state: present
      groups: "{{ item.groups }}"
      - { name: 'testuser1', groups: 'mozilla' }
      - { name: 'testuser2', groups: 'dgplug' }
  - name: remove several users to several group
      name: "{{ item.name }}"
      state: absent
      groups: "{{ item.groups }}"
      - { name: 'testuser1', groups: 'mozilla' }
      - { name: 'testuser2', groups: 'dgplug' }

Now see how we can implement this via roles –

# web.yml
- hosts: webservers
  become: true
    - role: '/home/aniruddha/Desktop/ansible-playbook/roles/webservers'

# roles/webservers/tasks/add_group/main.yml
  - name: Ensure group {{ item }} exist
    name: "{{ item }}"
    state: present
    - mozilla
    - dgplug

# roles/webservers/tasks/add_user_to_group/main.yml
  - name: add several users to several group
    name: "{{ item.name }}"
    state: present
    groups: "{{ item.groups }}"
    - { name: 'testuser1', groups: 'mozilla' }
    - { name: 'testuser2', groups: 'dgplug' }

# roles/webservers/tasks/remove_user_from_group/main.yml
  - name: Remove several users from different group
    name: "{{ item.name }}"
    state: absent
    group: "{{ item.groups }}"
    - { name: 'testuser1', groups: 'mozilla' }
    - { name: 'testuser2', groups: 'dgplug' }

Thank you 🙂