Using Ansible for Hosting a Blog on a Cloud Server
Tags: devops, ansible, cloud
Published: 2020-06-18 16:11:55

My blog [Admantium](https://admantium.com) is hosted on a cloud server managed with Ansible. This article shows you how to use the cloud computing provider Hetzner for setting up an Nginx server with TLS encryption. We will create the server via the management interface and install Nginx using ansible. Then we will get certificates form Lets Encrypt and configure Nginx to only provide HTTP connections.

_This article originally appeared at [my blog](https://admantium.com/blog/tech01_blog_in_the_cloud/)_.

## Creating Hetzner Cloud Server

[Hetzner](https://www.hetzner.com/cloud?country=us) is a German cloud computing provider. The reason I choose them is because they have good prices and a very usable Web UI. Furthermore, the have an [HTTP API](https://docs.hetzner.cloud/), as well as a CLI tool, Go and Python libraries.

Once you have an account, create a new project.

![](https://admantium.com/images/blog/tech/tech01_hetzner_projects.png)

Then add servers. Adding a server means: Decide the location, Linux image and type. Then, optional, add block storage and your SSH public key.

![](https://admantium.com/images/blog/tech/tech01_hetzner_konsole.png)

Before the first boot, you only have a limited number of images. But once the server runs, you can choose from a long list of even exotic Linux derivates.

![](https://admantium.com/images/blog/tech/tech01_hetzner_images.png)

Finally, once your server is running, you can see and configure it in the details view.

![](https://admantium.com/images/blog/tech/tech01_hetzner_server_overview.png)

## Installing Nginx

I install Nginx with the official [Ansible role from Nginx](https://github.com/nginxinc/ansible-role-nginx). This role gives you great amount of control: Install from OS or compile from sources, customize the nginx.conf, add other sites, and even upload certificates if you already have them. Check the available [basic configuration](https://github.com/nginxinc/ansible-role-nginx/blob/master/defaults/main/main.yml) and the [upload configuration](https://github.com/nginxinc/ansible-role-nginx/blob/master/defaults/main/upload.yml).

I use this ansible configuration:

```yaml
- name: Install nginx
  gather_facts: true
  hosts:
    - admantium
  tags:
    - nginx
  become: true
  vars:
    nginx_install_from: 'os_repository'
    nginx_repository: deb https://nginx.org/packages/mainline/debian/ stretch nginx
    nginx_main_upload_enable: true
    nginx_main_upload_src: config/nginx.conf
    nginx_main_upload_dest: /etc/nginx/
    nginx_http_upload_enable: true
    nginx_http_upload_src: config/http/*.conf
    nginx_http_upload_dest: /etc/nginx/conf.d/
  roles:
    - nginxinc.nginx
```

The role is executed, Nginx is installed.

## Get Certificates with Let's Encrypt

The installation of valid certificates with [Lets Encrypt](https://letsencrypt.org/) is nothing short of pleasure: Install and run the `certbot` program.

```bash
apt-get install certbot python-certbot-nginx
certbot certonly --nginx
```

The script then asks you to automatically customize your Nginx config, or it shows you the paths to the generated certificates. I opted for the latter, and manually inserted it.

```nginx
server {
  server_name admantium.com;
  listen 443 ssl http2;

  ssl_certificate /etc/letsencrypt/live/admantium.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/admantium.com/privkey.pem;
```

Then I added a simple "Hello World" index page and accessed the server to see the certificate being used in a HTTPS connection.

![](https://admantium.com/images/blog/tech/tech01_nginx_lets_encrypt_certificate.png)

## Securing the Web Server

The final part is to make the TLS connection even more secure. After reading a [list of security aspects](https://github.com/trimstray/nginx-admins-handbook/blob/master/doc/RULES.md#beginner-use-only-the-latest-supported-openssl-version), I learned the following:

* Only allow `TLSv1.2` and `TLSv1.3`, older version have been compromised
* Configure the server to offer a carefully selected set of `ssl_ciphers` and tell the client to select one of them
* Set the `Strict-Transport-Security` header, and proper redirects, to only allow TLS connections.

This is achieved with the following config:

```nginx
##
# SSL Settings
##

ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256";
ssl_prefer_server_ciphers on;
ssl_ecdh_curve secp521r1:secp384r1;
add_header Strict-Transport-Security "max-age=15768000; preload" always;
```

Once in place, I use the  [SSL labs scanner](https://www.ssllabs.com/ssltest/) and could improve the score from C to A. Great result!

![tech01_check_ssl_labs](https://admantium.com/images/blog/tech/tech01_check_ssl_labs.png)

## Conclusion

This article showed you how to setup a server with the cloud computing provider. You also learned how to apply the official Nginx Ansible role to install and configure the webserver. Finally I showed you how to get certificates with lets encrypt and how to improve your Nginx TLS config.