From c955a6f800e31c80431fd00b4c6e93bd63913459 Mon Sep 17 00:00:00 2001 From: shipperizer Date: Tue, 14 Jan 2025 10:20:33 +0000 Subject: [PATCH] ci: add remote deployment --- .github/workflows/_deploy.yaml | 55 +++++++++++++++++++++++ .github/workflows/on_push.yaml | 5 +++ .github/workflows/publish.yaml | 82 ++++++++++++++++++++++++++++++++-- .github/workflows/release.yaml | 60 +++++++++++++++++++++++++ deployment/main.tf | 80 +++++++++++++++++++++++++++++++++ 5 files changed, 279 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/_deploy.yaml create mode 100644 deployment/main.tf diff --git a/.github/workflows/_deploy.yaml b/.github/workflows/_deploy.yaml new file mode 100644 index 00000000..34c4d6cc --- /dev/null +++ b/.github/workflows/_deploy.yaml @@ -0,0 +1,55 @@ +# reusable workflow triggered manually +name: Deploy via JIMM + +on: + workflow_call: + inputs: + model: + type: string + revision: + type: string + channel: + type: string + secrets: + CLIENT_ID: + required: true + CLIENT_SECRET: + required: true + JIMM_URL: + required: true + +jobs: + deploy: + name: Deploy + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@v4 + - uses: hashicorp/setup-terraform@v3 + with: + terraform_wrapper: false + - name: "Set environment to configure provider" + # language=bash + run: | + echo "TF_VAR_client_id=${{ secrets.CLIENT_ID }}" >> $GITHUB_ENV + echo "TF_VAR_client_secret=${{ secrets.CLIENT_SECRET }}" >> $GITHUB_ENV + echo "TF_VAR_jimm_url=${{ secrets.JIMM_URL }}" >> $GITHUB_ENV + - name: Import application into state if present + working-directory: ./deployment + run: | + terraform init + terraform import juju_application.application ${{ inputs.model}}:hydra || true + env: + TF_VAR_model: ${{ inputs.model }} + TF_VAR_revision: ${{ inputs.revision }} + TF_VAR_channel: ${{ inputs.channel }} + TF_VAR_application_name: "hydra" + + - name: Deploy + working-directory: ./deployment + run: | + terraform apply --auto-approve + env: + TF_VAR_model: ${{ inputs.model }} + TF_VAR_revision: ${{ inputs.revision }} + TF_VAR_channel: ${{ inputs.channel }} + TF_VAR_application_name: "hydra" diff --git a/.github/workflows/on_push.yaml b/.github/workflows/on_push.yaml index db3ad2a8..43b62374 100644 --- a/.github/workflows/on_push.yaml +++ b/.github/workflows/on_push.yaml @@ -25,3 +25,8 @@ jobs: uses: ./.github/workflows/publish.yaml secrets: CHARMCRAFT_CREDENTIALS: ${{ secrets.CHARMCRAFT_CREDENTIALS }} + JIMM_DEV_CLIENT_ID: ${{ secrets.JIMM_DEV_CLIENT_ID }} + JIMM_DEV_CLIENT_SECRET: ${{ secrets.JIMM_DEV_CLIENT_SECRET }} + JIMM_STG_CLIENT_ID: ${{ secrets.JIMM_STG_CLIENT_ID }} + JIMM_STG_CLIENT_SECRET: ${{ secrets.JIMM_STG_CLIENT_SECRET }} + JIMM_URL: ${{ secrets.JIMM_URL }} diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index eca70af4..c348f586 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -1,5 +1,7 @@ # reusable workflow for publishing all charms in this repo -name: Publish +name: Publish and Deploy +run-name: Publish to ${{ inputs.destination_channel}} and deploy + on: workflow_call: @@ -12,6 +14,16 @@ on: secrets: CHARMCRAFT_CREDENTIALS: required: true + JIMM_DEV_CLIENT_ID: + required: true + JIMM_DEV_CLIENT_SECRET: + required: true + JIMM_STG_CLIENT_ID: + required: true + JIMM_STG_CLIENT_SECRET: + required: true + JIMM_URL: + required: true workflow_dispatch: inputs: @@ -30,7 +42,8 @@ jobs: publish-charm: name: Publish Charm runs-on: ubuntu-24.04 - + outputs: + channel: ${{ steps.parse-inputs.outputs.destination_channel }} steps: - name: Checkout uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 @@ -57,7 +70,7 @@ jobs: uses: canonical/setup-lxd@v0.1.2 with: channel: latest/stable - + - name: Upload charm to charmhub uses: canonical/charming-actions/upload-charm@934193396735701141a1decc3613818e412da606 # 2.6.3 with: @@ -65,3 +78,66 @@ jobs: github-token: ${{ secrets.GITHUB_TOKEN }} channel: ${{ steps.parse-inputs.outputs.destination_channel }} destructive-mode: false + + revision: + concurrency: + group: ${{ inputs.source_branch }}-${{ needs.publish-charm.outputs.channel }} + cancel-in-progress: true + needs: publish-charm + outputs: + revision: ${{ steps.set-revision.outputs.revision }} + runs-on: ubuntu-24.04 + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + with: + fetch-depth: 0 + ref: ${{ inputs.source_branch }} + - name: Set revision + id: set-revision + run: | + sudo snap install charmcraft --classic --channel latest/stable + revision=$(charmcraft status ${{ env.CHARM_NAME }} --format json | jq '.[] | select(.track == "${{ env.TRACK }}") | .mappings[0].releases[] | select(.channel == "${{ needs.publish-charm.outputs.channel }}") | .revision') + echo "setting output of revision=$revision" + echo "revision=$revision" >> $GITHUB_OUTPUT + env: + CHARMCRAFT_AUTH: ${{ secrets.CHARMCRAFT_CREDENTIALS }} + CHARM_NAME: hydra + # only cater for latest track for now + TRACK: latest + + dev-deploy: + concurrency: + group: ${{ inputs.source_branch }}-${{ needs.publish-charm.outputs.channel }} + cancel-in-progress: true + needs: + - publish-charm + - revision + if: ${{ (needs.publish-charm.outputs.channel == 'latest/edge') }} + uses: "./.github/workflows/_deploy.yaml" + secrets: + CLIENT_ID: ${{ secrets.JIMM_DEV_CLIENT_ID }} + CLIENT_SECRET: ${{ secrets.JIMM_DEV_CLIENT_SECRET }} + JIMM_URL: ${{ secrets.JIMM_URL }} + with: + model: dev-iam + revision: ${{ needs.revision.outputs.revision }} + channel: ${{ needs.publish-charm.outputs.channel}} + + stg-deploy: + concurrency: + group: ${{ inputs.source_branch }}-${{ needs.publish-charm.outputs.channel }} + cancel-in-progress: true + needs: + - publish-charm + - revision + if: ${{ (needs.publish-charm.outputs.channel == 'latest/stable') }} + uses: "./.github/workflows/_deploy.yaml" + secrets: + CLIENT_ID: ${{ secrets.JIMM_STG_CLIENT_ID }} + CLIENT_SECRET: ${{ secrets.JIMM_STG_CLIENT_SECRET }} + JIMM_URL: ${{ secrets.JIMM_URL }} + with: + model: stg-iam + revision: ${{ needs.revision.outputs.revision }} + channel: ${{ needs.publish-charm.outputs.channel}} diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index dce0dfc2..c5280d20 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -25,3 +25,63 @@ jobs: destination-channel: ${{ github.event.inputs.destination-channel }} origin-channel: ${{ github.event.inputs.origin-channel }} base-channel: '22.04' + + revision: + concurrency: + group: ${{ github.event.inputs.destination-channel }} + cancel-in-progress: true + needs: promote-charm + outputs: + revision: ${{ steps.set-revision.outputs.revision }} + runs-on: ubuntu-24.04 + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + with: + fetch-depth: 0 + - name: Get revision + id: set-revision + run: | + sudo snap install charmcraft --classic --channel latest/stable + revision=$(charmcraft status ${{ env.CHARM_NAME }} --format json | jq '.[] | select(.track == "${{ env.TRACK }}") | .mappings[0].releases[] | select(.channel == "${{ github.event.inputs.destination-channel }}") | .revision') + echo "setting output of revision=$revision" + echo "revision=$revision" >> $GITHUB_OUTPUT + env: + CHARMCRAFT_AUTH: ${{ secrets.CHARMCRAFT_CREDENTIALS }} + CHARM_NAME: hydra + # only cater for latest track for now + TRACK: latest + + dev-deploy: + concurrency: + group: ${{ github.event.inputs.destination-channel }} + cancel-in-progress: true + needs: + - promote-charm + - revision + if: ${{ (github.event.inputs.destination-channel == 'latest/edge') }} + uses: ./.github/workflows/_deploy.yaml + secrets: + CLIENT_ID: ${{ secrets.JIMM_DEV_CLIENT_ID }} + CLIENT_SECRET: ${{ secrets.JIMM_DEV_CLIENT_SECRET }} + JIMM_URL: ${{ secrets.JIMM_URL }} + with: + model: dev-iam + revision: ${{ needs.revision.outputs.revision }} + + stg-deploy: + concurrency: + group: ${{ github.event.inputs.destination-channel }} + cancel-in-progress: true + needs: + - promote-charm + - revision + if: ${{ (github.event.inputs.destination-channel == 'latest/stable') }} + uses: ./.github/workflows/_deploy.yaml + secrets: + CLIENT_ID: ${{ secrets.JIMM_STG_CLIENT_ID }} + CLIENT_SECRET: ${{ secrets.JIMM_STG_CLIENT_SECRET }} + JIMM_URL: ${{ secrets.JIMM_URL }} + with: + model: stg-iam + revision: ${{ needs.revision.outputs.revision }} diff --git a/deployment/main.tf b/deployment/main.tf new file mode 100644 index 00000000..9d5dff1e --- /dev/null +++ b/deployment/main.tf @@ -0,0 +1,80 @@ +terraform { + required_providers { + juju = { + version = ">= 0.15.0" + source = "juju/juju" + } + } +} + +variable "client_id" { + type = string + sensitive = true +} + +variable "client_secret" { + type = string + sensitive = true +} + +variable "jimm_url" { + type = string +} + +variable "model" { + type = string +} + +variable "charm" { + description = "The configurations of the application." + type = object({ + name = optional(string, "kratos") + units = optional(number, 1) + base = optional(string, "ubuntu@22.04") + trust = optional(string, true) + config = optional(map(string), {}) + }) + default = {} +} + +variable "application_name" { + type = string +} + +variable "revision" { + type = number +} + +variable "channel" { + type = string +} + +provider "juju" { + controller_addresses = var.jimm_url + + client_id = var.client_id + client_secret = var.client_secret + +} + +data "juju_model" "model" { + name = var.model +} + + +resource "juju_application" "application" { + model = data.juju_model.model.name + name = var.application_name + trust = var.charm.trust + units = var.charm.units + + charm { + name = var.charm.name + base = var.charm.base + revision = var.revision + channel = var.channel + } + + config = var.charm.config + +}