diff --git a/.ansible-lint b/.ansible-lint new file mode 100644 index 0000000..b386a4b --- /dev/null +++ b/.ansible-lint @@ -0,0 +1,8 @@ +--- +skip_list: + - yaml[comments-indentation] + +extra_vars: + hostvars: + localhost: + example_host_var: dummy_host diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..83b5a94 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,8 @@ +[*.{yml,yaml}] +indent_style = space +indent_size = 2 +end_of_line = lf +trim_trailing_whitespace = true +trim_final_newlines = true +insert_final_newline = true +max_line_length = 160 diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..4c2c5e7 --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,41 @@ +--- +on: # yamllint disable-line rule:truthy + push: + branches: + - main + pull_request: + +name: ⚒️ CI + +jobs: + yamllint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: yamllint + uses: ibiqlik/action-yamllint@v3 + with: + file_or_dir: . + config_file: .yamllint + + ansible-lint: + runs-on: ubuntu-latest + container: pipelinecomponents/ansible-lint:latest + steps: + - uses: actions/checkout@v4 + - run: | + git --version + ansible-lint --version + ansible-lint -v + + ansible-syntax: + runs-on: ubuntu-latest + container: cytopia/ansible:latest + steps: + - uses: actions/checkout@v4 + - run: | + apk add git + git --version + ansible-galaxy --version + ansible-playbook --version + ansible-playbook --syntax-check --list-tasks playbooks/*.yml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1d74e21 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.vscode/ diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..db209dd --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,37 @@ +--- +stages: + - lint + +yamllint: + stage: lint + image: + name: cytopia/yamllint:latest + entrypoint: ["/bin/ash", "-c"] + script: + - yamllint --version + - yamllint . + +ansible-lint: + stage: lint + image: pipelinecomponents/ansible-lint:latest + script: + - git --version + - ansible-lint --version + - ansible-lint + - ansible-lint roles/ + +ansible-syntax: + stage: lint + image: + name: cytopia/ansible:latest + entrypoint: ["/bin/sh", "-c"] + variables: + ANSIBLE_ROLES_PATH: roles + script: + - apk add git + - git --version + - ansible-galaxy --version + - ansible-playbook --version + - ansible-galaxy role install -r roles/requirements.yml + - ansible-galaxy collection install -r collections/requirements.yml + - ansible-playbook --syntax-check --list-tasks playbooks/*.yml diff --git a/.yamllint b/.yamllint new file mode 100644 index 0000000..a317ae0 --- /dev/null +++ b/.yamllint @@ -0,0 +1,16 @@ +--- +extends: default + +rules: + line-length: + max: 160 + empty-lines: + max: 1 + max-start: 0 + max-end: 1 + hyphens: + max-spaces-after: 1 + indentation: + spaces: 2 + indent-sequences: whatever + check-multi-line-strings: false diff --git a/README.md b/README.md new file mode 100644 index 0000000..a90e8e7 --- /dev/null +++ b/README.md @@ -0,0 +1,57 @@ +# Ansible Control Repository Template +[![⚒️ CI](https://github.com/betadots/ansible-control-repo-template/actions/workflows/ci.yaml/badge.svg)](https://github.com/betadots/ansible-control-repo-template/actions/workflows/ci.yaml) +[![Created by betadots GmbH](https://img.shields.io/badge/Created_by-betadots_GmbH-blue)](https://www.betadots.de) + +# Usage + +Copy this repository into your own Git Server. +Then clone it from there and adapt your changes. + +# What's in this template + +Here is a visual representation of the structure of this repository: + +```bash +bin/helpers # here you may place scripts which help the ci or the ansible surroundings +inventories/ # + production/ # + hosts # inventory file for production servers + group_vars/ # here we assign variables to particular groups + host_vars/ # here we assign variables to particular systems + staging/ # + hosts # inventory file for staging environment + group_vars/ # here we assign variables to particular groups + host_vars/ # here we assign variables to particular systems + # +library/ # if any custom modules, put them here (optional) +module_utils/ # if any custom module_utils to support modules, put them here (optional) +filter_plugins/ # if any custom filter plugins, put them here (optional) + # +site.yml # master playbook + # +playbooks/ # put all playbooks here + foo.yml # foo demo playbook + # +collections/ # local collections + requirements.yml # <-- required remote collections + +roles/ # + common/ # this hierarchy represents a "role" + tasks/ # + main.yml # <-- tasks file can include smaller files if warranted + handlers/ # + main.yml # <-- handlers file + templates/ # <-- files for use with the template resource + files/ # <-- files for use with the copy resource + vars/ # + main.yml # <-- variables associated with this role + defaults/ # + main.yml # <-- default lower priority variables for this role + meta/ # + main.yml # <-- role dependencies + library/ # roles can also include custom modules + module_utils/ # roles can also include custom module_utils + lookup_plugins/ # or other types of plugins, like lookup in this case + # + requirements.yml # required remote roles +``` diff --git a/ansible.cfg b/ansible.cfg new file mode 100644 index 0000000..05b78e4 --- /dev/null +++ b/ansible.cfg @@ -0,0 +1,9 @@ +[defaults] +collections_paths = /etc/ansible/collections:/opt/ansible/collections:collections +roles_path = /etc/ansible/roles:/opt/ansible/roles:roles + +# You’ll also need to make sure that requiretty is disabled +# in /etc/sudoers on the remote host, or become won’t work +# with pipelining enabled. +[ssh_connection] +pipelining = True diff --git a/bin/helpers/.gitkeep b/bin/helpers/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/bin/helpers/user_repair.sh b/bin/helpers/user_repair.sh new file mode 100644 index 0000000..0c62e47 --- /dev/null +++ b/bin/helpers/user_repair.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +# these commands are run as root +# if ansible user is somehow broken or missing, execute this script to repair it + +useradd -m ansible -s /bin/bash +mkdir /home/ansible/.ssh +chmod 700 /home/ansible/.ssh +chown ansible:ansible /home/ansible/.ssh +echo "ansible ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers.d/ansible +chmod 0440 /etc/sudoers.d/ansible +echo "< place key here >" >> /home/ansible/.ssh/authorized_keys +chmod 600 /home/ansible/.ssh/authorized_keys +chown ansible:ansible /home/ansible/.ssh/authorized_keys diff --git a/collections/.gitignore b/collections/.gitignore new file mode 100644 index 0000000..aca6f9a --- /dev/null +++ b/collections/.gitignore @@ -0,0 +1,11 @@ +# Ignore everything in dir... +/* + +# ... but current file... +!.gitignore + +# ... external collections requirement file +!requirements.yml + +# ... and configured custom/local collections +!ansible_collections/example_collection.*/ diff --git a/collections/requirements.yml b/collections/requirements.yml new file mode 100644 index 0000000..351f1d3 --- /dev/null +++ b/collections/requirements.yml @@ -0,0 +1,15 @@ +--- +collections: [] + # - name: ansible.netcommon + # version: 5.1.2 + # - name: ansible.posix + # version: 1.5.4 + # - name: ansible.utils + # version: 2.10.3 + # - name: ansible.windows + # version: 1.14.0 + + # - name: community.docker + # version: 3.4.8 + # - name: community.general + # version: 7.4.0 diff --git a/filter_plugins/.gitkeep b/filter_plugins/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/inventories/production/group_vars/.gitkeep b/inventories/production/group_vars/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/inventories/production/group_vars/all.yml b/inventories/production/group_vars/all.yml new file mode 100644 index 0000000..4854dcf --- /dev/null +++ b/inventories/production/group_vars/all.yml @@ -0,0 +1,16 @@ +--- +# to use short names in your inventory file +# uncomment the following lines. +# then you can use the hostname as the inventory name +# and do not need to specify the fqdn. + +# host_domain: company.example.com +# ansible_host: "{{inventory_hostname}}.{{host_domain}}" + +ansible_user: ansible +ansible_connection: ssh +ansible_become_method: sudo +ansible_python_interpreter: "/usr/bin/python3" + +# if you want to use a specific ssh key +# ansible_ssh_private_key_file: /Users/rwaffen/.ssh/ansible diff --git a/inventories/production/host_vars/.gitkeep b/inventories/production/host_vars/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/inventories/production/hosts b/inventories/production/hosts new file mode 100644 index 0000000..e69de29 diff --git a/inventories/staging/group_vars/.gitkeep b/inventories/staging/group_vars/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/inventories/staging/group_vars/all.yml b/inventories/staging/group_vars/all.yml new file mode 100644 index 0000000..4854dcf --- /dev/null +++ b/inventories/staging/group_vars/all.yml @@ -0,0 +1,16 @@ +--- +# to use short names in your inventory file +# uncomment the following lines. +# then you can use the hostname as the inventory name +# and do not need to specify the fqdn. + +# host_domain: company.example.com +# ansible_host: "{{inventory_hostname}}.{{host_domain}}" + +ansible_user: ansible +ansible_connection: ssh +ansible_become_method: sudo +ansible_python_interpreter: "/usr/bin/python3" + +# if you want to use a specific ssh key +# ansible_ssh_private_key_file: /Users/rwaffen/.ssh/ansible diff --git a/inventories/staging/host_vars/.gitkeep b/inventories/staging/host_vars/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/inventories/staging/hosts b/inventories/staging/hosts new file mode 100644 index 0000000..e69de29 diff --git a/library/.gitkeep b/library/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/module_utils/.gitkeep b/module_utils/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/playbooks/foo.yml b/playbooks/foo.yml new file mode 100644 index 0000000..67978a6 --- /dev/null +++ b/playbooks/foo.yml @@ -0,0 +1,5 @@ +--- +- name: Demo playbook + hosts: "{{ target_hosts | default('foo') }}" + roles: + - common diff --git a/playbooks/prepare_semaphore_exec_env.yaml b/playbooks/prepare_semaphore_exec_env.yaml new file mode 100644 index 0000000..9ade883 --- /dev/null +++ b/playbooks/prepare_semaphore_exec_env.yaml @@ -0,0 +1,18 @@ +--- +# +# This has to be run once the container from semaphore is up and running +# It will install the collections and pip packages needed for the playbooks +# + +- name: "Dummy plug on localhost" + hosts: localhost + gather_facts: false + connection: local + tasks: + - name: "Install collections" + ansible.builtin.import_tasks: + file: "../tasks/install_collections.yml" + + - name: "Install pip packages" + ansible.builtin.import_tasks: + file: "../tasks/install_pip.yml" diff --git a/playbooks/test_ssh_connection.yml b/playbooks/test_ssh_connection.yml new file mode 100644 index 0000000..8895f88 --- /dev/null +++ b/playbooks/test_ssh_connection.yml @@ -0,0 +1,8 @@ +--- +- name: "Test SSH Connection" + hosts: "{{ target_hosts | default('all') }}" + gather_facts: false + tasks: + - name: Test we can logon to the servers and execute python with json lib. + ansible.builtin.ping: + register: ping_result diff --git a/roles/.gitignore b/roles/.gitignore new file mode 100644 index 0000000..be8b065 --- /dev/null +++ b/roles/.gitignore @@ -0,0 +1,11 @@ +# Ignore everything in dir... +/* + +# ... but current file... +!.gitignore + +# ... external role requirement file +!requirements.yml + +# ... and configured custom/local roles +!common/ diff --git a/roles/common/defaults/main.yml b/roles/common/defaults/main.yml new file mode 100644 index 0000000..205c4a1 --- /dev/null +++ b/roles/common/defaults/main.yml @@ -0,0 +1,2 @@ +--- +# defaults file for common diff --git a/roles/common/files/.gitkeep b/roles/common/files/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/roles/common/handlers/main.yml b/roles/common/handlers/main.yml new file mode 100644 index 0000000..2662adc --- /dev/null +++ b/roles/common/handlers/main.yml @@ -0,0 +1,2 @@ +--- +# handlers file for common diff --git a/roles/common/library/.gitkeep b/roles/common/library/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/roles/common/lookup_plugins/.gitkeep b/roles/common/lookup_plugins/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/roles/common/meta/main.yml b/roles/common/meta/main.yml new file mode 100644 index 0000000..bb7b529 --- /dev/null +++ b/roles/common/meta/main.yml @@ -0,0 +1,40 @@ +--- +galaxy_info: + author: betadots GmbH + description: Common role + company: betadots GmbH + issue_tracker_url: http://example.com/issue/tracker + license: BSD-3-Clause + min_ansible_version: "2.15.3" + + # If this a Container Enabled role, provide the minimum Ansible Container version. + # min_ansible_container_version: + + # Provide a list of supported platforms, and for each platform a list of versions. + # If you don't wish to enumerate all versions for a particular platform, use 'all'. + # To view available platforms and versions (or releases), visit: + # https://galaxy.ansible.com/api/v1/platforms/ + # + # platforms: + # - name: Fedora + # versions: + # - all + # - 25 + # - name: SomePlatform + # versions: + # - all + # - 1.0 + # - 7 + # - 99.99 + + # List tags for your role here, one per line. A tag is a keyword that describes + # and categorizes the role. Users find roles by searching for tags. Be sure to + # remove the '[]' above, if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of alphanumeric characters. + # Maximum 20 tags per role. + galaxy_tags: [] + +# List your role dependencies here, one per line. Be sure to remove the '[]', +# if you add dependencies to this list. +dependencies: [] diff --git a/roles/common/module_utils/.gitkeep b/roles/common/module_utils/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/roles/common/tasks/main.yml b/roles/common/tasks/main.yml new file mode 100644 index 0000000..7b72b3d --- /dev/null +++ b/roles/common/tasks/main.yml @@ -0,0 +1,2 @@ +--- +# tasks file for common diff --git a/roles/common/templates/.gitkeep b/roles/common/templates/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/roles/common/tests/inventory b/roles/common/tests/inventory new file mode 100644 index 0000000..878877b --- /dev/null +++ b/roles/common/tests/inventory @@ -0,0 +1,2 @@ +localhost + diff --git a/roles/common/tests/test.yml b/roles/common/tests/test.yml new file mode 100644 index 0000000..c6716e1 --- /dev/null +++ b/roles/common/tests/test.yml @@ -0,0 +1,6 @@ +--- +- name: Test + hosts: localhost + remote_user: root + roles: + - common diff --git a/roles/common/vars/main.yml b/roles/common/vars/main.yml new file mode 100644 index 0000000..fed6035 --- /dev/null +++ b/roles/common/vars/main.yml @@ -0,0 +1,2 @@ +--- +# vars file for common diff --git a/roles/requirements.yml b/roles/requirements.yml new file mode 100644 index 0000000..1b129d5 --- /dev/null +++ b/roles/requirements.yml @@ -0,0 +1,15 @@ +--- +roles: [] + ### Galaxy + # - name: geerlingguy.ntp + # version: 2.3.3 + # - name: geerlingguy.pip + # version: 2.2.0 + # - name: geerlingguy.docker + # version: 6.2.0 + + # ### Github + # - name: mlangry.google-chrome + # version: 43198de + # scm: git + # src: https://github.com/mlangry/ansible-role-google-chrome.git diff --git a/site.yml b/site.yml new file mode 100644 index 0000000..9bdc341 --- /dev/null +++ b/site.yml @@ -0,0 +1,3 @@ +--- +- name: Foo Demo Playbook + import_playbook: playbooks/foo.yml diff --git a/tasks/install_collections.yml b/tasks/install_collections.yml new file mode 100644 index 0000000..d349c66 --- /dev/null +++ b/tasks/install_collections.yml @@ -0,0 +1,17 @@ +--- +# workaround for ansible semaphore +# usage for a playobook from the playbooks directory: +# +# - hosts: localhost +# name: "Dummy plug on localhost" +# gather_facts: false +# connection: local +# tasks: +# - name: "Install collections" +# ansible.builtin.import_tasks: +# file: "../tasks/install_collections.yml" + +- name: Install collections + ansible.builtin.command: "ansible-galaxy collection install -r ../collections/requirements.yml" + register: collections_install + changed_when: collections_install.rc != 0 diff --git a/tasks/install_pip.yml b/tasks/install_pip.yml new file mode 100644 index 0000000..2bc51a6 --- /dev/null +++ b/tasks/install_pip.yml @@ -0,0 +1,27 @@ +--- +# workaround for ansible semaphore +# usage for a playobook from the playbooks directory: +# +# - hosts: localhost +# name: "Dummy plug on localhost" +# gather_facts: false +# connection: local +# tasks: +# - name: "Install pip packages" +# ansible.builtin.import_tasks: +# file: "../tasks/install_pip.yml" + +- name: "Make sure pip is installed" + ansible.builtin.command: "{{ ansible_python_interpreter }} -m ensurepip --upgrade" + register: pip_installed + changed_when: pip_installed.rc != 0 + +- name: "Make sure pip packages are installed" + ansible.builtin.pip: + name: "{{ item }}" + state: present + with_items: + - proxmoxer + - requests + - jmespath + - netaddr diff --git a/tasks/main.yml b/tasks/main.yml new file mode 100644 index 0000000..faf4d07 --- /dev/null +++ b/tasks/main.yml @@ -0,0 +1,2 @@ +--- +# default file for tasks