DEV-302: abolish manual installation steps

master
Görz, Friedrich 4 years ago committed by Ketelsen, Sven
parent 0bbf0bc719
commit 37d94b5166

@ -1,3 +1,59 @@
--- ---
harbor_version: v2.4.1 harbor_version: v2.4.1
harbor_hostname: '{{ stage_server_domain }}'
harbor_external_url: 'https://{{ stage_server_domain }}'
harbor_admin_username: '{{ harbor_admin_username_vault }}'
harbor_admin_password: '{{ harbor_admin_password_vault }}'
traefik_id: '{{ inventory_hostname }}-harbor'
harbor_dockercompose_customized:
services:
core:
extra_hosts:
- '{{ shared_service_keycloak_hostname }}:{{ shared_service_keycloak_ip }}'
- '{{ shared_service_mail_hostname }}:{{ shared_service_mail_ip }}'
proxy:
networks:
- harbor
- front-tier
ports: [] # not exposing ports - already used by traefik
labels:
- "traefik.enable=true"
- "traefik.http.middlewares.{{ traefik_id }}.headers.customrequestheaders.X-Forwarded-Proto=https"
- "traefik.http.routers.{{ traefik_id }}.service={{ traefik_id }}"
- "traefik.http.routers.{{ traefik_id }}.rule=Host(`{{ harbor_hostname }}`)"
- "traefik.http.routers.{{ traefik_id }}.entrypoints=websecure"
- "traefik.http.routers.{{ traefik_id }}.tls=true"
- "traefik.http.routers.{{ traefik_id }}.tls.certresolver=letsencrypt"
- "traefik.http.services.{{ traefik_id }}.loadbalancer.server.port=8080"
- "traefik.http.middlewares.{{ traefik_id }}-monitor.headers.customrequestheaders.X-Forwarded-Proto=https"
- "traefik.http.routers.{{ traefik_id }}-monitor.service={{ traefik_id }}-monitor"
- "traefik.http.routers.{{ traefik_id }}-monitor.rule=Host(`{{ harbor_hostname }}`)"
- "traefik.http.routers.{{ traefik_id }}-monitor.entrypoints=monitoring-harbor"
- "traefik.http.routers.{{ traefik_id }}-monitor.tls=true"
- "traefik.http.routers.{{ traefik_id }}-monitor.tls.certresolver=letsencrypt"
- "traefik.http.services.{{ traefik_id }}-monitor.loadbalancer.server.port=9090"
networks:
front-tier:
external: true
harbor_base_configuration:
email_host: '{{ shared_service_mail_hostname }}'
email_port: 25
email_from: '{{ ansible_fqdn }}@{{ shared_service_mail_hostname }}'
email_password: ''
email_username: ''
email_insecure: true
auth_mode: oidc_auth
oidc_name: docker
oidc_endpoint: 'https://{{ shared_service_keycloak_hostname }}/auth/realms/docker'
oidc_client_id: docker-registry
oidc_groups_claim: groups
oidc_scope: openid
oidc_verify_cert: true
oidc_auto_onboard: true
oidc_admin_group: '/admin'

@ -0,0 +1,20 @@
---
- name: "Add harbor base configuration via API"
delegate_to: 127.0.0.1
become: false
uri:
url: "{{ harbor_external_url }}/api/v2.0/configurations"
user: '{{ harbor_admin_username }}'
password: '{{ harbor_admin_password }}'
method: PUT
body_format: json
force_basic_auth: yes
body: "{{ base_configuration }}"
headers:
Content-Type: application/json
status_code: [200]
register: base_setting
delay: 10
retries: 10
until: base_setting.status in [200]

