15 Commits

24 changed files with 436 additions and 81 deletions

2
.gitignore vendored
View File

@@ -3,6 +3,7 @@
ext_roles/*
!ext_roles/.gitkeep
test.yml
.ansible/*
# pyenv
.venv/*
@@ -13,7 +14,6 @@ test.yml
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
*.code-workspace
# Local History for Visual Studio Code
.history/

14
CHANGELOG.md Normal file
View File

@@ -0,0 +1,14 @@
# changelog
## 0.2.0
* [role] ⚠️ rename `set_locale` to `locale_config` along with the variable names (prefix)
* [playbook] add `test_connection.yml` playbook which tests the connection to a target host including `become`
* [docs] update [README](README.md) to reflect the latest changes
* [docs] add READMEs for all roles
* [dev] changes regarding the development environment:
* add setup script
* add pip requirements files
* add vscode workspace file
## 0.1.4
anything before 0.2.0 see [commit history](https://gitea.wululu.de/dede/ansible-common/commits/branch/main)

View File

@@ -1,24 +1,42 @@
# Ansible Collection - dede.common
# Ansible Collection - `dede.common`
```
_ _
__| | ___ __| | ___ ___ ___ _ __ ___ _ __ ___ ___ _ __
/ _` |/ _ \/ _` |/ _ \ / __/ _ \| '_ ` _ \| '_ ` _ \ / _ \| '_ \
| (_| | __/ (_| | __/| (_| (_) | | | | | | | | | | | (_) | | | |
\__,_|\___|\__,_|\___(_)___\___/|_| |_| |_|_| |_| |_|\___/|_| |_|
```
this ansible collection primarily aims to provide common roles that i've been building
for either my home or the wululu web network and systems.
for either my home or the wululu web network and systems.
by publishing it i hope it can be useful for anyone looking for inspiration
or even roles ready-to-go.
or even roles ready-to-go.
please mind that everything in this collection mainly focuses debian as a server operating system.
thus i will not add features specific to other operating systems unless i really need to.
thus i will not add features specific to other operating systems unless i really need to.
if you have any questions or suggestions feel free to get in touch with me.
## roles
## contents
* **test** a simple role to test ansible or just this collection
it will run a debug task printing 'hello world'
* **config_locale** role to configure system locale and language settings
you should set `system_locale` and `system_language` if you want to deviate from the default:
```
system_locale: 'de_DE.UTF-8'
system_language: 'en_US.UTF-8'
```
* **docker** a docker install role that can install docker-ce engine in two ways:
1. from the official docker repository (recommended by docker)
2. from your distribution
you can switch to the distribution method by setting `docker_use_dist_repo` to `true` (defaults to `false`).
### roles
* **test** a simple test role which runs a `debug` task printing 'hello world'
* **locale_config** role to configure system locale and language settings [🠞README](roles/locale_config/README.md)
* **docker** a docker install role to install docker-ce engine [🠞README](roles/docker/README.md)
### playbooks
* **test_connection.yml** a playbook to test ansible and connectivity by running ansible pings and the role `test`.
## usage
to use a **playbook** provided with this collection you can use `import_playbook`:
```yaml
- ansible.builtin.import_playbook: dede.common.test_connection.yml
```
to use a **role** provided with this collection just reference it using the collection name as a prefix:
```yaml
- hosts: all
roles:
- dede.common.test
```

View File

@@ -0,0 +1,27 @@
{
"folders": [
{
"path": "."
}
],
"settings": {
"files.associations": {
"*.yml": "ansible",
"*.j2": "ansible-jinja"
},
"ansible.python.interpreterPath": "${workspaceFolder}/.venv/bin/python",
"python.defaultInterpreterPath": "${workspaceFolder}/.venv/bin/python",
"editor.tabSize": 2,
"trailing-spaces.highlightCurrentLine": false,
"trailing-spaces.schemeIgnore": [
"markdown",
"output"
]
},
"extensions": {
"recommendations": [
"redhat.ansible",
"shardulm94.trailing-spaces"
]
}
}

View File

@@ -8,7 +8,7 @@ namespace: dede
name: common
# The version of the collection. Must be compatible with semantic versioning
version: 0.1.4
version: 0.3.1
# The path to the Markdown (.md) readme file. This path is relative to the root of the collection
readme: README.md
@@ -46,7 +46,7 @@ dependencies: {}
repository: https://gitea.wululu.de/dede/ansible-common
# The URL to any online docs
documentation: https://gitea.wululu.de/dede/ansible-common/wiki
documentation: https://gitea.wululu.de/dede/ansible-common/src/branch/main/README.md
# The URL to the homepage of the collection/project
homepage: https://gitea.wululu.de/dede/ansible-common
@@ -66,4 +66,3 @@ build_ignore: []
# 'omit_default_directives' is a boolean that controls whether the default directives are used. Mutually exclusive
# with 'build_ignore'
# manifest: null

2
requirements-raw.txt Normal file
View File

@@ -0,0 +1,2 @@
ansible
ansible-lint

33
requirements.txt Normal file
View File

@@ -0,0 +1,33 @@
ansible==12.2.0
ansible-compat==25.8.2
ansible-core==2.19.4
ansible-lint==25.9.2
attrs==25.4.0
black==25.9.0
bracex==2.6
cffi==2.0.0
click==8.3.0
cryptography==46.0.3
distro==1.9.0
filelock==3.20.0
importlib_metadata==8.7.0
Jinja2==3.1.6
jsonschema==4.25.1
jsonschema-specifications==2025.9.1
MarkupSafe==3.0.3
mypy_extensions==1.1.0
packaging==25.0
pathspec==0.12.1
platformdirs==4.5.0
pycparser==2.23
pytokens==0.3.0
PyYAML==6.0.3
referencing==0.37.0
resolvelib==1.2.1
rpds-py==0.28.0
ruamel.yaml==0.18.16
ruamel.yaml.clib==0.2.14
subprocess-tee==0.4.2
wcmatch==10.1
yamllint==1.37.1
zipp==3.23.0

View File

@@ -0,0 +1,8 @@
---
apt_sources_debian_repos_list: |
deb https://ftp-stud.hs-esslingen.de/debian/ bookworm main non-free-firmware
deb-src https://ftp-stud.hs-esslingen.de/debian/ bookworm main non-free-firmware
deb https://ftp-stud.hs-esslingen.de/debian-security/ bookworm-security main non-free-firmware
deb-src https://ftp-stud.hs-esslingen.de/debian-security/ bookworm-security main non-free-firmware
deb https://ftp-stud.hs-esslingen.de/debian/ bookworm-updates main non-free-firmware
deb-src https://ftp-stud.hs-esslingen.de/debian/ bookworm-updates main non-free-firmware

View File

@@ -0,0 +1,6 @@
---
- name: update apt sources
listen: apt_sources_update
become: true
ansible.builtin.apt:
update_cache: true

View File

@@ -0,0 +1,35 @@
---
- name: ensure custom repositories in apt sources
become: true
notify: apt_sources_update
ansible.builtin.copy:
dest: /etc/apt/sources.list.d/debian.list
mode: '0644'
owner: root
group: root
backup: true
content: |
#
# this file was modified by ansible on {{ ansible_date_time.iso8601 }}
#
{{ apt_sources_debian_repos_list }}
- name: disable default apt repos
become: true
notify: apt_sources_update
register: apt_sources_disable
ansible.builtin.replace:
path: /etc/apt/sources.list
backup: true
regexp: '^(deb(?:\-src)?.*)$'
replace: '#\1'
- name: ensure info comment in default sources file
become: true
when: apt_sources_disable is changed
ansible.builtin.lineinfile:
state: present
path: /etc/apt/sources.list
insertbefore: BOF
search_string: '# this file was modified by ansible on '
line: '# this file was modified by ansible on {{ ansible_date_time.iso8601 }}'

View File

@@ -1,5 +1,5 @@
# docker role
# dede.common.docker
this role will simply install the docker engine (community edition) from the official docker repositories.
this role will simply ensure the docker engine (community edition) is installed from the official docker repositories.
source: https://docs.docker.com/engine/install/debian/#install-using-the-repository

View File

@@ -1,18 +1,17 @@
---
- name: test docker setup
block:
- name: run hello-world container
become: true
register: docker_test
community.docker.docker_container:
state: started
name: hello-world
image: hello-world
- name: run hello-world container
become: true
listen: docker_run_test
notify: docker_rm_test
community.docker.docker_container:
state: started
name: hello-world
image: hello-world
- name: remove hello-world container
become: true
when: docker_test is changed
community.docker.docker_container:
state: absent
name: hello-world
image: hello-world
- name: remove hello-world container
become: true
listen: docker_rm_test
community.docker.docker_container:
state: absent
name: hello-world
image: hello-world

View File

@@ -55,7 +55,7 @@
- name: install docker + compose plugin and dependencies
become: true
notify: test docker setup
notify: docker_run_test
ansible.builtin.package:
state: present
name:

View File

@@ -0,0 +1,9 @@
# dede.common.locale_config
this role will ensure the system locale and language settings
you can modify `system_locale` and `system_language` if you want to deviate from the default, which is:
```yaml
locale_config_locale: 'de_DE.UTF-8'
locale_config_language: 'en_US.UTF-8'
```

View File

@@ -0,0 +1,3 @@
---
locale_config_locale: 'en_US.UTF-8'
locale_config_language: 'en_US.UTF-8'

View File

@@ -0,0 +1,45 @@
---
# got this from here:
# https://serverfault.com/questions/959026/how-do-i-generate-and-set-the-locale-using-ansible/981742#981742
- name: ensure locale files are available for {{ locale_config_locale }}
become: true
community.general.locale_gen:
state: present
name: "{{ locale_config_locale }}"
- name: ensure locale files are available for {{ locale_config_language }}
become: true
community.general.locale_gen:
state: present
name: "{{ locale_config_language }}"
- name: get current locale and language configuration
register: locale_config_status
changed_when: false
ignore_errors: true
ansible.builtin.command:
cmd: localectl status
- name: remember current LANG config
when: not locale_config_status is skipped
ansible.builtin.set_fact:
locale_config_current: "{{ locale_config_status.stdout | regex_search('LANG=([^\n]+)', '\\1') | first }}"
- name: print current config
ansible.builtin.debug:
msg: "LANG={{ locale_config_current }}"
- name: set locale to '{{ locale_config_locale }}'
become: true
changed_when: locale_config_current != locale_config_locale
ansible.builtin.command:
cmd: localectl set-locale LANG={{ locale_config_locale }}
- name: set language to '{{ locale_config_language }}'
become: true
changed_when: locale_language != locale_config_language
vars:
locale_language: "{{ locale_config_status.stdout | regex_search('LANGUAGE=([^\n]+)', '\\1') | default([locale_config_current], true) | first }}"
ansible.builtin.command:
cmd: localectl set-locale LANGUAGE={{ locale_config_language }}

View File

@@ -1,3 +0,0 @@
---
set_locale_locale: 'de_DE.UTF-8'
set_locale_language: 'en_US.UTF-8'

View File

@@ -1,38 +0,0 @@
---
# got this from here:
# https://serverfault.com/questions/959026/how-do-i-generate-and-set-the-locale-using-ansible/981742#981742
- name: ensure locale files are available for {{ set_locale_locale }}
become: true
community.general.locale_gen:
name: "{{ set_locale_locale }}"
state: present
- name: ensure locale files are available for {{ set_locale_language }}
become: true
community.general.locale_gen:
name: "{{ set_locale_language }}"
state: present
- name: get current locale and language configuration
register: locale_status
changed_when: false
ignore_errors: true
ansible.builtin.command:
cmd: localectl status
- name: set locale to '{{ set_locale_locale }}'
become: true
changed_when: locale_lang != set_locale_locale
vars:
locale_lang: "{{ locale_status.stdout | regex_search('LANG=([^\n]+)', '\\1') | first }}"
ansible.builtin.command:
cmd: localectl set-locale LANG={{ set_locale_locale }}
- name: set language to '{{ set_locale_language }}'
become: true
changed_when: locale_language != set_locale_language
vars:
locale_language: "{{ locale_status.stdout | regex_search('LANGUAGE=([^\n]+)', '\\1') | default([locale_lang], true) | first }}"
ansible.builtin.command:
cmd: localectl set-locale LANGUAGE={{ set_locale_language }}

3
roles/test/README.md Normal file
View File

@@ -0,0 +1,3 @@
# dede.common.test
a role that simply will print 'hello world!'

View File

@@ -0,0 +1,7 @@
---
timesyncd_setup_timezone: Europe/Berlin
timesyncd_setup_ntp_servers:
- rustime02.rus.uni-stuttgart.de
- ntp2.fau.de
- rustime01.rus.uni-stuttgart.de
- ntp1.fau.de

View File

@@ -0,0 +1,35 @@
---
# handlers file for systemd-timesyncd
- name: reload ntp
become: true
listen: reload_ntp
ansible.builtin.shell:
timedatectl set-ntp false || true;
timedatectl set-ntp true || true;
- name: reload timesyncd
become: true
listen: reload_timesyncd
ansible.builtin.service:
name: systemd-timesyncd
state: reloaded
- name: restart timesyncd
become: true
listen: restart_timesyncd
ansible.builtin.service:
name: systemd-timesyncd
state: restarted
- name: reconfigure timezone
become: true
listen: reconfigure_timezone
ansible.builtin.shell:
DEBIAN_FRONTEND=noninteractive \
dpkg-reconfigure --frontend noninteractive tzdata
- name: sync rtc
become: true
listen: sync_rtc
ansible.builtin.command:
timedatectl set-local-rtc 0

View File

@@ -0,0 +1,65 @@
---
- name: set timezone in /etc/localtime
become: true
ansible.builtin.file:
src: /usr/share/zoneinfo/{{ timesyncd_setup_timezone }}
dest: /etc/localtime
state: link
force: true
notify:
- reconfigure_timezone
- reload_ntp
- name: set timezone in /etc/timezone
become: true
ansible.builtin.lineinfile:
state: present
dest: /etc/timezone
regexp: '.*'
line: '{{ timesyncd_setup_timezone }}'
insertbefore: EOF
create: true
mode: '0644'
notify:
- reconfigure_timezone
- reload_ntp
- name: set timezone via systemd
become: true
ansible.builtin.command:
timedatectl set-timezone {{ timesyncd_setup_timezone }}
- name: set ntp config in /etc/systemd/timesyncd.conf
become: true
community.general.ini_file:
path: /etc/systemd/timesyncd.conf
section: Time
option: NTP
value: '{{ timesyncd_setup_ntp_servers | join(" ") }}'
backup: true
notify:
- reload_ntp
- restart_timesyncd
- sync_rtc
- name: enable systemd-timesyncd unit
become: true
service:
name: systemd-timesyncd
enabled: true
notify:
- reload_ntp
- restart_timesyncd
- sync_rtc
- name: flush handlers
ansible.builtin.meta: flush_handlers
# - name: wait for timesyncd to synchronize
# ansible.builtin.command: systemctl status systemd-timesyncd
# retries: 60
# delay: 3
# register: task_result
# until:
# - task_result.rc == 0
# - task_result.stdout is search('[Ss]ynchroniz.* to time server')

74
scripts/setup.sh Executable file
View File

@@ -0,0 +1,74 @@
#!/bin/bash
# exit immediately if a command exits with a non-zero status
set -e
VENV_DIR=.venv
# define color codes for output
RED=$(tput setaf 1)
GREEN=$(tput setaf 2)
YELLOW=$(tput setaf 3)
BLUE=$(tput setaf 4; tput bold)
NC=$(tput sgr0) # no color
# function to check for required commands
check_command() {
command -v "$1" >/dev/null 2>&1 || {
echo -e "${RED}error: $1 is not installed. please install it and try again.${NC}" >&2;
exit 1;
}
}
# function to install the latest python
install_python() {
echo -e "${BLUE}installing the latest python...${NC}"
sudo pacman -S python --noconfirm
}
# function to create a virtual environment
create_virtualenv() {
check_command "python"
echo -e "${BLUE}creating virtual environment...${NC}"
if [ ! -d "$VENV_DIR" ]; then
python -m venv $VENV_DIR
echo -e "${GREEN}virtual environment created at $VENV_DIR${NC}"
else
echo -e "${YELLOW}virtual environment already exists at $VENV_DIR${NC}"
fi
}
# function to install python requirements
install_requirements() {
check_command "pip"
echo -e "${BLUE}installing python requirements from requirements.txt...${NC}"
source $VENV_DIR/bin/activate
pip install --upgrade pip
if [ -f "requirements.txt" ]; then
pip install -r requirements.txt
else
echo -e "${YELLOW}requirements.txt not found. skipping python requirements installation.${NC}"
fi
deactivate
}
# function to install ansible roles from requirements.yml
install_ansible_requirements() {
check_command "ansible-galaxy"
echo -e "${BLUE}installing ansible roles from requirements.yml...${NC}"
if [ -f "requirements.yml" ]; then
source $VENV_DIR/bin/activate
ansible-galaxy install -r requirements.yml
deactivate
else
echo -e "${YELLOW}requirements.yml not found. skipping ansible requirements installation.${NC}"
fi
}
# main script execution
install_python # install the latest python
create_virtualenv # create a virtual environment
install_requirements # install python requirements
install_ansible_requirements # install ansible requirements
echo -e "${GREEN}setup completed successfully!${NC}"

14
test_connection.yml Normal file
View File

@@ -0,0 +1,14 @@
---
- name: test play
hosts: "{{ target | default([]) }}"
tasks:
- name: say hello to the world
ansible.builtin.debug:
msg: hello world!
- name: check connection using ping
ansible.builtin.ping:
- name: check become using ping
become: true
ansible.builtin.ping: