Skip to content

Commit 7b70063

Browse files
authored
feat: manage Caddyfile with a docker config (#50)
* feat: manage caddy file with a config * fix: make sure the lock is released when merging to master * fix: caddyfile path * fix: accessing assest in sub-role * fix: checksum gathering * fix: we need to index loops * test: debug file stats * fix: caddyfile path * fix: creating config * fix: init file path update * fix: checksums paths * chore: use the new create config and remove unused checksum file * chore: rename config to caddy_global_caddyfile * fix: typo config vs configs
1 parent 2460897 commit 7b70063

File tree

10 files changed

+85
-47
lines changed

10 files changed

+85
-47
lines changed

.github/workflows/ansible.yml

+4
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ on:
1919
# Allows you to run this workflow manually from the Actions tab
2020
workflow_dispatch:
2121

22+
# Trigger on main to clear the lock
23+
push:
24+
branches: [ "main" ]
25+
2226
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
2327
jobs:
2428

ansible/roles/docker-swarm-app-caddy/assets/Caddyfile

+6-6
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
dynamic_dns {
1010
provider digitalocean {env.DIGITALOCEAN_API_TOKEN}
1111
domains {
12-
{{domain}} @ www
12+
{$DOMAIN} @ www
1313
}
1414
dynamic_domains
1515
}
@@ -20,7 +20,7 @@
2020
authentication portal myportal {
2121
crypto default token lifetime 3600
2222
crypto key sign-verify {env.JWT_SHARED_KEY}
23-
cookie domain {{domain}}
23+
cookie domain {$DOMAIN}
2424
enable identity provider github
2525
ui {
2626
links {
@@ -36,7 +36,7 @@
3636
}
3737

3838
authorization policy admins_policy {
39-
set auth url https://auth.{{domain}}/oauth2/github
39+
set auth url https://auth.{$DOMAIN}/oauth2/github
4040
crypto key verify {env.JWT_SHARED_KEY}
4141
allow roles authp/admin authp/user
4242
validate bearer header
@@ -58,15 +58,15 @@
5858
}
5959

6060
# Snippet enable automatic DNS configuration
61-
(external-dns) {
61+
(dns-challenge) {
6262
tls {
6363
dns digitalocean {env.DIGITALOCEAN_API_TOKEN}
6464
}
6565
}
6666

6767
# Auth endpoint for caddy security
68-
auth.{{domain}} {
69-
import external-dns
68+
auth.{$DOMAIN} {
69+
import dns-challenge
7070
authenticate with myportal
7171
}
7272

ansible/roles/docker-swarm-app-caddy/assets/caddy-stack.yml

+8-1
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,18 @@ services:
1717
- caddy
1818
volumes:
1919
- /var/run/docker.sock:/var/run/docker.sock
20-
- "{{ caddy_dir }}/Caddyfile:/etc/caddy/Caddyfile"
2120
- caddy_data:/data
2221
- caddy_config:/config
22+
configs:
23+
- source: caddy_global_caddyfile
24+
target: "/etc/caddy/Caddyfile"
2325
secrets:
2426
- caddy_github_client_id
2527
- caddy_github_client_secret
2628
- caddy_jwt_shared_key
2729
- caddy_digitalocean_api_token
2830
environment:
31+
DOMAIN: "{{ domain }}"
2932
GITHUB_CLIENT_ID_FILE: /run/secrets/caddy_github_client_id
3033
GITHUB_CLIENT_SECRET_FILE: /run/secrets/caddy_github_client_secret
3134
JWT_SHARED_KEY_FILE: /run/secrets/caddy_jwt_shared_key
@@ -58,6 +61,10 @@ volumes:
5861
caddy_data:
5962
caddy_config:
6063

64+
configs:
65+
caddy_global_caddyfile:
66+
external: true
67+
6168
networks:
6269
caddy:
6370
attachable: true

ansible/roles/docker-swarm-app-caddy/tasks/main.yaml

+15-3
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,31 @@
1313
state: directory
1414
mode: '0644'
1515

16+
- name: Define asssets folder
17+
set_fact:
18+
assets_path: "{{ role_path }}/assets"
19+
1620
- name: Copy Compose file to remote server
1721
template:
1822
src: "{{ item }}"
1923
dest: "{{ caddy_dir }}"
2024
mode: '0644'
2125
with_fileglob:
22-
- "{{ role_path }}/assets/*-stack.yml"
23-
- "{{ role_path }}/assets/Caddyfile"
24-
- "{{ role_path }}/assets/Dockerfile"
26+
- "{{ assets_path }}/*-stack.yml"
27+
- "{{ assets_path }}/Caddyfile"
28+
- "{{ assets_path }}/Dockerfile"
2529

2630
###
2731
# Create Caddy Pre-requisits
2832
###
33+
- name: Manager Caddy Configs
34+
include_role:
35+
name: utils-rotate-docker-configs
36+
vars:
37+
docker_compose_path: "{{ caddy_dir }}/caddy-stack.yml"
38+
configs:
39+
- {name: 'caddy_global_caddyfile', file_path: "{{ caddy_dir }}/Caddyfile"}
40+
2941
- name: Manager Caddy Secrets
3042
include_role:
3143
name: utils-rotate-docker-secrets
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
docker_compose_path: "{{ undef(hint='You must specify docker-compose file to update') }}"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
- name: List all Docker configs managed by this role
2+
command: docker config ls --filter label=managed_by=rotate_docker_configs --format "{{ '{{ .Name }}' }}"
3+
register: existing_configs
4+
changed_when: false
5+
6+
- name: Identify configs to keep
7+
set_fact:
8+
configs_to_keep: "{{ configs_to_keep | default([]) + [item.name + '_' + config_checksums[item.name]] }}"
9+
loop: "{{ configs }}"
10+
11+
- name: Remove dangling configs
12+
docker_config:
13+
name: "{{ item }}"
14+
state: absent
15+
when: item not in configs_to_keep
16+
loop: "{{ existing_configs.stdout_lines }}"
17+
ignore_errors: true
18+
register: ignore_errors_register
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
dependencies: []
2+
# List your role dependencies here, one per line. Be sure to remove the '[]' above,
3+
# if you add dependencies to this list.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
- name: Gather file stats and checksums
2+
stat:
3+
path: "{{ item.file_path }}"
4+
checksum: md5
5+
loop: "{{ configs }}"
6+
register: file_stats
7+
8+
- name: Create dictionary of checksums
9+
set_fact:
10+
config_checksums: "{{ config_checksums | default({}) | combine({ item.name: file_stats.results[idx].stat.checksum }) }}"
11+
loop: "{{ configs }}"
12+
loop_control:
13+
index_var: idx
14+
15+
- name: Create new configs if value has changed
16+
docker_config:
17+
name: "{{ item.name }}_{{ config_checksums[item.name] }}"
18+
data_src: "{{ item.file_path }}"
19+
state: present
20+
labels:
21+
managed_by: "rotate_docker_configs"
22+
name: "{{ item.name }}"
23+
loop: "{{ configs }}"
24+
25+
- name: Replace config names in Docker Compose file
26+
replace:
27+
path: "{{ docker_compose_path }}"
28+
regexp: "{{ item.name }}(_[a-f0-9]{32})?"
29+
replace: "{{ item.name }}_{{ config_checksums[item.name] }}"
30+
loop: "{{ configs }}"
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
1-
checksum_directory: /var/data/ansible
21
docker_compose_path: "{{ undef(hint='You must specify docker-compose file to update') }}"

ansible/roles/utils-rotate-docker-secrets/tasks/main.yaml

-36
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,3 @@
1-
- name: Ensure checksum directory exists
2-
file:
3-
path: "{{ checksum_directory }}"
4-
mode: '0644'
5-
state: directory
6-
71
- name: Calculate checksums for secrets
82
set_fact:
93
secret_checksums: "{{ secret_checksums
@@ -13,27 +7,6 @@
137
| cut -d\" \" -f1')}) }}"
148
loop: "{{ secrets }}"
159

16-
- name: Check if previous checksums file exists
17-
stat:
18-
path: "{{ checksum_directory }}/secrets.ini"
19-
register: previous_checksums_file
20-
21-
- name: Load previous checksums if file exists
22-
set_fact:
23-
previous_checksums: "{{ previous_checksums
24-
| default({})
25-
| combine({
26-
item.name: lookup(
27-
'ansible.builtin.ini',
28-
'checksum',
29-
section=item.name,
30-
file=checksum_directory + '/secrets.ini'
31-
)
32-
})
33-
}}"
34-
loop: "{{ secrets }}"
35-
when: previous_checksums_file.stat.exists
36-
3710
- name: Create new secrets if value has changed
3811
docker_secret:
3912
name: "{{ item.name }}_{{ secret_checksums[item.name] }}"
@@ -45,15 +18,6 @@
4518
when: (previous_checksums[item.name] is not defined) or (previous_checksums[item.name] != secret_checksums[item.name])
4619
loop: "{{ secrets }}"
4720

48-
- name: Update checksums file
49-
ini_file:
50-
path: ./secrets.ini
51-
section: "{{ item.name }}"
52-
option: checksum
53-
value: "{{ secret_checksums[item.name] }}"
54-
mode: '0644'
55-
loop: "{{ secrets }}"
56-
5721
- name: Replace secret names in Docker Compose file
5822
replace:
5923
path: "{{ docker_compose_path }}"

0 commit comments

Comments
 (0)