@ -0,0 +1,154 @@
---
### tags:
- name: "Setup DNS configuration for {{ inventory_hostname }} harbor"
include_role:
name: _digitalocean
tasks_from: domain
vars:
record_data: "{{ stage_server_ip }}"
record_name: "{{ inventory_hostname }}"
- name: 'Ensures {{ service_base_path }}/{{ inventory_hostname }} directory exists'
file:
state: directory
path: '{{ service_base_path }}/{{ inventory_hostname }}'
tags:
- update_deployment
- update_config
- name: Install pip dependencies
ansible.builtin.pip:
name: "{{ item }}"
loop:
- docker-compose
- name: 'Copy hacky upgrade script'
template:
src: 'hacky_harbor_upgrade.sh.j2'
dest: '/root/hacky_harbor_upgrade.sh'
owner: 'root'
group: 'root'
mode: '0744'
tags:
- upgrade-helper
# work around for DEV-271("container start failure after reboot")
- name: Ensure systemd file
template:
src: harbor-systemd.service.j2
dest: /etc/systemd/system/harbor.service
owner: root
group: root
mode: 0755
- name: "Check if harbor tarball exists"
stat:
path: '{{ service_base_path }}/{{ inventory_hostname }}/harbor-offline-installer-{{ harbor_version }}.tgz'
register: harbor_tarball
- name: Download harbor offline installer
ansible.builtin.get_url:
url: https://github.com/goharbor/harbor/releases/download/{{ harbor_version }}/harbor-offline-installer-{{ harbor_version }}.tgz
dest: "{{ service_base_path }}/{{ inventory_hostname }}/harbor-offline-installer-{{ harbor_version }}.tgz"
when:
- not harbor_tarball.stat.exists
- set_fact:
remote_docker_compose_file_path: '{{ service_base_path }}/{{ inventory_hostname }}/harbor/docker-compose.yml'
- name: "Check if {{ inventory_hostname }}/harbor/docker-compose.yml exists"
stat:
path: '{{ remote_docker_compose_file_path }}'
register: harbor_installation
- name: Extract harbor-offline-installer-{{ harbor_version }}.tgz into {{ service_base_path }}/{{ inventory_hostname }}
ansible.builtin.unarchive:
src: "{{ service_base_path }}/{{ inventory_hostname }}/harbor-offline-installer-{{ harbor_version }}.tgz"
dest: "{{ service_base_path }}/{{ inventory_hostname }}"
remote_src: yes
when:
- not harbor_installation.stat.exists
- name: Ensure config template files are populated from templates/harbor
template:
src: "harbor.yml.j2"
dest: "{{ service_base_path }}/{{ inventory_hostname }}/harbor/harbor.yml"
owner: 'root'
group: 'root'
mode: 0644
- name: "Exec harbor install.sh "
ansible.builtin.shell:
cmd: './install.sh {{ harbor_install_opts | default("--with-trivy --with-chartmuseum") }}'
chdir: '{{ service_base_path }}/{{ inventory_hostname }}/harbor/'
ignore_errors: yes
when:
- not harbor_installation.stat.exists
- name: "Stopping harbor"
community.docker.docker_compose:
project_src: '{{ service_base_path }}/{{ inventory_hostname }}/harbor/'
stopped: yes
when:
- not harbor_installation.stat.exists
- name: "ensure harbor systemd service also stopped"
systemd:
name: harbor
state: stopped
daemon_reload: yes
when:
- not harbor_installation.stat.exists
# create backup in case just sth weird had happened
- name: "Create backup of generated docker-compose.yml by install.sh"
copy:
src: '{{ remote_docker_compose_file_path }}'
dest: '{{ remote_docker_compose_file_path}}_from_installsh'
remote_src: yes
when:
- not harbor_installation.stat.exists
- name: "Create backup of common/config/nginx/nginx.conf"
copy:
src: '{{ service_base_path }}/{{ inventory_hostname }}/harbor/common/config/nginx/nginx.conf'
dest: '{{ service_base_path }}/{{ inventory_hostname }}/harbor/common/config/nginx/nginx.conf_orig'
remote_src: yes
when:
- not harbor_installation.stat.exists
- name:
ansible.builtin.lineinfile:
path: '{{ service_base_path }}/{{ inventory_hostname }}/harbor/common/config/nginx/nginx.conf'
state: absent
regexp: 'proxy_set_header'
- name: "Read remote docker-compose.yml from harbor DIR"
ansible.builtin.slurp:
src: '{{ remote_docker_compose_file_path }}'
register: docker_compose_file_remote_encoded
- set_fact:
harbor_dockercompose_merged: '{{ docker_compose_file_remote_encoded.content | b64decode | from_yaml | combine(harbor_dockercompose_customized, recursive=True) }}'
- name: "Create docker-compose.yml with merged VARs"
copy:
content: "{{ harbor_dockercompose_merged | to_nice_yaml(indent=2) }}"
dest: '{{ remote_docker_compose_file_path }}'
owner: 'root'
group: 'root'
mode: '0644'
register: docker_compose_change
- name: "Ensure harbor systemd service restarted"
systemd:
name: harbor
state: restarted
when: docker_compose_change.changed
- name: "Ensure harbor systemd service started"
systemd:
name: harbor
state: started

