diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..236812e --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.ansible/ +collections/ansible_collections/ diff --git a/collections/requirements.yml b/collections/requirements.yml new file mode 100644 index 0000000..3cb14fc --- /dev/null +++ b/collections/requirements.yml @@ -0,0 +1,4 @@ +--- +collections: + - name: 'containers.podman' + version: '>=1.16.3' diff --git a/galaxy.yml b/galaxy.yml new file mode 100644 index 0000000..a48d005 --- /dev/null +++ b/galaxy.yml @@ -0,0 +1,66 @@ +--- +### REQUIRED +# The namespace of the collection. This can be a company/brand/organization or product namespace under which all +# content lives. May only contain alphanumeric lowercase characters and underscores. Namespaces cannot start with +# underscores or numbers and cannot contain consecutive underscores +namespace: 'enbewe' + +# The name of the collection. Has the same character restrictions as 'namespace' +name: 'budget' + +# The version of the collection. Must be compatible with semantic versioning +version: '1.0.0' + +# The path to the Markdown (.md) readme file. This path is relative to the root of the collection +readme: 'README.md' + +# A list of the collection's content authors. Can be just the name or in the format 'Full Name (url) +# @nicks:irc/im.site#channel' +authors: + - 'Nis Wechselberg ' + +### OPTIONAL but strongly recommended +# A short summary description of the collection +description: 'Deployment of Actual Budget' + +# Either a single license or a list of licenses for content inside of a collection. Ansible Galaxy currently only +# accepts L(SPDX,https://spdx.org/licenses/) licenses. This key is mutually exclusive with 'license_file' +license: + - 'MIT' + +# A list of tags you want to associate with the collection for indexing/searching. A tag name has the same character +# requirements as 'namespace' and 'name' +tags: + - 'linux' + +# Collections that this collection requires to be installed for it to be usable. The key of the dict is the +# collection label 'namespace.name'. The value is a version range +# L(specifiers,https://python-semanticversion.readthedocs.io/en/latest/#requirement-specification). Multiple version +# range specifiers can be set and are separated by ',' +dependencies: + containers.podman: '>=1.16.3' + +# The URL of the originating SCM repository +repository: 'https://git.enbewe.de/Coding/ansible-collection-budget' + +# The URL to any online docs +# documentation: http://docs.example.com + +# The URL to the homepage of the collection/project +# homepage: http://example.com + +# The URL to the collection issue tracker +# issues: http://example.com/issue/tracker + +# A list of file glob-like patterns used to filter any files or directories that should not be included in the build +# artifact. A pattern is matched from the relative path of the file or directory of the collection directory. This +# uses 'fnmatch' to match the files or directories. Some directories and files like 'galaxy.yml', '*.pyc', '*.retry', +# and '.git' are always filtered. Mutually exclusive with 'manifest' +# build_ignore: [] + +# A dict controlling use of manifest directives used in building the collection artifact. The key 'directives' is a +# list of MANIFEST.in style +# L(directives,https://packaging.python.org/en/latest/guides/using-manifest-in/#manifest-in-commands). The key +# 'omit_default_directives' is a boolean that controls whether the default directives are used. Mutually exclusive +# with 'build_ignore' +# manifest: null diff --git a/meta/runtime.yml b/meta/runtime.yml new file mode 100644 index 0000000..ddab9ac --- /dev/null +++ b/meta/runtime.yml @@ -0,0 +1,52 @@ +--- +# Collections must specify a minimum required ansible version to upload +# to galaxy +requires_ansible: '>=2.18.0' + +# Content that Ansible needs to load from another location or that has +# been deprecated/removed +# plugin_routing: +# action: +# redirected_plugin_name: +# redirect: ns.col.new_location +# deprecated_plugin_name: +# deprecation: +# removal_version: "4.0.0" +# warning_text: | +# See the porting guide on how to update your playbook to +# use ns.col.another_plugin instead. +# removed_plugin_name: +# tombstone: +# removal_version: "2.0.0" +# warning_text: | +# See the porting guide on how to update your playbook to +# use ns.col.another_plugin instead. +# become: +# cache: +# callback: +# cliconf: +# connection: +# doc_fragments: +# filter: +# httpapi: +# inventory: +# lookup: +# module_utils: +# modules: +# netconf: +# shell: +# strategy: +# terminal: +# test: +# vars: + +# Python import statements that Ansible needs to load from another location +# import_redirection: +# ansible_collections.ns.col.plugins.module_utils.old_location: +# redirect: ansible_collections.ns.col.plugins.module_utils.new_location + +# Groups of actions/modules that take a common set of options +# action_groups: +# group_name: +# - module1 +# - module2 diff --git a/playbooks/deploy.yml b/playbooks/deploy.yml new file mode 100644 index 0000000..da5b825 --- /dev/null +++ b/playbooks/deploy.yml @@ -0,0 +1,5 @@ +--- +- name: 'Deploy actual budget to host group' + hosts: 'budget' + roles: + - 'enbewe.budget.budget' diff --git a/roles/budget/defaults/main.yml b/roles/budget/defaults/main.yml new file mode 100644 index 0000000..67707a9 --- /dev/null +++ b/roles/budget/defaults/main.yml @@ -0,0 +1,7 @@ +--- +budget_network: 'actualbudget' +budget_image_name: 'docker.io/actualbudget/actual-server' +budget_image_tag: '25.5.0-alpine' +budget_data_location: '/srv/budget' +budget_container_name: 'actualbudget' +budget_app_environments: {} diff --git a/roles/budget/handlers/main.yml b/roles/budget/handlers/main.yml new file mode 100644 index 0000000..5253c42 --- /dev/null +++ b/roles/budget/handlers/main.yml @@ -0,0 +1,23 @@ +--- +- name: 'Reload budget services' + become: true + ansible.builtin.service: + daemon_reload: true + +- name: 'Restart budget network' + become: true + ansible.builtin.service: + name: '{{ budget_network }}-network' + state: 'restarted' + +- name: 'Restart budget image' + become: true + ansible.builtin.service: + name: 'actual-server-image' + state: 'restarted' + +- name: 'Restart budget container' + become: true + ansible.builtin.service: + name: '{{ budget_container_name }}' + state: 'restarted' diff --git a/roles/budget/tasks/main.yml b/roles/budget/tasks/main.yml new file mode 100644 index 0000000..3d2c162 --- /dev/null +++ b/roles/budget/tasks/main.yml @@ -0,0 +1,51 @@ +--- +- name: 'Ensure needed software is installed' + become: true + ansible.builtin.apt: + name: 'podman' + state: 'present' + +- name: 'Prepare budget network' + become: true + containers.podman.podman_network: + name: '{{ budget_network }}' + ipv6: true + state: 'quadlet' + notify: + - 'Reload budget services' + - 'Restart budget network' + +- name: 'Define budget image' + become: true + containers.podman.podman_image: + name: '{{ budget_image_name }}:{{ budget_image_tag }}' + state: 'quadlet' + notify: + - 'Reload budget services' + - 'Restart budget image' + +- name: 'Prepare budget data files location' + become: true + ansible.builtin.file: + path: '{{ budget_data_location }}' + state: 'directory' + owner: 'root' + group: 'root' + mode: 'u=rwx,g=rx,o=rx' + +- name: 'Create budget container' + become: true + containers.podman.podman_container: + name: '{{ budget_container_name }}' + image: 'actual-server.image' + network: '{{ budget_network }}.network' + state: 'quadlet' + volume: + - '{{ budget_data_location }}:/data' + env: '{{ budget_app_environments }}' + quadlet_options: | + [Install] + WantedBy=default.target + notify: + - 'Reload budget services' + - 'Restart budget container'