Skip to content

Commit

Permalink
tf(harbor-standalone): add module to deploy harbor registry in a vm
Browse files Browse the repository at this point in the history
  • Loading branch information
giovannibaratta committed Jan 15, 2024
1 parent a4dd027 commit b4fce90
Show file tree
Hide file tree
Showing 10 changed files with 436 additions and 0 deletions.
20 changes: 20 additions & 0 deletions terraform/modules/harbor-standalone/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Harbor standalone

The module deploys Harbor registry in a VM in a vSphere environment.

<!-- BEGIN_TF_DOCS -->
<!-- This section will be overridden by terraform-docs. Do not change it.-->
## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_domain"></a> [domain](#input\_domain) | n/a | `string` | n/a | yes |
| <a name="input_vm_authorized_key"></a> [vm\_authorized\_key](#input\_vm\_authorized\_key) | Public key authorized to ssh into the VM | `string` | n/a | yes |
| <a name="input_vsphere"></a> [vsphere](#input\_vsphere) | vSphere related references to deploy the VM | <pre>object({<br> resource_pool_id = string<br> datastore_id = string<br> network_id = string<br> template_id = string<br> })</pre> | n/a | yes |

## Outputs

| Name | Description |
|------|-------------|
| <a name="output_harbor_instance_ip"></a> [harbor\_instance\_ip](#output\_harbor\_instance\_ip) | n/a |
<!-- END_TF_DOCS -->
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#cloud-config

fqdn: ${fqdn}

ssh_pwauth: false

chpasswd:
# Passwords don't need to be reset on next login
expire: false

users:
- name: root
lock_passwd: false
plain_text_passwd: ${password}
- name: ubuntu
ssh_authorized_keys:
- ${authorized_key}
sudo: ALL=(ALL) NOPASSWD:ALL
groups: sudo,docker
lock_passwd: true
shell: /bin/bash
- name: ansible
gecos: Ansible User
shell: /bin/bash
groups: sudo
lock_passwd: true
sudo: ALL=(ALL) NOPASSWD:ALL

package_update: true
package_upgrade: true
packages:
- python3-pip # Required to install Ansible

write_files:
- path: /harbor/ansible/harbor-install-playbook.yaml
owner: root:root
permissions: '0644'
encoding: base64
content: ${harbor_install_playbook}
- path: /harbor/harbor.yml
owner: root:root
permissions: '0644'
encoding: base64
content: ${harbor_conf}
- path: /etc/systemd/system/harbor.service
owner: root:root
permissions: '0644'
encoding: base64
content: ${harbor_service}

ansible:
install_method: pip
package_name: ansible
run_user: ansible
galaxy:
actions:
- ["ansible-galaxy", "role", "install", "geerlingguy.docker"]

setup_controller:
run_ansible:
- playbook_dir: /harbor/ansible
playbook_name: harbor-install-playbook.yaml
timeout: 120
forks: 1
61 changes: 61 additions & 0 deletions terraform/modules/harbor-standalone/files/harbor-config.yml.tftpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Configuration file of Harbor

hostname: ${fqdn}

http:
# If https enabled, this port will redirect to https port
port: 80

https:
port: 443
# The cert and the key must be available in the data_volume configured in
# this configuration file
certificate: /data/cert/${fqdn}.pem
private_key: /data/cert/${fqdn}.key

internal_tls:
enabled: false
dir: /data/cert

harbor_admin_password: ${admin_password}

database:
# The password for the root user of Harbor DB.
password: ${db_root_password}
max_idle_conns: 400
max_open_conns: 400
conn_max_lifetime: 0 # Do not close connections
conn_max_idle_time: 600

data_volume: /data

trivy:
ignore_unfixed: false
skip_update: false
offline_scan: false
security_check: vuln
insecure: false

jobservice:
max_job_workers: 10
job_loggers:
- STD_OUTPUT
- FILE
logger_sweeper_duration: 1 #days


notification:
webhook_job_max_retry: 3
webhook_job_http_client_timeout: 3 #seconds

log:
level: info
local:
rotate_count: 50
location: /var/log/harbor

cache:
enabled: false

#This attribute is for migrator to detect the version of the .cfg file, DO NOT MODIFY!
_version: 2.10.0
148 changes: 148 additions & 0 deletions terraform/modules/harbor-standalone/files/harbor-install-playbook.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
- name: Prepare host
hosts: localhost
connection: local
become: true

roles:
- geerlingguy.docker

- name: Install & configure Harbor
hosts: localhost
gather_facts: false
connection: local
become: true

vars:
harbor_hostname: "${harbor_fqdn}"

tasks:
- name: Create TLS folder
ansible.builtin.file:
path: "/harbor/tls/"
state: directory
mode: '0700'

# Create self-signed CA
- name: Create CA private key
community.crypto.openssl_privatekey:
path: /harbor/tls/ca.key

- name: Create CA certificate
community.crypto.x509_certificate:
path: /harbor/tls/ca.pem
privatekey_path: /harbor/tls/ca.key
provider: selfsigned

- name: Create Harbor private key
community.crypto.openssl_privatekey:
path: /harbor/tls/harbor.key

# Create CSR and sign it with the self-signed cA
- name: Create Harbor certificate signing request (CSR)
community.crypto.openssl_csr_pipe:
privatekey_path: /harbor/tls/harbor.key
common_name: "{{ harbor_hostname }}"
subject_alt_name:
- "DNS:{{ harbor_hostname }}"
register: harbor_csr

- name: Create Harbor certificate
community.crypto.x509_certificate:
path: /harbor/tls/harbor.pem
csr_content: "{{ harbor_csr.csr }}"
ownca_privatekey_path: /harbor/tls/ca.key
ownca_path: /harbor/tls/ca.pem
provider: ownca

# Copy certificate and private key in the all the required folders
- name: Create Docker cert folder
ansible.builtin.file:
path: "/etc/docker/certs.d/{{ harbor_hostname }}/"
state: directory
mode: '0755'

- name: Create /data folder
ansible.builtin.file:
path: "/data"
state: directory
mode: '0755'

- name: Create /data/cert folder
ansible.builtin.file:
path: "/data/cert"
state: directory
mode: '0755'

- name: Create /data/ca_download folder
ansible.builtin.file:
path: "/data/ca_download"
state: directory
mode: '0755'

- name: Copy Harbor private key to Docker certs
ansible.builtin.copy:
src: /harbor/tls/harbor.key
dest: "/etc/docker/certs.d/{{ harbor_hostname }}/{{ harbor_hostname}}.key"
remote_src: yes

- name: Copy Harbor certificate to Docker certs
ansible.builtin.copy:
src: /harbor/tls/harbor.pem
dest: "/etc/docker/certs.d/{{ harbor_hostname }}/{{ harbor_hostname}}.pem"
remote_src: yes

- name: Copy CA certificate
ansible.builtin.copy:
src: /harbor/tls/ca.pem
dest: "/etc/docker/certs.d/{{ harbor_hostname }}/ca.pem"
remote_src: yes

- name: Copy Harbor private key to data volume
ansible.builtin.copy:
src: /harbor/tls/harbor.key
dest: "/data/cert/{{ harbor_hostname}}.key"
remote_src: yes

- name: Copy Harbor certificate to data volume
ansible.builtin.copy:
src: /harbor/tls/harbor.pem
dest: "/data/cert/{{ harbor_hostname}}.pem"
remote_src: yes

- name: Copy CA to data volume
ansible.builtin.copy:
src: /harbor/tls/ca.pem
dest: "/data/ca_download/ca.crt"
remote_src: yes

- name: Check if Harbor is already installed
ansible.builtin.shell:
cmd: docker compose ls | grep harbor
register: harbor_installed
ignore_errors: true

- name: Install Harbor
when: harbor_installed.rc == 1
block:
- name: Download install script
ansible.builtin.get_url:
url: "https://github.com/goharbor/harbor/releases/download/v2.10.0/harbor-offline-installer-v2.10.0.tgz"
dest: /tmp/harbor.tgz
checksum: md5:a63bba7a1d820dc27a5caaa4a9ff3721

- name: Extract archive
ansible.builtin.unarchive:
remote_src: true
src: /tmp/harbor.tgz
dest: /

- name: Install harbor
ansible.builtin.shell:
cmd: /harbor/install.sh --with-trivy

# The service file is copied via cloud-init
- name: Start Harbor service
ansible.builtin.systemd:
name: harbor
state: started
enabled: true
18 changes: 18 additions & 0 deletions terraform/modules/harbor-standalone/files/harbor-systemd.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Source https://github.com/goharbor/harbor/blob/04a140332ef92e12531fc0b5b839d3222036b8b0/tools/systemd/harbor.service

[Unit]
Description=Harbor Cloud Native Registry
Documentation=https://goharbor.io
After=docker.service
Requires=docker.service

[Service]
Type=simple
Restart=on-failure
RestartSec=5
ExecStart=docker compose -f /harbor/docker-compose.yml up
ExecStop=docker compose -f /harbor/docker-compose.yml down -v
ExecStopPost=docker compose -f /harbor/docker-compose.yml rm -f

[Install]
WantedBy=multi-user.target
3 changes: 3 additions & 0 deletions terraform/modules/harbor-standalone/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
output "harbor_instance_ip" {
value = vsphere_virtual_machine.harbor.default_ip_address
}
20 changes: 20 additions & 0 deletions terraform/modules/harbor-standalone/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
variable "vm_authorized_key" {
description = "Public key authorized to ssh into the VM"
type = string
}

variable "domain" {
type = string
}

variable "vsphere" {

description = "vSphere related references to deploy the VM"

type = object({
resource_pool_id = string
datastore_id = string
network_id = string
template_id = string
})
}
1 change: 1 addition & 0 deletions terraform/modules/harbor-standalone/version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0.0.1
18 changes: 18 additions & 0 deletions terraform/modules/harbor-standalone/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
terraform {
required_providers {
cloudinit = {
source = "hashicorp/cloudinit"
version = "~> 2.3, < 3.0.0"
}

random = {
source = "hashicorp/random"
version = "~> 3.6, < 4.0.0"
}

vsphere = {
source = "hashicorp/vsphere"
version = "~> 2.6, < 3.0.0"
}
}
}
Loading

0 comments on commit b4fce90

Please sign in to comment.