@ -1,117 +1,60 @@
--- ---
### tags: - name: "Install harbor"
include_tasks: install.yml
args:
apply:
tags:
- harbor-install
- name: "Setup DNS configuration for {{ inventory_hostname }} harbor" - name: "harbor BASE settings"
block:
- name: "BLOCK: Login with keycloak-admin"
include_role: include_role:
name: _digitalocean name: keycloak
tasks_from: domain tasks_from: _authenticate
- name: "GET available clients from <<{{ harbor_base_configuration.oidc_name }}>>-realm"
delegate_to: localhost
become: False
uri:
url: "{{ keycloak_server_url }}/auth/admin/realms/{{ harbor_base_configuration.oidc_name }}/clients"
method: GET
headers:
Content-Type: "application/json"
Authorization: "Bearer {{ access_token }}"
status_code: [200]
register: realm_clients
# available clients: get needed ID
- set_fact:
id_of_client: '{{ ( realm_clients.json | selectattr("clientId","equalto", harbor_base_configuration.oidc_client_id ) | first ).id }}'
- name: "BLOCK: GET client-secret for client <<{{ harbor_base_configuration.oidc_client_id }}>> in realm <<{{ harbor_base_configuration.oidc_name }}>>"
delegate_to: localhost
become: False
uri:
url: "{{ keycloak_server_url }}/auth/admin/realms/{{ harbor_base_configuration.oidc_name }}/clients/{{ id_of_client }}/client-secret"
method: GET
headers:
Content-Type: "application/json"
Authorization: "Bearer {{ access_token }}"
status_code: [200]
register: client_secret
- set_fact:
dict:
oidc_client_secret: '{{ client_secret.json.value }}'
- set_fact:
harbor_base_configuration_merged: '{{ harbor_base_configuration | combine( dict ,recursive=True ) }}'
- name: "BLOCK: Configure harbor BASE settings"
include_tasks: configure_base_config.yml
vars: vars:
record_data: "{{ stage_server_ip }}" base_configuration: '{{ harbor_base_configuration_merged }}'
record_name: "{{ inventory_hostname }}" args:
apply:
- name: 'Ensures {{ service_base_path }}/{{ inventory_hostname }} directory exists'
file:
state: directory
path: '{{ service_base_path }}/{{ inventory_hostname }}'
tags:
- update_deployment
- update_config
- name: 'Ensure directory structure for harbor exists'
file:
path: "{{ service_base_path }}/{{ inventory_hostname }}/{{ item.path }}"
state: directory
owner: "{{ docker_owner }}"
group: "{{ docker_group }}"
mode: 0755
with_filetree: "templates/harbor"
when: item.state == "directory"
tags:
- update_config
- name: 'Copy hacky upgrade script'
template:
src: 'hacky_harbor_upgrade.sh.j2'
dest: '/root/hacky_harbor_upgrade.sh'
owner: 'root'
group: 'root'
mode: '0744'
tags:
- upgrade-helper
- name: Ensure config template files are populated from templates/harbor
template:
src: "{{ item.src }}"
dest: "{{ service_base_path }}/{{ inventory_hostname }}/{{ item.path | regex_replace('\\.j2$', '') }}"
owner: "{{ docker_owner }}"
group: "{{ docker_group }}"
mode: 0644
with_filetree: "templates/harbor"
when: item.state == 'file' and item.src is match('.*\.j2$')
tags:
- update_config
# work around for DEV-271("container start failure after reboot")
- name: Ensure systemd file
template:
src: harbor-systemd.service.j2
dest: /etc/systemd/system/harbor.service
owner: root
group: root
mode: 0755
- name: Ensure config files are populated from from templates/harbor
copy:
src: "{{ item.src }}"
dest: "{{ service_base_path }}/{{ inventory_hostname }}/{{ item.path }}"
owner: "{{ docker_owner }}"
group: "{{ docker_group }}"
mode: 0644
with_filetree: "templates/harbor"
when: item.state == 'file' and item.src is not match('.*\.j2$')
tags: tags:
- update_config - harbor-configure-base
# end of block for base settings
- name: "Check if harbor tarball exists"
stat:
path: '{{ service_base_path }}/{{ inventory_hostname }}/harbor-offline-installer-{{ harbor_version }}.tgz'
register: harbor_tarball
- name: Download harbor offline installer
ansible.builtin.get_url:
url: https://github.com/goharbor/harbor/releases/download/{{ harbor_version }}/harbor-offline-installer-{{ harbor_version }}.tgz
dest: "{{ service_base_path }}/{{ inventory_hostname }}/harbor-offline-installer-{{ harbor_version }}.tgz"
when:
- not harbor_tarball.stat.exists
- name: "Check if {{ inventory_hostname }}/harbor/docker-compose.yml exists"
stat:
path: '{{ service_base_path }}/{{ inventory_hostname }}/harbor/docker-compose.yml'
register: harbor_installation
- name: Extract harbor-offline-installer-{{ harbor_version }}.tgz into {{ service_base_path }}/{{ inventory_hostname }}
ansible.builtin.unarchive:
src: "{{ service_base_path }}/{{ inventory_hostname }}/harbor-offline-installer-{{ harbor_version }}.tgz"
dest: "{{ service_base_path }}/{{ inventory_hostname }}"
remote_src: yes
when:
- not harbor_installation.stat.exists
- name: "Check if {{ inventory_hostname }}/harbor/docker-compose.yml exists"
stat:
path: '{{ service_base_path }}/harbor/{{ inventory_hostname }}/docker-compose.yml'
register: check_docker_compose_file
tags:
- update_deployment
- name: "Ensure harbor is running"
systemd:
name: harbor
enabled: yes
state: started
daemon_reload: yes

@ -2,7 +2,7 @@
# The IP address or hostname to access admin UI and registry service. # The IP address or hostname to access admin UI and registry service.
# DO NOT use localhost or 127.0.0.1, because Harbor needs to be accessed by external clients. # DO NOT use localhost or 127.0.0.1, because Harbor needs to be accessed by external clients.
hostname: {{ stage }}-docker-registry-01.{{ domain }} hostname: {{ harbor_hostname }}
# http related config # http related config
http: http:
@ -26,7 +26,7 @@ https:
# Uncomment external_url if you want to enable external proxy # Uncomment external_url if you want to enable external proxy
# And when it enabled the hostname will no longer used # And when it enabled the hostname will no longer used
external_url: https://{{ stage }}-docker-registry-01.{{ domain }} external_url: {{ harbor_external_url }}
# The initial password of Harbor admin # The initial password of Harbor admin
# It only works in first time to install harbor # It only works in first time to install harbor
Loading…
Cancel
Save