From bc9032644caf1d035d9a97e67acc60b514a64b5b Mon Sep 17 00:00:00 2001 From: transcaffeine Date: Wed, 5 Feb 2025 13:48:09 +0100 Subject: [PATCH] WIP: feat(jenkins_inbound_agent): add ansible role for deployment with docker --- roles/jenkins_inbound_agent/README.md | 11 +++ .../defaults/main/container.yml | 74 +++++++++++++++++++ .../defaults/main/main.yml | 14 ++++ roles/jenkins_inbound_agent/tasks/check.yml | 38 ++++++++++ .../tasks/deploy-docker.yml | 43 +++++++++++ roles/jenkins_inbound_agent/tasks/main.yml | 8 ++ roles/jenkins_inbound_agent/vars/main.yml | 13 ++++ 7 files changed, 201 insertions(+) create mode 100644 roles/jenkins_inbound_agent/README.md create mode 100644 roles/jenkins_inbound_agent/defaults/main/container.yml create mode 100644 roles/jenkins_inbound_agent/defaults/main/main.yml create mode 100644 roles/jenkins_inbound_agent/tasks/check.yml create mode 100644 roles/jenkins_inbound_agent/tasks/deploy-docker.yml create mode 100644 roles/jenkins_inbound_agent/tasks/main.yml create mode 100644 roles/jenkins_inbound_agent/vars/main.yml diff --git a/roles/jenkins_inbound_agent/README.md b/roles/jenkins_inbound_agent/README.md new file mode 100644 index 0000000..23fb292 --- /dev/null +++ b/roles/jenkins_inbound_agent/README.md @@ -0,0 +1,11 @@ +# `finallycoffee.cicd.jenkins_inbound_agent` ansible role + +## Overview + +Deploy Jenkins inbound agents using docker. + +## Required configuration + +- `jenkins_agent_server_url` - URL of the jenkins control node, including protocol and port, i.e.: http://jenkins-server:port +- `jenkins_agent_secret` - Secret for this jenkins agent generated by the jenkins control node +- `jenkins_agent_name` - Name of this (inbound) agent, must match agent name in jenkins control node diff --git a/roles/jenkins_inbound_agent/defaults/main/container.yml b/roles/jenkins_inbound_agent/defaults/main/container.yml new file mode 100644 index 0000000..d9a5ee2 --- /dev/null +++ b/roles/jenkins_inbound_agent/defaults/main/container.yml @@ -0,0 +1,74 @@ +--- +jenkins_agent_container_name: "jenkins-inbound-agent-{{ jenkins_agent_name }}" +jenkins_agent_container_image: >-2 + {{ + [ + jenkins_agent_container_image_repository, + jenkins_agent_container_image_tag + | default( + jenkins_agent_version + jenkins_agent_container_suffix, + true + ) + ] | join(':') + }} +jenkins_agent_container_image_registry: docker.io +jenkins_agent_container_image_namespace: jenkins +jenkins_agent_container_image_name: inbound-agent +jenkins_agent_container_image_repository: >-2 + {{ + [ + jenkins_agent_container_image_registry | default([], true), + jenkins_agent_container_image_namespace | default([], true), + jenkins_agent_container_image_name + ] | flatten | join('/') + }} +jenkins_agent_container_image_source: "pull" +jenkins_agent_container_image_force_source: >-2 + {{ jenkins_agent_container_image_tag | default(true, true) }} +jenkins_agent_container_image_tag: ~ +jenkins_agent_container_image_jdk_version: "jdk17" +jenkins_agent_container_image_distribution: "alpine" + +jenkins_agent_container_suffix: >-2 + {{ + ( + ((jenkins_agent_container_image_distribution is string) + and (jenkins_agent_container_image_distribution | length > 0)) + | ternary( + '-' + jenkins_agent_container_image_distribution | default('', true), + '' + ) + ) + + + ( + ((jenkins_agent_container_image_jdk_version is string) + and (jenkins_agent_container_image_jdk_version | length > 0)) + | ternary( + '-' + jenkins_agent_container_image_jdk_version | default('', true), + '' + ) + ) + }} + +jenkins_agent_container_env: ~ +jenkins_agent_container_base_env: + JENKINS_URL: "{{ jenkins_agent_server_url | ansible.builtin.mandatory }}" + JENKINS_AGENT_NAME: "{{ jenkins_agent_name | ansible.builtin.mandatory }}" + JENKINS_SECRET: "@{{ jenkins_agent_secret_file }}" +jenkins_agent_all_env: >-2 + {{ jenkins_agent_container_base_env + | combine(jenkins_agent_container_env | default({}, true)) }} +jenkins_agent_container_ports: ~ +jenkins_agent_container_state: >-2 + {{ (jenkins_agent_state == 'present') | ternary('started', 'absent') }} +jenkins_agent_container_labels: + version: "{{ jenkins_agent_container_image_tag | default(jenkins_agent_version, true) }}" +jenkins_agent_container_networks: ~ +jenkins_agent_container_etc_hosts: ~ +jenkins_agent_container_base_volumes: + - "{{ jenkins_agent_secret_file }}:{{ jenkins_agent_secret_file }}:ro" +jenkins_agent_container_volumes: ~ +jenkins_agent_container_all_volumes: >-2 + {{ jenkins_agent_container_base_volumes | default([], true) + + jenkins_agent_container_volumes | default([], true) }} +jenkins_agent_container_restart_policy: "on-failure" diff --git a/roles/jenkins_inbound_agent/defaults/main/main.yml b/roles/jenkins_inbound_agent/defaults/main/main.yml new file mode 100644 index 0000000..35cf22d --- /dev/null +++ b/roles/jenkins_inbound_agent/defaults/main/main.yml @@ -0,0 +1,14 @@ +--- +jenkins_agent_user: "jenkins-agent" +jenkins_agent_user_create_home: false +jenkins_agent_user_is_system: false +jenkins_agent_version: "3283.v92c105e0f819-8" + +jenkins_agent_state: "present" +jenkins_agent_deployment_method: "docker" + +jenkins_agent_name: ~ +jenkins_agent_secret: ~ +jenkins_agent_server_url: ~ + +jenkins_agent_secret_file: "/etc/jenkins/agent/{{ jenkins_agent_name }}.secret" diff --git a/roles/jenkins_inbound_agent/tasks/check.yml b/roles/jenkins_inbound_agent/tasks/check.yml new file mode 100644 index 0000000..fe852fb --- /dev/null +++ b/roles/jenkins_inbound_agent/tasks/check.yml @@ -0,0 +1,38 @@ +--- +- name: Ensure 'jenkins_agent_state' is valid + ansible.builtin.fail: + msg: >-2 + Unsupported jenkins_agent_state '{{ jenkins_agent_state }}'. + Supported values are: {{ jenkins_agent_states | join(', ') }} + when: jenkins_agent_state not in jenkins_agent_states + +- name: Ensure 'jenkins_agent_deployment_method' is valid + ansible.builtin.fail: + msg: >-2 + Unsupported jenkins_agent_deployment_method '{{ jenkins_agent_deployment_method }}'. + Supported values are: {{ jenkins_agent_deployment_methods | join(', ') }} + when: jenkins_agent_deployment_method not in jenkins_agent_deployment_methods + +- name: Ensure Jenkins agent JDK version is valid if specified + ansible.builtin.fail: + msg: >-2 + Unsupported jenkins_agent_container_image_jdk_version + '{{ jenkins_agent_container_image_jdk_version }}' specified! + Supported JDK versions are: + {{ jenkins_agent_container_image_jdk_versions | join(', ') }} + when: + - jenkins_agent_container_image_jdk_version is string + - jenkins_agent_container_image_jdk_version | length > 0 + - jenkins_agent_container_image_jdk_version not in jenkins_agent_container_image_jdk_versions + +- name: Ensure Jenkins agent distribution is valid if specified + ansible.builtin.fail: + msg: >-2 + Unsupported jenkins_agent_container_image_distribution + '{{ jenkins_agent_container_image_distribution }}' specified! + Supported JDK versions are: + {{ jenkins_agent_container_image_distibrutions | join(', ') }} + when: + - jenkins_agent_container_image_distribution is string + - jenkins_agent_container_image_distribution | length > 0 + - jenkins_agent_container_image_distribution not in jenkins_agent_container_image_distributions diff --git a/roles/jenkins_inbound_agent/tasks/deploy-docker.yml b/roles/jenkins_inbound_agent/tasks/deploy-docker.yml new file mode 100644 index 0000000..28edde9 --- /dev/null +++ b/roles/jenkins_inbound_agent/tasks/deploy-docker.yml @@ -0,0 +1,43 @@ +--- +- name: Ensure container image '{{ jenkins_agent_container_image }}' is {{ jenkins_agent_state }} + community.docker.docker_image: + name: "{{ jenkins_agent_container_image }}" + state: "{{ jenkins_agent_state }}" + source: "{{ jenkins_agent_container_image_source }}" + force_source: "{{ jenkins_agent_container_image_force_source }}" + +- name: Ensure jenkins configuration directory exists + ansible.builtin.file: + path: "{{ jenkins_agent_secret_file | dirname }}" + state: directory + mode: "0755" + recurse: true + when: jenkins_agent_state == 'present' + +- name: Ensure jenkins secret is persisted + ansible.builtin.copy: + dest: "{{ jenkins_agent_secret_file }}" + content: "{{ jenkins_agent_secret }}" + mode: "0400" + when: jenkins_agent_state == 'present' + +- name: Ensure jenkins configuration is removed + ansible.builtin.file: + path: "{{ jenkins_agent_secret_file | dirname }}" + state: absent + recurse: true + when: jenkins_agent_state == 'absent' + +- name: Ensure jenkins-agent container '{{ jenkins_agent_container_name }}' is {{ jenkins_agent_container_state }} + community.docker.docker_container: + name: "{{ jenkins_agent_container_name }}" + image: "{{ jenkins_agent_container_image }}" + env: "{{ jenkins_agent_container_env | default(omit, true) }}" + init: "{{ jenkins_agent_container_init | default(true, true) }}" + ports: "{{ jenkins_agent_container_ports | default(omit, true) }}" + labels: "{{ jenkins_agent_container_labels | default(omit, true) }}" + volumes: "{{ jenkins_agent_container_volumes }}" + networks: "{{ jenkins_agent_container_networks | default(omit, true) }}" + etc_hosts: "{{ jenkins_agent_container_etc_hosts | default(omit, true) }}" + restart_policy: "{{ jenkins_agent_container_restart_policy }}" + state: "{{ jenkins_agent_container_state }}" diff --git a/roles/jenkins_inbound_agent/tasks/main.yml b/roles/jenkins_inbound_agent/tasks/main.yml new file mode 100644 index 0000000..1f49abb --- /dev/null +++ b/roles/jenkins_inbound_agent/tasks/main.yml @@ -0,0 +1,8 @@ +--- +- name: Ensure required variables are populated (correctly) + ansible.builtin.include_tasks: + file: "check.yml" + +- name: Ensure jenkins-agent '{{ jenkins_agent_name }}' is deployed using {{ jenkins_agent_deployment_method }} + ansible.builtin.include_tasks: + file: "deploy-{{ jenkins_agent_deployment_method }}.yml" diff --git a/roles/jenkins_inbound_agent/vars/main.yml b/roles/jenkins_inbound_agent/vars/main.yml new file mode 100644 index 0000000..d2d6a9d --- /dev/null +++ b/roles/jenkins_inbound_agent/vars/main.yml @@ -0,0 +1,13 @@ +--- +jenkins_agent_states: + - "present" + - "absent" +jenkins_agent_deployment_methods: + - "docker" +jenkins_agent_container_image_jdk_versions: + - "jdk17" + - "jdk21" +jenkins_agent_container_image_distributions: + - "alpine" + - "alpine3.21" + - "rhel-ubi9"