Setting up a website with Ansible
Create VPS
Create a new VPS (virtual private server), I chose to host my VPS on DigitalOcean. I’ve already uploaded my Mac’s public key to DigitalOcean, so it is installed automatically. This will allow ansible to connect without a password.
The ansible and config files I use are at the bottom of this post.
Inital config
ansible-playbook initial_server_setup.yml -i hosts -l nickbodmer.com -u root
This initial configuration playbook will:
- create ‘wheel’ group (which probably already exists)
- enable passwordless sudo
- create my user ‘nick’ with sudo privileges
- add my ssh key to that new user
- disable password authentication for root
- update apt
- install a few packages, most importantly UFW firewall
- allow SSH through the firewall
- enable the firewall
nginx setup
ansible-playbook -i hosts -l nickbodmer.com nginx.yml
This playbook will:
- Install and start nginx
- open ports 80 and 443 for http and https
- copy the nginx config file to the server
- symlink the config file to sites-enabled
- restart nginx
At this point we have a fully running http webserver
letsencrypt using certbot
certbot will automatically configure nginx to use https and set a cron job to automatically renew your certfiicates.
Add certbot repository
sudo add-apt-repository ppa:certbot/certbot
install certbot for nginx
sudo apt install python-certbot-nginx
install cert for domain
sudo certbot --nginx -d nickbodmer.com -d www.nickbodmer.com
Files needed:
hosts
[cloud]
nickbodmer.com
[cloud:vars]
ansible_python_interpreter=/usr/bin/python3
[local]
192.168.1.206
initial_server_setup.yml
###########################################################################################################
# DO Community Playbooks
# Playbook: Initial Server Setup
# Based on: https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-18-04
# Dedicated Guide: https://www.digitalocean.com/community/tutorials/automating-initial-server-setup-with-ansible
###################################################################################################################
---
- hosts: all
remote_user: root
gather_facts: false
vars:
create_user: nick
copy_local_key: "{{ lookup('file', lookup('env','HOME') + '/.ssh/id_rsa.pub') }}"
sys_packages: [ 'curl', 'vim', 'git', 'ufw']
tasks:
- name: Make sure we have a 'wheel' group
group:
name: wheel
state: present
- name: Allow 'wheel' group to have passwordless sudo
lineinfile:
path: /etc/sudoers
state: present
regexp: '^%wheel'
line: '%wheel ALL=(ALL) NOPASSWD: ALL'
validate: '/usr/sbin/visudo -cf %s'
- name: Create a new regular user with sudo privileges
user:
name: "{{ create_user }}"
state: present
groups: wheel
append: true
create_home: true
shell: /bin/bash
- name: Set authorized key for remote user
authorized_key:
user: "{{ create_user }}"
state: present
key: "{{ copy_local_key }}"
- name: Disable password authentication for root
lineinfile:
path: /etc/ssh/sshd_config
state: present
regexp: '^#?PermitRootLogin'
line: 'PermitRootLogin prohibit-password'
- name: Update apt
apt: update_cache=yes
- name: Install required system packages
apt: name={{ sys_packages }} state=latest
- name: UFW - Allow SSH connections
ufw:
rule: allow
name: OpenSSH
- name: UFW - Deny all other incoming traffic by default
ufw:
state: enabled
policy: deny
direction: incoming
nginix_config.cfg
server {
listen 80;
listen [::]:80;
server_name nickbodmer.com www.nickbodmer.com;
root /home/nick/nickbodmer.com/;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
nginx.yml
---
- hosts: all
tasks:
- name: ensure nginx is at the latest version
apt: name=nginx state=latest
become: yes
- name: start nginx
service:
name: nginx
state: started
become: yes
- name: UFW - Allow http/https connections
ufw:
rule: allow
name: 'Nginx Full'
become: yes
- name: copy the nginx config file and restart nginx
copy:
src: /Users/nick/Google Drive/Sync/Documents/Ansible/nginx_config.cfg
dest: /etc/nginx/sites-available/nginx_config.cfg
become: yes
- name: create symlink
file:
src: /etc/nginx/sites-available/nginx_config.cfg
dest: /etc/nginx/sites-enabled/default
state: link
become: yes
- name: restart nginx
service:
name: nginx
state: restarted
become: yes