From dd603044fcbef81b2bfb3a62fc40421f27347505 Mon Sep 17 00:00:00 2001 From: Nis Wechselberg Date: Mon, 17 Jun 2024 16:45:02 +0200 Subject: [PATCH] Initial base playbooks Signed-off-by: Nis Wechselberg --- .yamllint.yml | 26 ++++++++++ CHANGELOG.md | 5 ++ README.md | 26 ++++++++++ galaxy.yml | 66 ++++++++++++++++++++++++ meta/runtime.yml | 52 +++++++++++++++++++ playbooks/access.yml | 36 +++++++++++++ playbooks/known_hosts.yml | 14 +++++ playbooks/motd.yml | 14 +++++ playbooks/templates/sudoers.d/ansible.j2 | 4 ++ playbooks/ubuntu_pro.yml | 40 ++++++++++++++ playbooks/update.yml | 22 ++++++++ 11 files changed, 305 insertions(+) create mode 100644 .yamllint.yml create mode 100644 CHANGELOG.md create mode 100644 README.md create mode 100644 galaxy.yml create mode 100644 meta/runtime.yml create mode 100644 playbooks/access.yml create mode 100644 playbooks/known_hosts.yml create mode 100644 playbooks/motd.yml create mode 100644 playbooks/templates/sudoers.d/ansible.j2 create mode 100644 playbooks/ubuntu_pro.yml create mode 100644 playbooks/update.yml diff --git a/.yamllint.yml b/.yamllint.yml new file mode 100644 index 0000000..bfe72e7 --- /dev/null +++ b/.yamllint.yml @@ -0,0 +1,26 @@ +--- +extends: 'default' + +ignore: + - '.ansible/' + +rules: + braces: + max-spaces-inside: 1 + comments: + min-spaces-from-content: 1 + comments-indentation: false + document-start: + present: true + line-length: + max: 120 + octal-values: + forbid-implicit-octal: true + forbid-explicit-octal: true + quoted-strings: + required: true + quote-type: 'single' + truthy: + allowed-values: + - 'true' + - 'false' diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..fac1c60 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changelog + +## 1.0.0 + +* Initial Release \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..8ddbcf5 --- /dev/null +++ b/README.md @@ -0,0 +1,26 @@ +# Ansible Collection - enbewe.base + +Collecion of base things for common deployment of systems. + +## Playbooks + +### enbewe.base.known_hosts + +Uses the (host) variable `ssh_ed25519` to register SSH host keys in the known hosts of localhost. + +### enbewe.base.access + +Install ssh keys as authorized keys in the target system and also configures sudo rights to the ansible user. +Afterwards tightens ssh security to disallow password logins. + +### enbewe.base.motd + +Remove components from motd, that are not needed. + +### enbewe.base.ubuntu_pro + +Configures the enrollment of the machine in Ubuntu Pro, enables the desired services and disables unwanted services. + +### enbewe.base.update + +Install available updates from package management. diff --git a/galaxy.yml b/galaxy.yml new file mode 100644 index 0000000..065c49e --- /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: 'base' + +# 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: 'Small base playbooks used for ansible deployments' + +# 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: + ansible.posix: '>=2.0.0' + +# The URL of the originating SCM repository +repository: 'https://git.enbewe.de/Coding/ansible-collection-base' + +# 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/access.yml b/playbooks/access.yml new file mode 100644 index 0000000..079f681 --- /dev/null +++ b/playbooks/access.yml @@ -0,0 +1,36 @@ +--- +- name: 'Configure access permissions' + hosts: 'all' + + vars: + ssh_public_keys_exclusive: true + + tasks: + - name: 'Install ssh keys in target system' + ansible.posix.authorized_key: + user: '{{ ansible_user }}' + key: '{{ ssh_public_keys }}' + exclusive: '{{ ssh_public_keys_exclusive }}' + + - name: 'Allow ansible user to use sudo' + become: true + ansible.builtin.template: + src: 'sudoers.d/ansible.j2' + dest: '/etc/sudoers.d/ansible' + owner: 'root' + group: 'root' + mode: 'u=rw,g=r,o=' + + - name: 'Disallow ssh password login' + become: true + ansible.builtin.lineinfile: + path: '/etc/ssh/sshd_config' + regexp: '^#?PasswordAuthentication ' + line: 'PasswordAuthentication no' + + - name: 'Disallow ssh root login without key' + become: true + ansible.builtin.lineinfile: + path: '/etc/ssh/sshd_config' + regexp: '^#?PermitRootLogin ' + line: 'PermitRootLogin prohibit-password' diff --git a/playbooks/known_hosts.yml b/playbooks/known_hosts.yml new file mode 100644 index 0000000..391a74f --- /dev/null +++ b/playbooks/known_hosts.yml @@ -0,0 +1,14 @@ +--- +- name: 'Install SSH keys as known hosts' + hosts: 'all' + serial: 1 + gather_facts: false + + tasks: + - name: 'Register host key' + delegate_to: 'localhost' + throttle: 1 + when: 'ssh_ed25519' + ansible.builtin.known_hosts: + name: '{{ inventory_hostname }}' + key: '{{ inventory_hostname }} ssh-ed25519 {{ ssh_ed25519 }}' diff --git a/playbooks/motd.yml b/playbooks/motd.yml new file mode 100644 index 0000000..87becb6 --- /dev/null +++ b/playbooks/motd.yml @@ -0,0 +1,14 @@ +--- +- name: 'Configure Motd components' + hosts: 'all' + + tasks: + - name: 'Remove components from motd, that are not needed' + become: true + ansible.builtin.file: + state: 'file' + path: '/etc/update-motd.d/{{ item }}' + mode: 'u=rw,g=r,o=r' + loop: + - '10-help-text' + - '50-motd-news' diff --git a/playbooks/templates/sudoers.d/ansible.j2 b/playbooks/templates/sudoers.d/ansible.j2 new file mode 100644 index 0000000..bacf639 --- /dev/null +++ b/playbooks/templates/sudoers.d/ansible.j2 @@ -0,0 +1,4 @@ +# {{ ansible_managed }} + +# Allow user for ansible to use sudo without password +{{ ansible_user }} ALL=(ALL:ALL) NOPASSWD: ALL diff --git a/playbooks/ubuntu_pro.yml b/playbooks/ubuntu_pro.yml new file mode 100644 index 0000000..01e10dd --- /dev/null +++ b/playbooks/ubuntu_pro.yml @@ -0,0 +1,40 @@ +--- +- name: 'Configure Ubuntu Pro subscription' + hosts: 'ubuntu_pro' + + tasks: + - name: 'Install required software' + become: true + ansible.builtin.apt: + name: 'ubuntu-advantage-tools' + state: 'present' + + - name: 'Register this host on Ubuntu Pro (pro attach )' + become: true + ansible.builtin.command: 'pro attach {{ ubuntu_pro_token }}' + register: 'reg_pro_attach' + changed_when: 'reg_pro_attach.rc == 0' + failed_when: + - 'reg_pro_attach.rc != 0' + - '"This machine is already attached to" not in reg_pro_attach.stderr_lines[0]' + + - name: 'Enable selected Ubuntu Pro services' + become: true + ansible.builtin.command: 'pro enable {{ item }}' + register: 'reg_pro_enable' + changed_when: 'reg_pro_enable.rc == 0' + failed_when: + - 'reg_pro_enable.rc != 0' + - '"is already enabled" not in reg_pro_enable.stdout_lines[1]' + - '"is not available for" not in reg_pro_enable.stdout_lines[1]' + loop: '{{ ubuntu_pro_enabled_services }}' + + - name: 'Disable selected Ubuntu Pro services' + become: true + ansible.builtin.command: 'pro disable {{ item }}' + register: 'reg_pro_disable' + changed_when: 'reg_pro_disable.rc == 0' + failed_when: + - 'reg_pro_disable.rc != 0' + - '"is not currently enabled not" in reg_pro_disable.stdout_lines[0]' + loop: '{{ ubuntu_pro_disabled_services }}' diff --git a/playbooks/update.yml b/playbooks/update.yml new file mode 100644 index 0000000..b7b89c6 --- /dev/null +++ b/playbooks/update.yml @@ -0,0 +1,22 @@ +--- +- name: 'Install updates through package management' + hosts: 'all' + + pre_tasks: + - name: 'Update package cache if needed' + become: true + ansible.builtin.apt: + update_cache: true + cache_valid_time: 3600 + + tasks: + - name: 'Install all available update' + become: true + ansible.builtin.apt: + upgrade: 'dist' + + - name: 'Remove unneeded dependencies and leftover packages from cache' + become: true + ansible.builtin.apt: + autoclean: true + autoremove: true