├── .gitignore ├── .ansible-lint ├── handlers └── main.yml ├── .github ├── FUNDING.yml ├── workflows │ ├── release.yml │ ├── ci.yml │ └── stale.yml └── stale.yml ├── .yamllint ├── molecule └── default │ ├── molecule.yml │ └── converge.yml ├── tasks ├── setup-Debian.yml ├── setup-RedHat.yml └── main.yml ├── meta └── main.yml ├── LICENSE ├── defaults └── main.yml └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | *.retry 2 | */__pycache__ 3 | *.pyc 4 | .ansible 5 | .cache 6 | 7 | -------------------------------------------------------------------------------- /.ansible-lint: -------------------------------------------------------------------------------- 1 | skip_list: 2 | - 'yaml' 3 | - 'risky-shell-pipe' 4 | - 'role-name' 5 | -------------------------------------------------------------------------------- /handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: restart containerd 3 | service: 4 | name: containerd 5 | state: restarted 6 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | --- 3 | github: geerlingguy 4 | patreon: geerlingguy 5 | -------------------------------------------------------------------------------- /.yamllint: -------------------------------------------------------------------------------- 1 | --- 2 | extends: default 3 | 4 | rules: 5 | line-length: 6 | max: 200 7 | level: warning 8 | 9 | ignore: | 10 | .github/workflows/stale.yml 11 | -------------------------------------------------------------------------------- /molecule/default/molecule.yml: -------------------------------------------------------------------------------- 1 | --- 2 | role_name_check: 1 3 | dependency: 4 | name: galaxy 5 | options: 6 | ignore-errors: true 7 | driver: 8 | name: docker 9 | platforms: 10 | - name: instance 11 | image: "geerlingguy/docker-${MOLECULE_DISTRO:-rockylinux9}-ansible:latest" 12 | command: ${MOLECULE_DOCKER_COMMAND:-""} 13 | volumes: 14 | - /sys/fs/cgroup:/sys/fs/cgroup:rw 15 | cgroupns_mode: host 16 | privileged: true 17 | pre_build_image: true 18 | provisioner: 19 | name: ansible 20 | playbooks: 21 | converge: ${MOLECULE_PLAYBOOK:-converge.yml} 22 | -------------------------------------------------------------------------------- /tasks/setup-Debian.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Ensure dependencies are installed. 3 | apt: 4 | name: 5 | - python3-debian 6 | state: present 7 | 8 | - name: Add Docker repository. 9 | deb822_repository: 10 | name: docker 11 | types: deb 12 | uris: "{{ docker_apt_repository }}" 13 | state: present 14 | suites: "{{ ansible_facts.distribution_release }}" 15 | components: "{{docker_apt_release_channel }}" 16 | signed_by: "{{ docker_apt_gpg_key }}" 17 | register: docker_repository 18 | 19 | - name: Update Apt cache if repositories have changed 20 | apt: 21 | update_cache: true 22 | when: docker_repository is changed 23 | -------------------------------------------------------------------------------- /tasks/setup-RedHat.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Add Docker GPG key. 3 | rpm_key: 4 | key: "{{ docker_yum_gpg_key }}" 5 | state: present 6 | 7 | - name: Add Docker repository. 8 | get_url: 9 | url: "{{ docker_yum_repo_url }}" 10 | dest: '/etc/yum.repos.d/docker-ce.repo' 11 | owner: root 12 | group: root 13 | mode: 0644 14 | 15 | - name: Configure Docker Nightly repo. 16 | ini_file: 17 | dest: '/etc/yum.repos.d/docker-ce.repo' 18 | section: 'docker-ce-nightly' 19 | option: enabled 20 | value: '{{ docker_yum_repo_enable_nightly }}' 21 | mode: 0644 22 | 23 | - name: Ensure container-selinux is installed. 24 | package: 25 | name: container-selinux 26 | state: present 27 | -------------------------------------------------------------------------------- /meta/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | dependencies: [] 3 | 4 | galaxy_info: 5 | role_name: containerd 6 | author: geerlingguy 7 | description: containerd.io for Linux. 8 | company: "Midwestern Mac, LLC" 9 | license: "license (BSD, MIT)" 10 | min_ansible_version: 2.10 11 | platforms: 12 | - name: Fedora 13 | versions: 14 | - all 15 | - name: Debian 16 | versions: 17 | - bullseye 18 | - bookworm 19 | - trixie 20 | - name: Ubuntu 21 | versions: 22 | - xenial 23 | - bionic 24 | - focal 25 | galaxy_tags: 26 | - system 27 | - containers 28 | - docker 29 | - containerd 30 | - kubernetes 31 | - orchestration 32 | - server 33 | -------------------------------------------------------------------------------- /molecule/default/converge.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Converge 3 | hosts: all 4 | # become: true 5 | 6 | pre_tasks: 7 | - name: Update apt cache. 8 | apt: update_cache=yes cache_valid_time=600 9 | when: ansible_facts.os_family == 'Debian' 10 | 11 | - name: Wait for systemd to complete initialization. # noqa command-instead-of-module 12 | command: systemctl is-system-running 13 | register: systemctl_status 14 | until: > 15 | 'running' in systemctl_status.stdout or 16 | 'degraded' in systemctl_status.stdout 17 | retries: 30 18 | delay: 5 19 | when: ansible_facts.service_mgr == 'systemd' 20 | changed_when: false 21 | failed_when: systemctl_status.rc > 1 22 | 23 | roles: 24 | - role: geerlingguy.containerd 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2021 Jeff Geerling 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Package options. 3 | containerd_package: containerd.io 4 | containerd_package_state: present 5 | 6 | # Service options. 7 | containerd_service_state: started 8 | containerd_service_enabled: true 9 | 10 | # Write a default containerd config.toml file. 11 | containerd_config_default_write: true 12 | 13 | # Set systemd as cgroup driver in config.toml 14 | # Only use with containerd_config_default_write: true 15 | containerd_config_cgroup_driver_systemd: false 16 | 17 | # Used only for Debian/Ubuntu. Switch 'stable' to 'nightly' if needed. 18 | docker_apt_release_channel: stable 19 | docker_apt_repository: "https://download.docker.com/linux/{{ ansible_facts.distribution | lower }}" 20 | docker_apt_ignore_key_error: true 21 | docker_apt_gpg_key: https://download.docker.com/linux/{{ ansible_facts.distribution | lower }}/gpg 22 | 23 | # Used only for RedHat/CentOS/Fedora. 24 | docker_yum_repo_url: https://download.docker.com/linux/{{ (ansible_facts.distribution == "Fedora") | ternary("fedora","centos") }}/docker-ce.repo 25 | docker_yum_repo_enable_nightly: '0' 26 | docker_yum_gpg_key: https://download.docker.com/linux/centos/gpg 27 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # This workflow requires a GALAXY_API_KEY secret present in the GitHub 3 | # repository or organization. 4 | # 5 | # See: https://github.com/marketplace/actions/publish-ansible-role-to-galaxy 6 | # See: https://github.com/ansible/galaxy/issues/46 7 | 8 | name: Release 9 | 'on': 10 | push: 11 | tags: 12 | - '*' 13 | 14 | defaults: 15 | run: 16 | working-directory: 'geerlingguy.containerd' 17 | 18 | jobs: 19 | 20 | release: 21 | name: Release 22 | runs-on: ubuntu-latest 23 | steps: 24 | - name: Check out the codebase. 25 | uses: actions/checkout@v4 26 | with: 27 | path: 'geerlingguy.containerd' 28 | 29 | - name: Set up Python 3. 30 | uses: actions/setup-python@v5 31 | with: 32 | python-version: '3.13' # Can't go to 3.14+ until Ansible 13.x 33 | 34 | - name: Install Ansible. 35 | run: pip3 install ansible-core 36 | 37 | - name: Trigger a new import on Galaxy. 38 | run: >- 39 | ansible-galaxy role import --api-key ${{ secrets.GALAXY_API_KEY }} 40 | $(echo ${{ github.repository }} | cut -d/ -f1) $(echo ${{ github.repository }} | cut -d/ -f2) 41 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: CI 3 | 'on': 4 | pull_request: 5 | push: 6 | branches: 7 | - master 8 | schedule: 9 | - cron: "0 7 * * 0" 10 | 11 | defaults: 12 | run: 13 | working-directory: 'geerlingguy.containerd' 14 | 15 | jobs: 16 | 17 | lint: 18 | name: Lint 19 | runs-on: ubuntu-latest 20 | steps: 21 | - name: Check out the codebase. 22 | uses: actions/checkout@v4 23 | with: 24 | path: 'geerlingguy.containerd' 25 | 26 | - name: Set up Python 3. 27 | uses: actions/setup-python@v5 28 | with: 29 | python-version: '3.13' # Can't go to 3.14+ until Ansible 13.x 30 | 31 | - name: Install test dependencies. 32 | run: pip3 install yamllint 33 | 34 | - name: Lint code. 35 | run: | 36 | yamllint . 37 | 38 | molecule: 39 | name: Molecule 40 | runs-on: ubuntu-latest 41 | strategy: 42 | matrix: 43 | distro: 44 | - rockylinux9 45 | - ubuntu2404 46 | - debian13 47 | - fedora42 48 | 49 | steps: 50 | - name: Check out the codebase. 51 | uses: actions/checkout@v4 52 | with: 53 | path: 'geerlingguy.containerd' 54 | 55 | - name: Set up Python 3. 56 | uses: actions/setup-python@v5 57 | with: 58 | python-version: '3.13' # Can't go to 3.14+ until Ansible 13.x 59 | 60 | - name: Install test dependencies. 61 | run: pip3 install ansible molecule molecule-plugins[docker] docker 62 | 63 | - name: Run Molecule tests. 64 | run: molecule test 65 | env: 66 | PY_COLORS: '1' 67 | ANSIBLE_FORCE_COLOR: '1' 68 | MOLECULE_DISTRO: ${{ matrix.distro }} 69 | -------------------------------------------------------------------------------- /.github/workflows/stale.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Close inactive issues 3 | 'on': 4 | schedule: 5 | - cron: "55 8 * * 1" # semi-random time 6 | 7 | jobs: 8 | close-issues: 9 | runs-on: ubuntu-latest 10 | permissions: 11 | issues: write 12 | pull-requests: write 13 | steps: 14 | - uses: actions/stale@v8 15 | with: 16 | days-before-stale: 120 17 | days-before-close: 60 18 | exempt-issue-labels: bug,pinned,security,planned 19 | exempt-pr-labels: bug,pinned,security,planned 20 | stale-issue-label: "stale" 21 | stale-pr-label: "stale" 22 | stale-issue-message: | 23 | This issue has been marked 'stale' due to lack of recent activity. If there is no further activity, the issue will be closed in another 30 days. Thank you for your contribution! 24 | 25 | Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark issues as stale. 26 | close-issue-message: | 27 | This issue has been closed due to inactivity. If you feel this is in error, please reopen the issue or file a new issue with the relevant details. 28 | stale-pr-message: | 29 | This pr has been marked 'stale' due to lack of recent activity. If there is no further activity, the issue will be closed in another 30 days. Thank you for your contribution! 30 | 31 | Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark issues as stale. 32 | close-pr-message: | 33 | This pr has been closed due to inactivity. If you feel this is in error, please reopen the issue or file a new issue with the relevant details. 34 | repo-token: ${{ secrets.GITHUB_TOKEN }} 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Ansible Role: Containerd 2 | 3 | [![CI](https://github.com/geerlingguy/ansible-role-containerd/actions/workflows/ci.yml/badge.svg)](https://github.com/geerlingguy/ansible-role-containerd/actions/workflows/ci.yml) 4 | 5 | An Ansible Role that installs [containerd](https://containerd.io) on Linux. 6 | 7 | ## Requirements 8 | 9 | None. 10 | 11 | ## Role Variables 12 | 13 | Available variables are listed below, along with default values (see `defaults/main.yml`): 14 | 15 | containerd_package: containerd.io 16 | containerd_package_state: present 17 | 18 | Package name and state controls. 19 | 20 | containerd_service_state: started 21 | containerd_service_enabled: true 22 | 23 | Service controls. You can install containerd but not have it running or enabled on boot by changing these defaults. 24 | 25 | containerd_config_default_write: true 26 | 27 | Write containerd defaults to the containerd config.toml file. 28 | 29 | containerd_config_cgroup_driver_systemd: false 30 | 31 | Set systemd as cgroup driver in config.toml. Only valid with `containerd_config_default_write: true` 32 | 33 | docker_apt_release_channel: stable 34 | docker_apt_repository: "https://download.docker.com/linux/{{ ansible_facts.distribution | lower }}" 35 | docker_apt_ignore_key_error: true 36 | docker_apt_gpg_key: https://download.docker.com/linux/{{ ansible_facts.distribution | lower }}/gpg 37 | 38 | Apt installation paramemeters, useful if you want to switch from the stable channel releases, or install on a different CPU architecture (e.g. `arm64`). 39 | 40 | docker_yum_repo_url: https://download.docker.com/linux/{{ (ansible_facts.distribution == "Fedora") | ternary("fedora","centos") }}/docker-ce.repo 41 | docker_yum_repo_enable_nightly: '0' 42 | docker_yum_gpg_key: https://download.docker.com/linux/centos/gpg 43 | 44 | Yum/DNF installation parameters, useful if you want to switch from the stable repository. 45 | 46 | ## Dependencies 47 | 48 | None. 49 | 50 | ## Example Playbook 51 | 52 | ```yaml 53 | - hosts: all 54 | roles: 55 | - geerlingguy.containerd 56 | ``` 57 | 58 | ## License 59 | 60 | MIT / BSD 61 | 62 | ## Author Information 63 | 64 | This role was created in 2021 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/). 65 | -------------------------------------------------------------------------------- /tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - include_tasks: setup-RedHat.yml 3 | when: ansible_facts.os_family == 'RedHat' 4 | 5 | - include_tasks: setup-Debian.yml 6 | when: ansible_facts.os_family == 'Debian' 7 | 8 | - name: Ensure containerd is installed. 9 | package: 10 | name: "{{ containerd_package }}" 11 | state: "{{ containerd_package_state }}" 12 | 13 | - name: Ensure containerd is started and enabled at boot. 14 | service: 15 | name: containerd 16 | state: "{{ containerd_service_state }}" 17 | enabled: "{{ containerd_service_enabled }}" 18 | 19 | - name: Ensure containerd config directory exists. 20 | file: 21 | path: /etc/containerd 22 | state: directory 23 | register: containerd_dir 24 | 25 | - name: Get defaults from containerd. 26 | command: containerd config default 27 | changed_when: false 28 | register: containerd_config_default 29 | when: containerd_config_default_write 30 | 31 | - name: Prepare containerd/config.toml from default config 32 | copy: 33 | dest: /tmp/containerd_config.toml 34 | content: "{{ containerd_config_default.stdout }}" 35 | when: containerd_config_default_write 36 | changed_when: false 37 | 38 | - name: Set Cgroup driver to systemd 39 | lineinfile: 40 | insertafter: '.*\[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options\]$' 41 | line: ' SystemdCgroup = true' 42 | state: present 43 | path: /tmp/containerd_config.toml 44 | when: containerd_config_default_write and containerd_config_cgroup_driver_systemd 45 | changed_when: false 46 | 47 | - name: Make sure SystemdCgroup = false is not set 48 | ansible.builtin.lineinfile: 49 | path: /tmp/containerd_config.toml 50 | state: absent 51 | line: ' SystemdCgroup = false' 52 | notify: restart containerd 53 | when: containerd_config_default_write and containerd_config_cgroup_driver_systemd 54 | changed_when: false 55 | 56 | - name: Copy config.toml to /etc/containerd 57 | copy: 58 | remote_src: true 59 | src: /tmp/containerd_config.toml 60 | dest: /etc/containerd/config.toml 61 | notify: restart containerd 62 | when: containerd_config_default_write 63 | 64 | - name: Cleanup temporary file 65 | file: 66 | path: /tmp/containerd_config.toml 67 | state: absent 68 | changed_when: false 69 | 70 | - name: Ensure containerd is restarted immediately if necessary. 71 | meta: flush_handlers 72 | -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Configuration for probot-stale - https://github.com/probot/stale 2 | --- 3 | # Number of days of inactivity before an Issue or Pull Request becomes stale 4 | daysUntilStale: 90 5 | 6 | # Number of days of inactivity before an Issue or Pull Request with the stale label is closed. 7 | # Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. 8 | daysUntilClose: 30 9 | 10 | # Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled) 11 | onlyLabels: [] 12 | 13 | # Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable 14 | exemptLabels: 15 | - bug 16 | - pinned 17 | - security 18 | - planned 19 | 20 | # Set to true to ignore issues in a project (defaults to false) 21 | exemptProjects: false 22 | 23 | # Set to true to ignore issues in a milestone (defaults to false) 24 | exemptMilestones: false 25 | 26 | # Set to true to ignore issues with an assignee (defaults to false) 27 | exemptAssignees: false 28 | 29 | # Label to use when marking as stale 30 | staleLabel: stale 31 | 32 | # Limit the number of actions per hour, from 1-30. Default is 30 33 | limitPerRun: 30 34 | 35 | pulls: 36 | markComment: |- 37 | This pull request has been marked 'stale' due to lack of recent activity. If there is no further activity, the PR will be closed in another 30 days. Thank you for your contribution! 38 | 39 | Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark pull requests as stale. 40 | 41 | unmarkComment: >- 42 | This pull request is no longer marked for closure. 43 | 44 | closeComment: >- 45 | This pull request has been closed due to inactivity. If you feel this is in error, please reopen the pull request or file a new PR with the relevant details. 46 | 47 | issues: 48 | markComment: |- 49 | This issue has been marked 'stale' due to lack of recent activity. If there is no further activity, the issue will be closed in another 30 days. Thank you for your contribution! 50 | 51 | Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark issues as stale. 52 | 53 | unmarkComment: >- 54 | This issue is no longer marked for closure. 55 | 56 | closeComment: >- 57 | This issue has been closed due to inactivity. If you feel this is in error, please reopen the issue or file a new issue with the relevant details. 58 | --------------------------------------------------------------------------------