Skip to content

Cloud Init

Introduction

Today I had to upgrade my Ubuntu server. The loads running on the server are not critical and could survive some downtime. For tinkering and hosting my own work loads I use Hetzer. It’s extremely well balanced between complexity and features. The UI is simple and intuitive. VPS for 2.99Euro a months is also extremely nice.

But there is a small problem. Last time I provisioned servers with Ansible was a couple of years ago. While I still had the configuration available, it hasn’t been maintained simply because there was no need. After the initial set up, there’s a very limited set of commands one has to run.

I read abit Ansible’s docs but quickly realised that it’s not what I should or want to do at this point. The goal is to install and config a fresh Ubuntu server. Not automate provisioning, installation and management of hundreds servers.

I still didn’t feel like doing it manually. But maybe it’s not that bad I though. Before pressing “Create a server” button on Hetzner I noticed a text box which said “Cloud config with cloud-init” this looks interesing I thought. And here we go again.

Advantages of cloud-init:

  • industry standard
  • supported by all major and not that major cloud providers
  • simple to read and to manage
  • bullet proof, the same cloud-config which worked 10 years ago will work today

Disadvantages of cloud-init:

  • hard to debug

But this is just what I needed! After quick search I found a suitable base for my config. All I basically wanted is to create a user, install a couple of packages and configure sshd.

End result

Here is the cloud-config file so far:

1

#cloud-config
users:
  - name: kotir
    groups: users, admin, docker
    sudo: ALL=(ALL) NOPASSWD:ALL
    shell: /bin/bash
    ssh_authorized_keys:
      - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBi0KVsjB4qS1dHixjjN+6TdBeVS1C6al0rHESw9eXmj ilja@mailbox.org

packages:
  - fail2ban
  - ufw
  - make
package_update: true
package_upgrade: true

write_files:
  - path: /etc/ssh/sshd_config.d/ssh-hardening.conf
    content: |
      PermitRootLogin no
      PasswordAuthentication no
      Port 22
      KbdInteractiveAuthentication no
      ChallengeResponseAuthentication no
      MaxAuthTries 5
      AllowTcpForwarding no
      X11Forwarding no
      AllowAgentForwarding no
      ClientAliveInterval 300
      ClientAliveCountMax 3
      AuthorizedKeysFile .ssh/authorized_keys
      AllowUsers kotir

runcmd:
  - printf "[sshd]\nenabled = true\nport = ssh, 22\nbanaction = iptables-multiport" > /etc/fail2ban/jail.local
  - systemctl enable fail2ban
  - ufw allow 22
  - ufw allow 80,443/tcp
  - ufw enable
  - sudo groupadd docker
  - sudo usermod -aG docker $USER
  - newgrp docker
  - curl -fsSL https://get.docker.com -o get-docker.sh
  - sh get-docker.sh
  - reboot

One can also store the file on a remote server and use it like this:

#include
https://example.com/cloud-config.txt