--- - name: deploy browsertrix cloud on digital ocean hosts: localhost connection: local gather_facts: false vars_files: - ../group_vars/do/main.yml tasks: # =========================================== # Init - name: d_ocean | init | install doctl and helm ansible.builtin.package: name: "{{ item }}" state: present loop: - helm - doctl - name: d_ocean | init | set full domain ansible.builtin.set_fact: full_domain: "{{ subdomain + '.' + domain if subdomain else domain }}" # MongoDB # =========================================== - name: d_ocean | db | test for existing mongodb ansible.builtin.command: doctl db list -o json changed_when: false failed_when: false register: db_check - name: d_ocean | db | create mongodb database ansible.builtin.command: doctl databases create {{ db_name }} --region {{ droplet_region }} --engine mongodb --version 6 --output json async: 1800 poll: 60 register: db_create when: "db_check.stdout | from_json | json_query(name_query) | length < 1" changed_when: true vars: name_query: '[?name==`{{ db_name }}`]' - name: d_ocean | db | set db id ansible.builtin.set_fact: db_uuid: "{{ db_create.stdout if db_create.changed else db_check.stdout | from_json | json_query(name_query) | json_query('[0].id') }}" vars: name_query: '[?name==`{{ db_name }}`]' - name: d_ocean | db | reset db user password ansible.builtin.command: doctl databases user reset {{ db_uuid }} doadmin -o json register: db_user when: not db_create.changed changed_when: true - name: d_ocean | db | set db config ansible.builtin.set_fact: db_uuid: "{{ db_create.stdout if db_create.changed else db_check.stdout | from_json | json_query(name_query) | json_query('[0].id') }}" vars: name_query: '[?name==`{{ db_name }}`]' - name: d_ocean | db | set db config ansible.builtin.set_fact: db_url: "{{ db_check.stdout | from_json | json_query(name_query) | json_query('[0].private_connection.uri') | replace(old, new) }}" when: not db_create.changed vars: name_query: '[?name==`{{ db_name }}`]' old: ":@" new: ":{{ db_user.stdout | from_json | json_query('[0].password') }}@" # Storage (Space) # =========================================== - name: d_ocean | space | create new community.digitalocean.digital_ocean_spaces: name: "{{ bucket_name }}" state: present oauth_token: "{{ lookup('env', 'DO_API_TOKEN') }}" aws_access_key_id: "{{ lookup('env', 'DO_AWS_ACCESS_KEY') }}" aws_secret_access_key: "{{ lookup('env', 'DO_AWS_SECRET_KEY') }}" region: "{{ droplet_region }}" register: db_space_result ignore_errors: true - name: d_ocean | space | set endpoint urls ansible.builtin.set_fact: endpoint_url: "{{ db_space_result.data.space.endpoint_url }}/" bucket_endpoint_url: "{{ db_space_result.data.space.endpoint_url }}/{{ db_space_result.data.space.name }}/{{ bucket_path }}/" - name: d_ocean | space | set bucket cors community.aws.aws_s3_cors: name: "{{ bucket_name }}" aws_access_key: "{{ lookup('env', 'DO_AWS_ACCESS_KEY') }}" aws_secret_key: "{{ lookup('env', 'DO_AWS_SECRET_KEY') }}" endpoint_url: "{{ endpoint_url }}" region: "{{ droplet_region }}" state: present rules: - allowed_origins: - "https://{{ full_domain }}" allowed_methods: - GET - HEAD allowed_headers: - "*" expose_headers: - Content-Range - Content-Encoding - Content-Length # K8S # =========================================== - name: d_ocean | k8s | test for existing k8s cluster ansible.builtin.command: doctl k8s cluster list changed_when: false failed_when: false register: cluster_check - name: d_ocean | k8s | create a kubernetes cluster in {{ droplet_region }} # skip_ansible_lint ansible.builtin.command: >- doctl kubernetes cluster create {{ k8s_name }} --1-clicks ingress-nginx,cert-manager --node-pool "{{ node_pools | select('match', 'name=*') | list | join(',') }}" --region={{ droplet_region }} async: 1800 poll: 60 changed_when: false when: cluster_check.stdout.find(k8s_name) == -1 - name: d_ocean | k8s | test for existing k8s cluster's node pools ansible.builtin.command: doctl kubernetes cluster node-pool list {{ k8s_name }} changed_when: false failed_when: false register: cluster_nodepools_check - name: d_ocean | k8s | create a admin node pool in the cluster {{ k8s_name }} # skip_ansible_lint ansible.builtin.command: >- doctl kubernetes cluster node-pool create {{ k8s_name }} --name {{ admin_node_pool.name }} --size {{ admin_node_pool.size }} --label {{ admin_node_pool.label }} --count {{ admin_node_pool.count }} async: 1800 poll: 60 changed_when: false when: enable_admin_addons and cluster_nodepools_check.stdout.find(admin_node_pool.name) == -1 - name: d_ocean | k8s | remove a admin node pool from the cluster {{ k8s_name }} # skip_ansible_lint ansible.builtin.command: >- echo "yes" | doctl kubernetes cluster node-pool delete {{ k8s_name }} {{ admin_node_pool.name }} async: 1800 poll: 60 changed_when: false when: not enable_admin_addons and cluster_nodepools_check.stdout.find(admin_node_pool.name) >= 0 - name: d_ocean | k8s | Get information about our cluster community.digitalocean.digital_ocean_kubernetes_info: oauth_token: "{{ lookup('ansible.builtin.env', 'DO_API_TOKEN') }}" name: "{{ k8s_name }}" return_kubeconfig: true register: my_cluster - name: d_ocean | k8s | print information about an existing DigitalOcean Kubernetes cluster ansible.builtin.debug: msg: Cluster name is {{ my_cluster.data.name }}, ID is {{ my_cluster.data.id }} failed_when: not my_cluster - name: d_ocean | k8s | save kubectl config to kube_dir ansible.builtin.command: doctl kubernetes cluster kubeconfig save {{ my_cluster.data.id }} changed_when: false - name: d_ocean | k8s | get loadbalancer info from doctl ansible.builtin.command: doctl k8s cluster list-associated-resources {{ my_cluster.data.id }} --format LoadBalancers --output json register: lb_id_result retries: 100 delay: 5 changed_when: lb_id_result.stdout | from_json | json_query('load_balancers') | length > 0 until: lb_id_result.stdout | from_json | json_query('load_balancers') | length > 0 - name: d_ocean | k8s | parse lb id ansible.builtin.set_fact: lb_id: "{{ lb_id_result.stdout | from_json | json_query('load_balancers[0].id') }}" # FIREWALL # =========================================== - name: d_ocean | db | get db firewall list ansible.builtin.command: doctl db firewalls list {{ db_uuid }} -o json register: db_firewalls changed_when: true - name: d_ocean | db | configure firewall for mongoDB ansible.builtin.command: doctl db firewalls append {{ db_uuid }} --rule k8s:{{ my_cluster.data.id }} when: "db_firewalls.stdout == []" changed_when: true # if it runs, it's changed # DNS # =========================================== - name: d_ocean | dns | grab loadbalancer ip using doctl ansible.builtin.command: doctl compute load-balancer get --format IP "{{ lb_id }}" register: loadbalancer_ip_result retries: 100 delay: 5 changed_when: loadbalancer_ip_result.stdout_lines | length > 1 until: loadbalancer_ip_result.stdout_lines | length > 1 - name: d_ocean | dns | parse ip ansible.builtin.set_fact: lb_ip: "{{ loadbalancer_ip_result.stdout_lines[1] }}" - name: d_ocean | dns | register the dns for browsertrix cloud ansible.builtin.command: >- doctl compute domain records create --record-type A --record-name "{{ subdomain if subdomain else '@' }}" --record-data "{{ lb_ip }}" "{{ domain }}" changed_when: dns_result.rc == 0 register: dns_result # Signing + DNS # =========================================== - name: d_ocean | signing | set signing domain + authtoken ansible.builtin.set_fact: full_signing_domain: "{{ signing_host }}.{{ full_domain }}" signing_subdomain: "{{ signing_host + '.' + subdomain if subdomain else signing_host }}" signing_authtoken: "{{ 99999999 | random | to_uuid }}" when: enable_signing changed_when: true - name: d_ocean | signing | check signing record exists ansible.builtin.command: doctl compute domain records ls {{ domain }} -o json register: check_domain changed_when: true - name: d_ocean | signing | register the dns for signing subdomain ansible.builtin.command: >- doctl compute domain records create --record-type A --record-name "{{ signing_subdomain }}" --record-data "{{ lb_ip }}" "{{ domain }}" register: signing_dns_result when: "check_domain.stdout | from_json | json_query(name_query) | length < 1" changed_when: true # if it ran, it changed vars: name_query: '[?name==`{{ signing_subdomain }}`]' # Registry # =========================================== - name: d_ocean | registry | get endpoint, if using registry ansible.builtin.command: doctl registry get --format Endpoint register: do_registry_result when: use_do_registry changed_when: true failed_when: do_registry_result.stdout_lines | length < 2 - name: d_ocean | registry | store registry endpoint ansible.builtin.set_fact: registry_endpoint: "{{ do_registry_result.stdout_lines[1] }}" when: use_do_registry changed_when: true - name: d_ocean | registry | configure kubectl ansible.builtin.command: doctl k8s cluster kubeconfig save {{ my_cluster.data.id }} when: configure_kubectl changed_when: true - name: d_ocean | registry | add to new k8s cluster ansible.builtin.shell: set -o pipefail && doctl registry kubernetes-manifest | kubectl apply -f - when: use_do_registry changed_when: true # Addons # =========================================== - name: d_ocean | addons | run all admin bookstrap scripts ansible.builtin.command: >- ../../chart/admin/logging/scripts/eck_install.sh register: addons_init when: enable_admin_addons changed_when: true # Helm Output + Deploy # =========================================== - name: d_ocean | helm | output values yaml ansible.builtin.template: src: ../group_vars/do/do-values.template.yaml dest: ../deploys/{{ project_name }}-values.yaml mode: u+rw - name: d_ocean | helm | deploy btrix ansible.builtin.command: helm upgrade --install -f ../../chart/values.yaml -f ../deploys/{{ project_name }}-values.yaml btrix ../../chart/ register: helm_result changed_when: helm_result.rc == 0 tags: helm_upgrade