|
| 1 | +--- |
| 2 | +name: Build and Publish VM Image |
| 3 | + |
| 4 | +on: |
| 5 | + workflow_call: |
| 6 | + inputs: |
| 7 | + distrib: |
| 8 | + required: true |
| 9 | + type: string |
| 10 | + |
| 11 | +env: |
| 12 | + GCP_DEV_PROJECT: cosmian-dev |
| 13 | + GCP_PUBLIC_PROJECT: cosmian-public |
| 14 | + |
| 15 | +jobs: |
| 16 | + build-kms-cosmian-vm-image: |
| 17 | + name: Build KMS in Cosmian VM Image for SEV |
| 18 | + runs-on: ubuntu-22.04 |
| 19 | + outputs: |
| 20 | + timestamp: ${{ steps.env.outputs.TIMESTAMP }} |
| 21 | + image_name: ${{ steps.env.outputs.IMAGE_NAME }} |
| 22 | + ci_instance: ${{ steps.env.outputs.CI_INSTANCE }} |
| 23 | + permissions: |
| 24 | + contents: read |
| 25 | + id-token: write |
| 26 | + defaults: |
| 27 | + run: |
| 28 | + working-directory: ./packer |
| 29 | + steps: |
| 30 | + - name: Checkout |
| 31 | + uses: actions/checkout@v4 |
| 32 | + - uses: actions/download-artifact@v3 |
| 33 | + |
| 34 | + - name: List artifacts |
| 35 | + run: | |
| 36 | + find .. |
| 37 | +
|
| 38 | + - name: Create env variables |
| 39 | + id: env |
| 40 | + run: | |
| 41 | + TIMESTAMP="$(date -u +'%Y%m%d%H%M%S')" |
| 42 | + echo "TIMESTAMP=$TIMESTAMP" >> "$GITHUB_OUTPUT" |
| 43 | + echo "IMAGE_NAME=alpha-$TIMESTAMP-cosmian-vm-kms-sev-${{ inputs.distrib }}" >> "$GITHUB_OUTPUT" |
| 44 | + echo "CI_INSTANCE=gh-ci-cosmian-vm-kms-$TIMESTAMP-${{ inputs.distrib }}" >> "$GITHUB_OUTPUT" |
| 45 | +
|
| 46 | + - name: Setup `packer` |
| 47 | + uses: hashicorp/setup-packer@main |
| 48 | + |
| 49 | + - name: Run `packer init` |
| 50 | + run: packer init -machine-readable gcp-sev-${{ inputs.distrib }}.pkr.hcl |
| 51 | + |
| 52 | + - name: Install plugins |
| 53 | + run: | |
| 54 | + packer plugins install github.com/hashicorp/amazon |
| 55 | + packer plugins install github.com/hashicorp/googlecompute |
| 56 | +
|
| 57 | + - name: Authenticate to Google Cloud project |
| 58 | + uses: google-github-actions/auth@v2 |
| 59 | + with: |
| 60 | + credentials_json: ${{ secrets.GOOGLE_COSMIAN_DEV_CREDENTIALS }} |
| 61 | + |
| 62 | + - name: Build GCP images - main |
| 63 | + env: |
| 64 | + TIMESTAMP: ${{ steps.env.outputs.TIMESTAMP }} |
| 65 | + if: startsWith(github.ref, 'refs/tags/') != true |
| 66 | + run: | |
| 67 | + packer build -var "prefix=alpha-$TIMESTAMP" gcp-sev-${{ inputs.distrib }}.pkr.hcl |
| 68 | +
|
| 69 | + test-image: |
| 70 | + name: Test image |
| 71 | + runs-on: ubuntu-22.04 |
| 72 | + needs: build-kms-cosmian-vm-image |
| 73 | + permissions: |
| 74 | + contents: read |
| 75 | + id-token: write |
| 76 | + steps: |
| 77 | + - name: Checkout |
| 78 | + uses: actions/checkout@v4 |
| 79 | + |
| 80 | + - name: GCP auth |
| 81 | + uses: google-github-actions/auth@v2 |
| 82 | + with: |
| 83 | + credentials_json: ${{ secrets.GOOGLE_COSMIAN_DEV_CREDENTIALS }} |
| 84 | + |
| 85 | + - name: Set up Google Cloud SDK |
| 86 | + uses: google-github-actions/setup-gcloud@v2 |
| 87 | + with: |
| 88 | + version: latest |
| 89 | + install_components: beta |
| 90 | + |
| 91 | + - name: Launch GCP instance |
| 92 | + id: run-gcp-instance |
| 93 | + env: |
| 94 | + IMAGE_NAME: ${{ needs.build-kms-cosmian-vm-image.outputs.image_name }} |
| 95 | + CI_INSTANCE: ${{ needs.build-kms-cosmian-vm-image.outputs.ci_instance }} |
| 96 | + run: | |
| 97 | + gcloud beta compute instances create $CI_INSTANCE --machine-type n2d-standard-2 \ |
| 98 | + --zone europe-west4-a \ |
| 99 | + --min-cpu-platform="AMD Milan" \ |
| 100 | + --confidential-compute-type=SEV_SNP \ |
| 101 | + --maintenance-policy=TERMINATE \ |
| 102 | + --image="$IMAGE_NAME" \ |
| 103 | + --image-project=$GCP_DEV_PROJECT \ |
| 104 | + --project $GCP_DEV_PROJECT \ |
| 105 | + --tags ssh-full,backend,http-server,https-server,cosmian-vm-agent \ |
| 106 | + --metadata-from-file=startup-script=scripts/gcp-start-${{ inputs.distrib }}.sh \ |
| 107 | + --max-run-duration=10m \ |
| 108 | + --instance-termination-action=DELETE |
| 109 | + IP_ADDR=$(gcloud beta compute instances describe $CI_INSTANCE --format='get(networkInterfaces[0].accessConfigs[0].natIP)' --zone=europe-west4-a) |
| 110 | + echo "IP_ADDR=${IP_ADDR}" >> "$GITHUB_OUTPUT" |
| 111 | +
|
| 112 | + - name: Download Cosmian VM client |
| 113 | + run: | |
| 114 | + wget https://package.cosmian.com/cosmian_vm/1.1.0-rc.1/cosmian_vm |
| 115 | +
|
| 116 | + - name: Change permissions of binaries |
| 117 | + run: | |
| 118 | + chmod +x ./cosmian_vm |
| 119 | +
|
| 120 | + - name: Test Cosmian VM Agent on GCP instance |
| 121 | + env: |
| 122 | + IP_ADDR: ${{ steps.run-gcp-instance.outputs.IP_ADDR }} |
| 123 | + run: | |
| 124 | + echo "Waiting for Cosmian VM agent..." |
| 125 | + until curl --insecure --output /dev/null --silent --fail https://${IP_ADDR}:5355/ima/ascii; do sleep 3; done |
| 126 | + echo "[ OK ] Cosmian VM ready" |
| 127 | + ./cosmian_vm --url https://${IP_ADDR}:5355 --allow-insecure-tls snapshot |
| 128 | + ./cosmian_vm --url https://${IP_ADDR}:5355 --allow-insecure-tls verify --snapshot ./cosmian_vm.snapshot |
| 129 | +
|
| 130 | + - name: Test KMS conf deployment with Cosmian VM CLI |
| 131 | + env: |
| 132 | + IP_ADDR: ${{ steps.run-gcp-instance.outputs.IP_ADDR }} |
| 133 | + run: | |
| 134 | + ./cosmian_vm --url https://${IP_ADDR}:5355 --allow-insecure-tls app init -c resources/kms.toml |
| 135 | +
|
| 136 | + - name: Test KMS on the Cosmian VM |
| 137 | + env: |
| 138 | + IP_ADDR: ${{ steps.run-gcp-instance.outputs.IP_ADDR }} |
| 139 | + run: | |
| 140 | + echo "Checking Cosmian KMS HTTP connection..." |
| 141 | + curl http://${IP_ADDR}:8080/version |
| 142 | + echo "" |
| 143 | + echo "[ OK ] Cosmian KMS HTTP connection" |
| 144 | + echo "Checking Cosmian KMS HTTPS connection..." |
| 145 | + curl --insecure https://${IP_ADDR}/version |
| 146 | + echo "" |
| 147 | + echo "[ OK ] Cosmian KMS HTTPS connection" |
| 148 | + echo "Checking Cosmian KMS HTTP to HTTPS redirect connection..." |
| 149 | + curl --insecure http://${IP_ADDR}/version |
| 150 | + echo "" |
| 151 | + echo "[ OK ] Cosmian KMS HTTP to HTTPS redirect connection" |
| 152 | +
|
| 153 | + - name: Restart the Cosmian VM and test again |
| 154 | + continue-on-error: true |
| 155 | + env: |
| 156 | + CI_INSTANCE: ${{ needs.build-kms-cosmian-vm-image.outputs.ci_instance }} |
| 157 | + run: | |
| 158 | + sudo apt-get install -y jq moreutils |
| 159 | + echo "Rebooting instance..." |
| 160 | + gcloud beta compute instances stop $CI_INSTANCE --zone europe-west4-a --project $GCP_DEV_PROJECT |
| 161 | + gcloud beta compute instances start $CI_INSTANCE --zone europe-west4-a --project $GCP_DEV_PROJECT |
| 162 | + IP_ADDR=$(gcloud beta compute instances describe $CI_INSTANCE --format='get(networkInterfaces[0].accessConfigs[0].natIP)' --zone=europe-west4-a) |
| 163 | + timeout 4m bash -c 'until curl --insecure --output /dev/null --silent --fail https://${IP_ADDR}:5355/ima/ascii; do sleep 3; done' |
| 164 | + echo "[ OK ] Cosmian VM ready after reboot" |
| 165 | + RESET_COUNT=$(cat cosmian_vm.snapshot | jq '.tpm_policy.reset_count') |
| 166 | + NEW_RESET_COUNT=$(expr $RESET_COUNT + 1) |
| 167 | + jq --arg NEW_RESET_COUNT "$NEW_RESET_COUNT" '.tpm_policy.reset_count = $NEW_RESET_COUNT' cosmian_vm.snapshot > new_cosmian_vm.snapshot |
| 168 | + jq '.tpm_policy.reset_count |= tonumber' new_cosmian_vm.snapshot | sponge new_cosmian_vm.snapshot |
| 169 | + ./cosmian_vm --url https://${IP_ADDR}:5355 --allow-insecure-tls verify --snapshot new_cosmian_vm.snapshot |
| 170 | + echo "[ OK ] Integrity after reboot" |
| 171 | + echo "Starting the KMS" |
| 172 | + ./cosmian_vm --url https://${IP_ADDR}:5355 --allow-insecure-tls app restart |
| 173 | + echo "[ OK ] KMS is started" |
| 174 | + echo "Checking Cosmian KMS HTTP connection..." |
| 175 | + curl http://${IP_ADDR}:8080/version |
| 176 | + echo "" |
| 177 | + echo "[ OK ] Cosmian KMS HTTP connection" |
| 178 | + echo "Checking Cosmian KMS HTTPS connection..." |
| 179 | + curl --insecure https://${IP_ADDR}/version |
| 180 | + echo "" |
| 181 | + echo "[ OK ] Cosmian KMS HTTPS connection" |
| 182 | + echo "Checking Cosmian KMS HTTP to HTTPS redirect connection..." |
| 183 | + curl --insecure http://${IP_ADDR}/version |
| 184 | + echo "" |
| 185 | + echo "[ OK ] Cosmian KMS HTTP to HTTPS redirect connection" |
| 186 | +
|
| 187 | + - name: Delete GCP instance |
| 188 | + # if: success() || failure() |
| 189 | + if: success() |
| 190 | + env: |
| 191 | + CI_INSTANCE: ${{ needs.build-kms-cosmian-vm-image.outputs.ci_instance }} |
| 192 | + run: | |
| 193 | + set +e |
| 194 | + gcloud beta compute instances delete $CI_INSTANCE --zone europe-west4-a \ |
| 195 | + --project $GCP_DEV_PROJECT |
| 196 | +
|
| 197 | + release-image: |
| 198 | + name: Release image |
| 199 | + runs-on: ubuntu-22.04 |
| 200 | + needs: [build-kms-cosmian-vm-image, test-image] |
| 201 | + permissions: |
| 202 | + contents: read |
| 203 | + id-token: write |
| 204 | + steps: |
| 205 | + - name: Checkout |
| 206 | + uses: actions/checkout@v4 |
| 207 | + |
| 208 | + - name: GCP auth |
| 209 | + uses: google-github-actions/auth@v1 |
| 210 | + with: |
| 211 | + credentials_json: ${{ secrets.GOOGLE_COSMIAN_DEV_CREDENTIALS }} |
| 212 | + |
| 213 | + - name: Copy image to public project |
| 214 | + if: startsWith(github.ref, 'refs/tags') |
| 215 | + env: |
| 216 | + CI_INSTANCE: ${{ needs.build-kms-cosmian-vm-image.outputs.ci_instance }} |
| 217 | + IMAGE_NAME: ${{ needs.build-kms-cosmian-vm-image.outputs.image_name }} |
| 218 | + run: | |
| 219 | + TAG=${{ github.ref_name }} |
| 220 | + VERSION=$(echo $TAG | sed 's/\./-/g; s/_/-/g; s/+/-/g') |
| 221 | + NEW_IMAGE_NAME=cosmian-vm-kms-$VERSION-sev-${{ inputs.distrib }} |
| 222 | + gcloud beta compute --project=$GCP_DEV_PROJECT images create $NEW_IMAGE_NAME --source-image=$IMAGE_NAME --source-image-project=$GCP_DEV_PROJECT |
| 223 | + gcloud beta compute --project=$GCP_PUBLIC_PROJECT images create $NEW_IMAGE_NAME --source-image=$IMAGE_NAME --source-image-project=$GCP_DEV_PROJECT |
0 commit comments