From 9ffca89fcc9807cfd4bda4b65434cf1cb92084a5 Mon Sep 17 00:00:00 2001 From: Pratapa Lakshmi Date: Sun, 26 May 2024 16:16:18 +0530 Subject: [PATCH] chore: update ansible docker deployment steps feat: add steps to create ami image and push to marketplace feat: add steps to publish ami image chore: update github action changes update github actions to assume role --- .github/workflows/packer-build-ami.yml | 43 +++++++++++++ deploy/ansible/ballerine_playbook/README.md | 4 +- .../roles/setup-ballerine/defaults/main.yml | 4 ++ .../tasks/cleanup-packer-build.yml | 12 ++++ .../setup-ballerine/tasks/clone-ballerine.yml | 9 +++ .../tasks/deploy-ballerine.yml | 11 ++++ .../setup-ballerine/tasks/install-docker.yml | 6 +- .../roles/setup-ballerine/tasks/main.yml | 19 +++++- .../tasks/setup-ballerine-runtime.yml | 39 ++++++++++++ .../setup-ballerine/tasks/setup-ballerine.yml | 15 +---- .../tasks/setup-init-config.yml | 25 ++++++++ .../setup-ballerine/tasks/setup-user-data.yml | 9 +++ .../roles/setup-ballerine/templates/boot.sh | 11 ++++ .../templates/cloud-config.cfg | 5 ++ .../setup-ballerine/templates/init-ssh.sh | 17 +++++ .../setup-ballerine/templates/user-data.sh | 8 +++ deploy/aws_ami/defaults.cfg | 5 ++ deploy/aws_ami/template.json.pkr.hcl | 62 +++++++++++++++++++ 18 files changed, 284 insertions(+), 20 deletions(-) create mode 100644 .github/workflows/packer-build-ami.yml create mode 100644 deploy/ansible/ballerine_playbook/roles/setup-ballerine/tasks/cleanup-packer-build.yml create mode 100644 deploy/ansible/ballerine_playbook/roles/setup-ballerine/tasks/clone-ballerine.yml create mode 100644 deploy/ansible/ballerine_playbook/roles/setup-ballerine/tasks/deploy-ballerine.yml create mode 100644 deploy/ansible/ballerine_playbook/roles/setup-ballerine/tasks/setup-ballerine-runtime.yml create mode 100644 deploy/ansible/ballerine_playbook/roles/setup-ballerine/tasks/setup-init-config.yml create mode 100644 deploy/ansible/ballerine_playbook/roles/setup-ballerine/tasks/setup-user-data.yml create mode 100644 deploy/ansible/ballerine_playbook/roles/setup-ballerine/templates/boot.sh create mode 100644 deploy/ansible/ballerine_playbook/roles/setup-ballerine/templates/cloud-config.cfg create mode 100644 deploy/ansible/ballerine_playbook/roles/setup-ballerine/templates/init-ssh.sh create mode 100644 deploy/ansible/ballerine_playbook/roles/setup-ballerine/templates/user-data.sh create mode 100644 deploy/aws_ami/defaults.cfg create mode 100644 deploy/aws_ami/template.json.pkr.hcl diff --git a/.github/workflows/packer-build-ami.yml b/.github/workflows/packer-build-ami.yml new file mode 100644 index 0000000000..4782ca96a5 --- /dev/null +++ b/.github/workflows/packer-build-ami.yml @@ -0,0 +1,43 @@ +name: Packer build AWS AMI's +on: + workflow_dispatch: + branches: + - prod + +jobs: + plan: + environment: Terraform + defaults: + run: + working-directory: /home/runner/work/ballerine/deploy/aws_ami + runs-on: ubuntu-latest + name: Packer build Artifacts + steps: + - name: Checkout to Git + uses: actions/checkout@v2 + + - name: Assume Role + uses: ./ + env: + ROLE_ARN: ${{ secrets.AWS_PACKER_ROLE }} + ROLE_SESSION_NAME: packersession + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + DURATION_SECONDS: 900 + + - name: Setup `packer` + uses: hashicorp/setup-packer@main + id: setup + with: + version: 1.8.7 + + - name: Run `packer init` + id: init + run: "packer init template.json.pkr.hcl" + + - name: Run `packer validate` + id: validate + run: "packer validate template.json.pkr.hcl" + + - name: Build AWS AMIs + run: "packer build template.json.pkr.hcl" diff --git a/deploy/ansible/ballerine_playbook/README.md b/deploy/ansible/ballerine_playbook/README.md index 29fcf66972..4c6e967218 100644 --- a/deploy/ansible/ballerine_playbook/README.md +++ b/deploy/ansible/ballerine_playbook/README.md @@ -99,7 +99,7 @@ You can run the ansible playbook with the following command ```bash cd ballerine/deploy/ansible/ballerine_playbook -ansible-playbook -i inventory.txt ballerine-playbook.yml +ansible-playbook -i inventory.txt ballerine-playbook.yml --skip-tags packer ``` The command above will use the host information from the `inventory` file. @@ -110,4 +110,4 @@ When it's all done, provided all went well and no parameters were changed, you s ## Make entries to the DNS server -Make sure the appropriate entries for the url in DNS are created \ No newline at end of file +Make sure the appropriate entries for the url in DNS are created diff --git a/deploy/ansible/ballerine_playbook/roles/setup-ballerine/defaults/main.yml b/deploy/ansible/ballerine_playbook/roles/setup-ballerine/defaults/main.yml index cf0fb8648a..bfae8a5ddc 100644 --- a/deploy/ansible/ballerine_playbook/roles/setup-ballerine/defaults/main.yml +++ b/deploy/ansible/ballerine_playbook/roles/setup-ballerine/defaults/main.yml @@ -3,6 +3,10 @@ docker_edition: 'ce' docker_package: 'docker-{{ docker_edition }}' docker_package_state: present +default_user: ubuntu + +cloud_user: ballerine +cloud_group: ballerine # Service options. docker_service_state: started diff --git a/deploy/ansible/ballerine_playbook/roles/setup-ballerine/tasks/cleanup-packer-build.yml b/deploy/ansible/ballerine_playbook/roles/setup-ballerine/tasks/cleanup-packer-build.yml new file mode 100644 index 0000000000..cc9ad73e86 --- /dev/null +++ b/deploy/ansible/ballerine_playbook/roles/setup-ballerine/tasks/cleanup-packer-build.yml @@ -0,0 +1,12 @@ +--- +- name: Remove sensitive credential (1) + shell: find / -name "authorized_keys" -exec rm -f {} \; + become: true + +- name: Remove sensitive credential (2) + shell: find /root/ /home/*/ -name .cvspass -exec rm -f {} \; + become: true + +- name: Restart rsyslog + shell: service rsyslog restart + become: true diff --git a/deploy/ansible/ballerine_playbook/roles/setup-ballerine/tasks/clone-ballerine.yml b/deploy/ansible/ballerine_playbook/roles/setup-ballerine/tasks/clone-ballerine.yml new file mode 100644 index 0000000000..8cf3b2fd84 --- /dev/null +++ b/deploy/ansible/ballerine_playbook/roles/setup-ballerine/tasks/clone-ballerine.yml @@ -0,0 +1,9 @@ +--- +- name: Clone Ballerine + git: + repo: https://github.com/ballerine-io/ballerine.git + dest: "{{ install_dir }}" + version: dev + clone: yes + update: yes + ignore_errors: yes diff --git a/deploy/ansible/ballerine_playbook/roles/setup-ballerine/tasks/deploy-ballerine.yml b/deploy/ansible/ballerine_playbook/roles/setup-ballerine/tasks/deploy-ballerine.yml new file mode 100644 index 0000000000..443250a49f --- /dev/null +++ b/deploy/ansible/ballerine_playbook/roles/setup-ballerine/tasks/deploy-ballerine.yml @@ -0,0 +1,11 @@ +- name: Deploy Ballerine with localhost + shell: sudo docker-compose -f docker-compose-build.yml up -d + args: + chdir: "{{ install_dir }}/deploy" + when: vite_api_url == "" + +- name: Deploy Ballerine with custom Domain + shell: sudo docker-compose -f docker-compose-build-https.yml up -d + args: + chdir: "{{ install_dir }}/deploy" + when: vite_api_url != "" \ No newline at end of file diff --git a/deploy/ansible/ballerine_playbook/roles/setup-ballerine/tasks/install-docker.yml b/deploy/ansible/ballerine_playbook/roles/setup-ballerine/tasks/install-docker.yml index 6ff694ac49..0f75dd4f2b 100644 --- a/deploy/ansible/ballerine_playbook/roles/setup-ballerine/tasks/install-docker.yml +++ b/deploy/ansible/ballerine_playbook/roles/setup-ballerine/tasks/install-docker.yml @@ -24,15 +24,13 @@ - libnss3-tools state: latest become: true - tags: - - always + - name: Upgrade dist to apply security fixes ansible.builtin.apt: upgrade: dist become: true - tags: - - always + - name: Ensure old versions of Docker are not installed package: diff --git a/deploy/ansible/ballerine_playbook/roles/setup-ballerine/tasks/main.yml b/deploy/ansible/ballerine_playbook/roles/setup-ballerine/tasks/main.yml index 60912ea821..da99b9e573 100644 --- a/deploy/ansible/ballerine_playbook/roles/setup-ballerine/tasks/main.yml +++ b/deploy/ansible/ballerine_playbook/roles/setup-ballerine/tasks/main.yml @@ -3,8 +3,25 @@ package_facts: manager: auto -- include_tasks: install-docker.yml +- import_tasks: install-docker.yml - import_tasks: start-docker.yml +- import_tasks: clone-ballerine.yml + +- import_tasks: setup-init-config.yml + tags: packer + - import_tasks: setup-ballerine.yml + +- import_tasks: setup-ballerine-runtime.yml + tags: packer + +- import_tasks: deploy-ballerine.yml + tags: deploy + +- import_tasks: setup-user-data.yml + tags: packer + +- import_tasks: cleanup-packer-build.yml + tags: packer \ No newline at end of file diff --git a/deploy/ansible/ballerine_playbook/roles/setup-ballerine/tasks/setup-ballerine-runtime.yml b/deploy/ansible/ballerine_playbook/roles/setup-ballerine/tasks/setup-ballerine-runtime.yml new file mode 100644 index 0000000000..75782f49f1 --- /dev/null +++ b/deploy/ansible/ballerine_playbook/roles/setup-ballerine/tasks/setup-ballerine-runtime.yml @@ -0,0 +1,39 @@ +- name: create runtime path folder + file: + dest: "{{ install_dir }}/scripts" + mode: 0755 + recurse: yes + owner: "{{ cloud_user }}" + group: "{{ cloud_group }}" + state: directory + +- name: create boot script + template: + src: templates/boot.sh + dest: "{{ install_dir }}/scripts/boot.sh" + mode: 0755 + +- name: create reboot entry job + cron: + name: "ballerine job" + special_time: reboot + user: "{{ cloud_user }}" + job: "{{ install_dir }}/scripts/boot.sh" + +- name: setup ssh key for ballerine user + copy: + src: templates/init-ssh.sh + dest: /var/lib/cloud/scripts/per-instance + mode: 0755 + owner: "{{ cloud_user }}" + group: "{{ cloud_group }}" + become: true + +- name: setup ssh key for {{ default_user }} user + copy: + src: templates/init-ssh.sh + dest: /var/lib/cloud/scripts/per-instance + mode: 0755 + owner: "{{ default_user }}" + group: "{{ cloud_group }}" + become: true \ No newline at end of file diff --git a/deploy/ansible/ballerine_playbook/roles/setup-ballerine/tasks/setup-ballerine.yml b/deploy/ansible/ballerine_playbook/roles/setup-ballerine/tasks/setup-ballerine.yml index db93b96e7d..5e48b6228c 100644 --- a/deploy/ansible/ballerine_playbook/roles/setup-ballerine/tasks/setup-ballerine.yml +++ b/deploy/ansible/ballerine_playbook/roles/setup-ballerine/tasks/setup-ballerine.yml @@ -1,4 +1,5 @@ --- + - name: Replace VITE URL for backoffice lineinfile: path: '~/ballerine/apps/backoffice-v2/.env.example' @@ -33,16 +34,4 @@ ansible.builtin.template: src: templates/Caddyfile.j2 dest: "{{ install_dir }}/deploy/caddy/Caddyfile" - when: vite_api_url != "" - -- name: Deploy Ballerine up locally - shell: docker-compose -f docker-compose-build.yml up -d - args: - chdir: "{{ install_dir }}/deploy" - when: vite_api_url == "" - -- name: Deploy Ballerine up remote - shell: docker-compose -f docker-compose-build-https.yml up -d - args: - chdir: "{{ install_dir }}/deploy" - when: vite_api_url != "" + when: vite_api_url != "" \ No newline at end of file diff --git a/deploy/ansible/ballerine_playbook/roles/setup-ballerine/tasks/setup-init-config.yml b/deploy/ansible/ballerine_playbook/roles/setup-ballerine/tasks/setup-init-config.yml new file mode 100644 index 0000000000..3921effac9 --- /dev/null +++ b/deploy/ansible/ballerine_playbook/roles/setup-ballerine/tasks/setup-init-config.yml @@ -0,0 +1,25 @@ +--- +- name: deploy cloud init config file + template: src=templates/cloud-config.cfg dest=/etc/cloud/cloud.cfg.d/defaults.cfg + become: true + +- name: create group ballerine + group: name={{ cloud_user }} state=present + become: true + +- name: create user ballerine + user: name={{ cloud_user }} groups={{ cloud_group }} + become: true + +- name: create user {{ default_user }} + user: name={{ default_user }} groups={{ cloud_group }} + become: true + +- name: add sudoers group for user {{ cloud_user }} + copy: + content: 'ballerine ALL=(ALL) NOPASSWD: ALL' + dest: /etc/sudoers.d/ballerine + mode: 0440 + owner: root + group: root + become: true diff --git a/deploy/ansible/ballerine_playbook/roles/setup-ballerine/tasks/setup-user-data.yml b/deploy/ansible/ballerine_playbook/roles/setup-ballerine/tasks/setup-user-data.yml new file mode 100644 index 0000000000..265cf3de73 --- /dev/null +++ b/deploy/ansible/ballerine_playbook/roles/setup-ballerine/tasks/setup-user-data.yml @@ -0,0 +1,9 @@ +--- +- name: setup runtime user data + copy: + src: ../templates/user-data.sh + dest: /var/lib/cloud/scripts/per-instance + mode: 0755 + owner: "{{ cloud_user }}" + group: "{{ cloud_group }}" + become: true \ No newline at end of file diff --git a/deploy/ansible/ballerine_playbook/roles/setup-ballerine/templates/boot.sh b/deploy/ansible/ballerine_playbook/roles/setup-ballerine/templates/boot.sh new file mode 100644 index 0000000000..a35a24f27b --- /dev/null +++ b/deploy/ansible/ballerine_playbook/roles/setup-ballerine/templates/boot.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +cd /home/ballerine/ballerine + +git checkout dev ; git pull + +cd /home/ballerine/ballerine/deploy + +sudo docker-compose -f docker-compose-build.yml pull + +sudo docker-compose -f docker-compose-build.yml up -d diff --git a/deploy/ansible/ballerine_playbook/roles/setup-ballerine/templates/cloud-config.cfg b/deploy/ansible/ballerine_playbook/roles/setup-ballerine/templates/cloud-config.cfg new file mode 100644 index 0000000000..d54cdec92c --- /dev/null +++ b/deploy/ansible/ballerine_playbook/roles/setup-ballerine/templates/cloud-config.cfg @@ -0,0 +1,5 @@ +#cloud-config +system_info: + default_user: + name: ballerine + lock_passwd: false \ No newline at end of file diff --git a/deploy/ansible/ballerine_playbook/roles/setup-ballerine/templates/init-ssh.sh b/deploy/ansible/ballerine_playbook/roles/setup-ballerine/templates/init-ssh.sh new file mode 100644 index 0000000000..af532aaab7 --- /dev/null +++ b/deploy/ansible/ballerine_playbook/roles/setup-ballerine/templates/init-ssh.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +authorized_keys_path=/home/ballerine/.ssh/authorized_keys +if [[ ! -e "$authorized_keys_path" ]]; then + echo "Setting SSH key" + sudo cp ~/.ssh/authorized_keys "$authorized_keys_path" + sudo chown ballerine:ballerine "$authorized_keys_path" +fi + +authorized_keys_ubuntu_path=/home/ubuntu/.ssh/authorized_keys +if [[ ! -e "$authorized_keys_ubuntu_path" ]]; then + echo "Setting SSH key for ubuntu user" + sudo mkdir -p /home/ubuntu/.ssh/ + sudo chmod -R 700 /home/ubuntu/.ssh/ + sudo cp ~/.ssh/authorized_keys "$authorized_keys_ubuntu_path" + sudo chown -R ubuntu:ballerine /home/ubuntu/.ssh/ +fi \ No newline at end of file diff --git a/deploy/ansible/ballerine_playbook/roles/setup-ballerine/templates/user-data.sh b/deploy/ansible/ballerine_playbook/roles/setup-ballerine/templates/user-data.sh new file mode 100644 index 0000000000..7bc0f367cc --- /dev/null +++ b/deploy/ansible/ballerine_playbook/roles/setup-ballerine/templates/user-data.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +default_user_name="admin@admin.com" +default_user_password=admin + +echo "${default_user_name}:${default_user_password}" > /home/ballerine/ballerine/credential + +echo -e "\n***************************************************\n* Default username : $default_user_name *\n* Default password : $default_user_password *\n***************************************************\n" >/dev/console diff --git a/deploy/aws_ami/defaults.cfg b/deploy/aws_ami/defaults.cfg new file mode 100644 index 0000000000..d54cdec92c --- /dev/null +++ b/deploy/aws_ami/defaults.cfg @@ -0,0 +1,5 @@ +#cloud-config +system_info: + default_user: + name: ballerine + lock_passwd: false \ No newline at end of file diff --git a/deploy/aws_ami/template.json.pkr.hcl b/deploy/aws_ami/template.json.pkr.hcl new file mode 100644 index 0000000000..3134a352ac --- /dev/null +++ b/deploy/aws_ami/template.json.pkr.hcl @@ -0,0 +1,62 @@ +# Configuration - AWS base image +variable "base_ami" { + type = string + default = "ami-01e444924a2233b07" # Ubuntu 22.04.2 LTS +} + +# Configuration - AWS provisioning instance type +variable "instance_type" { + type = string + default = "t2.micro" +} + +# Configuration - AWS subnet +variable "subnet_id" { + type = string + default = "subnet-01d1b883a41235506" +} + +# Configuration - AWS VPC +variable "vpc_id" { + type = string + default = "vpc-0ed0113663b1fbf40" +} + + +# "timestamp" template function replacement +locals { timestamp = regex_replace(timestamp(), "[- TZ:]", "") } + +# Variable - AMI naming +locals { + image_name = "ballerine-marketplace-snapshot-${local.timestamp}" +} + +# Builder - Provision AWS instance +source "amazon-ebs" "ballerine-aws-ami" { + ami_name = "ballerine-ami-${local.timestamp}" + instance_type = "${var.instance_type}" + launch_block_device_mappings { + delete_on_termination = true + device_name = "/dev/sda1" + volume_size = 25 + volume_type = "gp2" + } + region = "eu-central-1" + source_ami = "${var.base_ami}" + ssh_username = "ballerine" + subnet_id = "${var.subnet_id}" + vpc_id = "${var.vpc_id}" + skip_create_ami = false + user_data_file = "./defaults.cfg" +} + +# Provisioning - Setup Ballerine +build { + sources = ["source.amazon-ebs.ballerine-aws-ami"] + + provisioner "ansible" { + user = "ballerine" + playbook_file = "../ansible/ballerine_playbook/ballerine-playbook.yml" + extra_arguments = ["--skip-tags", "deploy"] + } +}