Skip to content

Commit

Permalink
Improved ansible repository, added github actions workflow for gitops
Browse files Browse the repository at this point in the history
  • Loading branch information
felbinger committed Aug 26, 2023
1 parent aa8168b commit d50690f
Show file tree
Hide file tree
Showing 7 changed files with 138 additions and 52 deletions.
67 changes: 67 additions & 0 deletions .github/workflows/gitops.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
---
name: GitOps

on:
push:
branches: [main, development]
pull_request:
schedule:
- cron: '53 1 */15 * *'

jobs:
lint:
runs-on: ubuntu-latest
container:
image: ghcr.io/secshellnet/ansible-vyos-lint

steps:
- uses: actions/checkout@v3

- name: Run ansible-lint
run: |
ansible-lint -x yaml[comments],yaml[empty-lines],\
yaml[new-line-at-end-of-file],yaml[trailing-spaces],\
var-spacing,command-instead-of-shell,no-changed-when,\
name[template],args[module]
run:
runs-on: ubuntu-latest
needs: [lint]

steps:
- uses: actions/checkout@v3
if: vars.ENABLE_GITOPS == '1'

- name: Prepare environment
if: vars.ENABLE_GITOPS == '1'
run: |
echo "${{ secrets.SSH_KEY }}" > .keys/id_ecdsa
chmod 600 .keys/id_ecdsa
ssh-keygen -f .keys/id_ecdsa -y > .keys/id_ecdsa.pub
echo "${{ secrets.ANSIBLE_KEYS_ALL }}" > .keys/all
git submodule update
ansible-galaxy collection install hetzner.hcloud
/opt/pipx/venvs/ansible-core/bin/python -m pip install -r requirements.txt
# not quiet sure why, but we need this package in this python environment
pip3 install python-dateutil
- name: Run ansible inventory in check mode
if: |
vars.ENABLE_GITOPS == '1' &&
github.event_name == 'pull_request'
env:
ANSIBLE_HOST_KEY_CHECKING: false
run: |
ansible-playbook playbook.yaml --check
- name: Deploy ansible inventory
if: |
vars.ENABLE_GITOPS == '1'
&& github.event_name != 'pull_request'
env:
ANSIBLE_HOST_KEY_CHECKING: false
run: |
ansible-playbook playbook.yaml
51 changes: 34 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,22 @@
# Secure Shell Networks: [Hetzner Cloud](https://www.hetzner.com/cloud) Ansible Inventory

This repository template provides a ansible inventory to manage cloud server in
hetzner cloud (hcloud). It performes some basic linux hardening (unattended upgrades,
ssh, fail2ban) and can be extended by roles or tasks to perform whatever you need.

