Fun with Ansible

It was Black Friday last week and as per tradition, I purchased another OVH VPS to at half price to replace my expired one.

For the past 3 years, I ssh into the server and used the command to pull Docker images and config files from a git repo. This year, I tested out Ansible to automate setting up the VPS. The learning curve wasn’t too bad but I did run into a few problems here and there.

I’ve migrated all my previous blog posts to corresponding ansible roles.

New user

This role starts firewall with ssh port, creates a new user for ssh and remove root ssh login.

---
- name: install unattended upgrade
  apt:
    name: ""
  loop:
    - unattended-upgrades
    - fail2ban

- name: unattended upgrade config
  template:
    src: 10periodic.j2
    dest: /etc/apt/apt.conf.d/10periodic
    owner: root
    group: root
    mode: 0644

- name: start ufw with port 22
  ufw:
    state: enabled
    rule: allow
    port: 22

- name: Add a new user
  user:
    name: ""
    groups: sudo
    append: yes
    shell: /bin/bash
    password: ""

- name: Add ssh key
  authorized_key:
    user: ""
    key: ""

- name: Setup ssh config
  lineinfile:
    path: /etc/ssh/sshd_config
    regexp: ""
    line: ""
  loop:
    - regexp: '^PasswordAuthentication'
      line: 'PasswordAuthentication no'
    - regexp: '^PermitRootLogin'
      line: 'PermitRootLogin no'
  notify:
    - restart ssh

Secure VPS

This makes the server more secure and email me daily report. It’s pretty crazy how many ssh attempts my new VPS gets everyday.

---
- name: install postfix, fail2ban and logwatch
  apt:
    name: ""
    update_cache: yes
  loop:
    - unattended-upgrades
    - postfix
    - logwatch
    - fail2ban

- name: unattended upgrade config
  template:
    src: 10periodic.j2
    dest: /etc/apt/apt.conf.d/10periodic
    owner: root
    group: root
    mode: 0644

- name: Create fail2ban config
  template:
    src: jail.local.j2
    dest: /etc/fail2ban/jail.local
    owner: root
    group: root
    mode: 0644
  notify:
    - restart fail2ban

- name: Create postfix conf
  template:
    src: main.cf.j2
    dest: "/main.cf"
    owner: root
    group: root
    mode: 0644

- name: Create sasl password file
  template:
    src: mailgun.j2
    dest: "/mailgun"
    owner: root
    group: root
    mode: 0600

- name: Update postfix table
  command: postmap "/mailgun"
  notify:
    - restart postfix

- name: Setup logwatch cron
  lineinfile:
    path: /etc/cron.daily/00logwatch
    regexp: "^/usr/sbin/logwatch"
    line: "/usr/sbin/logwatch --mailto  --detail high"

docker

I use gitlab to host some docker images. I utilise private repo to build docker images with sensitive data. I’m not sure it’s a good idea to keep username, password and api key inside images. Would it be better to expose those via env variables?

---
- name: Install packages
  apt:
    name: ""
    update_cache: yes
  loop:
    - apt-transport-https
    - ca-certificates
    - python3-pip

- name: Add Docker's GPG key
  apt_key:
    url: https://download.docker.com/linux/ubuntu/gpg
    id: 9DC858229FC7DD38854AE2D88D81803C0EBFCD88

- name: Add Docker repo
  apt_repository:
    repo: ""

- name: Install docker
  apt:
    name: docker-ce

- name: Install docker compose
  get_url:
    url: "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-Linux-x86_64"
    dest: /usr/local/bin/docker-compose
    mode: 0755

- name: Install docker and docker-compose pip
  pip:
    name: ""
  loop:
    - docker
    - docker-compose

- name: Add docker group
  group:
    name: docker

- name: Add user to docker group
  user:
    name: ""
    groups: docker
    append: yes
  notify:
    - reboot

- name: Log into gitlab docker repo
  docker_login:
    registry: registry.gitlab.com
    username: ""
    password: ""
    config_path: "/home//.docker/config.json"

- name: Copy docker-compose.yml to remote
  template:
    src: docker-compose.yml.j2
    dest: "/home//docker-compose.yml"
    owner: ""
    group: ""

- name: Start docker compose
  become: false
  docker_service:
    project_src: "/home/"

VPN

---
- name: Add wireguard ppa
  apt_repository:
    repo: "ppa:wireguard/wireguard"

- name: Install wireguard
  apt:
    name: wireguard

- name: Allow forwarding
  lineinfile:
    path: /etc/sysctl.conf
    regexp: ""
    line: ""
  loop:
    - regexp: '^#net.ipv4.ip_forward'
      line: 'net.ipv4.ip_forward=1'
    - regexp: '^#net.ipv6.conf.all.forwarding'
      line: 'net.ipv6.conf.all.forwarding=1'
  notify:
    - restart sysctl

- name: Open ufw port
  ufw:
    state: enabled
    rule: allow
    port: ""

- name: Create wg config
  template:
    src: wg.conf.j2
    dest: "/wg.conf"
    owner: root
    group: root
    mode: 0600

- name: Start wg
  service:
    name: wg-quick@wg
    state: started
    enabled: yes

- name: Allow ovh ipv6
  template:
    src: 50-cloud-init.yaml.j2
    dest: "/50-cloud-init.yaml"
    owner: root
    group: root
    mode: 0644
  when: (ansible_distribution == "Ubuntu" and ansible_distribution_major_version == "18")
  notify:
    - restart netplan