homelab/playbooks/setup/alpine.yaml

223 lines
6.8 KiB
YAML

# > /COPILOT_GENERATE I'm writing an ansible playbook to setup a new alpine server, I want you to help me to generate some tasks
- name: Setup an alpine machine
hosts: homelab
user: root
vars_files:
../../variables/secrets.yaml
vars:
# alpine_version: v3.19
alpine_version: latest-stable
robo:
authorized_key: "{{ users.robo.ssh_keys.pub }}"
allowed_commands:
- "docker system dial-stdio"
tasks:
- name: Change login message
template:
src: ../../files/alpine/motd.j2
dest: /etc/motd
owner: root
group: root
mode: 0644
backup: yes
- name: Update repositories
template:
src: ../../files/alpine/repositories.j2
dest: /etc/apk/repositories
owner: root
group: root
mode: 0644
backup: yes
- name: Update all packages
command: /sbin/apk upgrade -U -a
- name: Be sure python is installed
command: /sbin/apk add python3
args:
creates: /usr/bin/python3
- name: Disable password authentication for SSH
become: true
notify: Restart sshd
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
regexp: '^#?PasswordAuthentication'
line: 'PasswordAuthentication no'
state: present
- name: Disable password authentication for SSH
become: true
notify: Restart sshd
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
regexp: '^#?PubkeyAuthentication'
line: 'PubkeyAuthentication yes'
state: present
- name: Allow users of the weel group to use doas command
become: true
ansible.builtin.lineinfile:
path: /etc/doas.conf
regexp: '^#\s*permit persist :wheel'
line: 'permit persist :wheel'
state: present
- name: Create a user group named docker
ansible.builtin.group:
name: docker
- name: Setup users
ansible.builtin.user:
state: present
name: aleidk
password: "{{ users.aleidk.password | password_hash('sha512') }}"
groups:
- wheel
- docker
- name: Create a user for executing remote commands
ansible.builtin.user:
name: robo
system: true
shell: /bin/sh
password: "*"
create_home: true
groups:
- nogroup
- docker
state: present
- name: Add SSH public key for robo user
ansible.posix.authorized_key:
user: robo
state: present
exclusive: true
key: "{{ robo.authorized_key }}"
key_options: "command=\"{{ robo.allowed_commands | join('; ') }}\""
- name: Setup Docker
hosts: docker
user: root
vars_files:
../../variables/secrets.yaml
tasks:
- name: Install packages
notify: Restart docker
ansible.builtin.package:
state: present
name:
- docker
- docker-cli-compose
- py3-yaml
- py3-pip
- py3-docker-py
- name: Start docker service
ansible.builtin.service:
name: docker
state: started
enabled: true
- name: Setup Docker Swarm
when: docker_swarm_manager | bool
block:
- name: Enable Docker Swarm mode
community.docker.docker_swarm:
state: present
- name: Create Traefik network
community.docker.docker_network:
name: reverse-proxy
driver: overlay
attachable: true
- name: Deploy Traefik service
community.docker.docker_compose_v2:
remove_orphans: true
project_name: reverse-proxy
definition:
networks:
reverse-proxy:
external: true
services:
traefik:
container_name: traefix-proxy
image: 'traefik:latest'
restart: unless-stopped
networks:
- reverse-proxy
ports:
# listen on host ports without ingress network
- target: 80
published: 80
protocol: tcp
mode: host
- target: 443
published: 443
protocol: tcp
mode: host
- target: 8080
published: 8080
protocol: tcp
mode: host
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
healthcheck:
test: 'wget -qO- http://localhost:80/ping || exit 1'
interval: 4s
timeout: 2s
retries: 5
command:
- '--ping=true'
- '--ping.entrypoint=http'
- '--api.dashboard=true'
- '--api.insecure=true'
- '--entrypoints.http.address=:80'
- '--entryPoints.http.forwardedHeaders.trustedIPs=10.0.10.0/24'
- '--entrypoints.http.http.encodequerysemicolons=true'
- '--entryPoints.http.http2.maxConcurrentStreams=50'
# - "--providers.swarm.endpoint=tcp://{{ ansible_default_ipv4.address }}:2375"
- --providers.swarm.exposedByDefault=false
- --providers.swarm.network=reverse-proxy
deploy:
mode: global
placement:
constraints:
- node.role==manager
labels:
- traefik.enable=true
- traefik.http.routers.traefik.entrypoints=http
- traefik.http.routers.traefik.service=api@internal
- traefik.http.services.traefik.loadbalancer.server.port=8080
- name: Check if Docker context exists
local_action: ansible.builtin.command docker context inspect {{ ansible_hostname }}
register: context_exists
ignore_errors: true
- name: Create Docker context for each Swarm manager machine
local_action: >
ansible.builtin.command docker context create {{ ansible_hostname }} --docker "host=ssh://{{ ansible_default_ipv4.address }}"
when: context_exists.stderr != ''
- name: Join Docker Swarm as a worker
community.docker.docker_swarm:
state: join
join_token: "{{ hostvars['manager']['docker_swarm_worker_token'] }}"
remote_addrs: ["{{ hostvars['manager']['ansible_default_ipv4']['address'] }}"]
when: not docker_swarm_manager | bool
handlers:
- name: Restart sshd
ansible.builtin.service:
name: sshd
state: restarted
- name: Restart docker
ansible.builtin.service:
name: docker
state: restarted