## Getting started
1. Clone this git repository:
```shell
git clone https://github.com/secshellnet/hcloud-ansible.git
```
2. Install the required ansible and python modules:
1. Create a reporitory from this template repository and clone it:
```shell
ansible-galaxy collection install hetzner.hcloud
pip3 install ipaddress passlib
git clone git@github.com:YOUR-USERNAME/hcloud-ansible.git
```
3. Create account on [hetzner.cloud](https://console.hetzner.cloud/)
4. Create new cloud project
5. Create an api token inside this cloud project
2. Create account on [hetzner.cloud](https://console.hetzner.cloud/) and create a new cloud project
3. Create an api token inside this cloud project
![Creating an api token in the hetzner cloud console](./img/hetzner-create-api-token.png)
6. Generate a new secret for the ansible vault file
4. Generate a new secret for the ansible vault file (you can use any password generated, store it in `.keys/all`)
```shell
cat /dev/urandom | tr -dc A-Za-z0-9 | fold -w 59 | head -n 1 > .keys/all
cat /dev/urandom | tr -dc A-Za-z0-9 | fold -w 20 | head -n 1 > .keys/all
```
7. Create a new ansible vault
5. Create a new ansible vault
```shell
ansible-vault create group_vars/all/vault
```
Expand All @@ -28,7 +26,7 @@
hcloud_api_token: "__YOUR_API_TOKEN__"
worker_password: "__RANDOM_SECRET_PASSWORD__"
```
8. Extend the [`inventory.yaml`](./inventory.yaml), it should look for example like this:
6. Extend the [`inventory.yaml`](./inventory.yaml), it should look for example like this:
```yaml
---
all:
Expand All @@ -46,14 +44,33 @@
enable_ipv4: true
enable_ipv6: true
```
9. Use the ansible inventory:

7. Install the required ansible and python modules:
```shell
ansible-galaxy collection install hetzner.hcloud
pip3 install -r requirements.txt
```
8. Use the ansible inventory:
```shell
ansible-playbook playbook.yaml
```
10. Create a backup of the [`.keys`](./keys/) directory. It contains the key to your vault and the ssh key ansible uses to connect to the cloud servers. For security reasons this directory is excluded from git operations (see [`.gitignore`](./.gitignore)), so by default it will not be pushed to your git repository!
9. Create a backup of the [`.keys`](./keys/) directory. It contains the key to your vault
and the ssh key ansible uses to connect to the cloud servers. For security reasons this
directory is excluded from git operations (see [`.gitignore`](./.gitignore)), so by
default it will not be pushed to your git repository!

## TODO

## What about GitOps?
I've tried integrating git ops, but there is one problem: the GitHub actions runner does
not support ipv6... So you need an ipv4 address on each vm to use git ops for now.
Create the following github actions variables and secrets in your repository and make
sure to commit and push both your `inventory.yaml` and `group_vars/all/vault` file:
- Variable: `ENABLE_GITOPS` to value `1`
- Secret: `SSH_KEY` to content of [`.keys/id_ecdsa`](./keys/id_ecdsa)
- Secret: `ANSIBLE_KEYS_ALL` to the content of [`.keys/all`](./keys/all)
## TODO
| Feature | State | |
|:--------------------------------------------------------------------------------------------------------:|:-----------:|:-----------------------:|
| unattended-upgrades | test | |
Expand Down
36 changes: 2 additions & 34 deletions playbook.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,40 +14,8 @@
state: "restarted"

tasks:
- name: "Create low privileged unix user account {{ worker_user }}"
ansible.builtin.user:
name: "{{ worker_user }}"
groups: "sudo"
append: true
shell: "/bin/bash"
become: true

- name: "Set password for low priviledged unix user account {{ worker_user }}"
ansible.builtin.user:
name: "{{ worker_user }}"
password: "{{ worker_password | password_hash('sha512') }}"
password_lock: no
when: new_server

- name: "Ensure .ssh directory exists for {{ worker_user }}"
ansible.builtin.file:
state: directory
path: "/home/{{ worker_user }}/.ssh/"
owner: "{{ worker_user }}"
group: "{{ worker_user }}"
mode: "0700"
become: true

- name: "Copy ssh key of ansible to {{ worker_user }}"
ansible.builtin.copy:
src: ".keys/id_ecdsa.pub"
dest: "/home/{{ worker_user }}/.ssh/authorized_keys"
owner: "{{ worker_user }}"
group: "{{ worker_user }}"
mode: "0600"
become: true

- ansible.builtin.include_tasks: "tasks/ssh.yaml"
- ansible.builtin.include_tasks: "tasks/create-worker-user.yaml"
- ansible.builtin.include_tasks: "tasks/configure-sshd.yaml"

- name: "Install tools and requirements"
ansible.builtin.apt:
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
passlib>=1.7.4
File renamed without changes.
33 changes: 33 additions & 0 deletions tasks/create-worker-user.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
- name: "Create low privileged unix user account {{ worker_user }}"
ansible.builtin.user:
name: "{{ worker_user }}"
groups: "sudo"
append: true
shell: "/bin/bash"
become: true

- name: "Set password for low priviledged unix user account {{ worker_user }}"
ansible.builtin.user:
name: "{{ worker_user }}"
password: "{{ worker_password | password_hash('sha512') }}"
password_lock: no
when: new_server

- name: "Ensure .ssh directory exists for {{ worker_user }}"
ansible.builtin.file:
state: directory
path: "/home/{{ worker_user }}/.ssh/"
owner: "{{ worker_user }}"
group: "{{ worker_user }}"
mode: "0700"
become: true

- name: "Copy ssh key of ansible to {{ worker_user }}"
ansible.builtin.copy:
src: ".keys/id_ecdsa.pub"
dest: "/home/{{ worker_user }}/.ssh/authorized_keys"
owner: "{{ worker_user }}"
group: "{{ worker_user }}"
mode: "0600"
become: true
2 changes: 1 addition & 1 deletion tasks/hetzner-cloud.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
register: ssh_key_check
run_once: true

- name: "Generate new SSH key if not present"
- name: "Generate new ssh key if not present"
ansible.builtin.command: ssh-keygen -t ecdsa -b 384 -C "ansible@localhost" -N "" -f ".keys/id_ecdsa"
when: not ssh_key_check.stat.exists
run_once: true
Expand Down

0 comments on commit d50690f

Please sign in to comment.