constellation/.github/actions/constellation_create/action.yml
Moritz Sanft c15e4efef6
terraform: Azure Marketplace image support (#2651)
* terraform: add Azure marketplace variable

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* config: add Azure marketplace variable

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* cli: use Terraform variables from config

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* terraform: pass down marketplace variable

* image: pad Azure images to 1GiB

* terraform: add version attribute to marketplace image

* semver: allow versions to be exported without prefix

* cli: boolean var to use marketplace images

* config: remove dive key

* dev-docs: add instructions on how to use marketplace images

* terraform: fix unit test

* terraform: only fetch image for non-marketplace images

* mpimage: refactor image selection

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* [remove] increase minor version for image build

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* terraform: ignore changes to source_image_reference on upgrade

* operator: add support for parsing Azure marketplace images

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* upgrade: fix imagefetcher call

* docs: add info about azure marketplace

* image: ensure more than 1GiB in size

* image: test to pad to 2GiB

* version: change back to v2.14.0-pre

* image: GPT-conformant image size padding

* [remove] increase version

* mpimage: inline prefix func

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* ci: add marketplace image e2e test

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* [remove] register workflow

* ci: fix workflow name

* ci: only allow azure test

* cli: add marketplace image input to interface

* cli: fix argument passing

* version: roll back to v2.14.0

* ci: add force-flag support

* Update docs/docs/overview/license.md

* Update dev-docs/workflows/marketplace-images.md

Co-authored-by: Moritz Eckert <m1gh7ym0@gmail.com>

---------

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>
Co-authored-by: Moritz Eckert <m1gh7ym0@gmail.com>
Co-authored-by: Thomas Tendyck <51411342+thomasten@users.noreply.github.com>
2023-12-08 14:40:31 +01:00

255 lines
9.0 KiB
YAML

name: Constellation create
description: Create a new Constellation cluster using the latest OS image.
inputs:
workerNodesCount:
description: "Number of worker nodes to spawn."
required: true
controlNodesCount:
description: "Number of control-plane nodes to spawn."
required: true
cloudProvider:
description: "Either 'gcp', 'aws' or 'azure'."
required: true
machineType:
description: "Machine type of VM to spawn."
required: false
cliVersion:
description: "Version of the CLI"
required: true
osImage:
description: "OS image to use."
required: true
isDebugImage:
description: "Is OS img a debug img?"
required: true
kubernetesVersion:
description: "Kubernetes version to create the cluster from."
required: false
artifactNameSuffix:
description: "Suffix for artifact naming."
required: true
fetchMeasurements:
default: "false"
description: "Update measurements via the 'constellation config fetch-measurements' command."
azureSNPEnforcementPolicy:
required: false
description: "Azure SNP enforcement policy."
test:
description: "The e2e test payload."
required: true
azureClusterCreateCredentials:
description: "Azure credentials authorized to create a Constellation cluster."
required: true
azureIAMCreateCredentials:
description: "Azure credentials authorized to create an IAM configuration."
required: true
refStream:
description: "Reference and stream of the image in use"
required: false
internalLoadBalancer:
description: "Whether to use an internal load balancer for the control plane"
required: false
selfManagedInfra:
description: "Use self-managed infrastructure instead of infrastructure created by the Constellation CLI."
required: true
marketplaceImageVersion:
description: "Marketplace OS image version. Used instead of osImage."
required: false
force:
description: "Set the force-flag on apply to ignore version mismatches."
required: false
outputs:
kubeconfig:
description: "The kubeconfig for the cluster."
value: ${{ steps.constellation-init.outputs.KUBECONFIG }}
osImageUsed:
description: "The OS image used in the cluster."
value: ${{ steps.setImage.outputs.image }}
runs:
using: "composite"
steps:
- name: Set constellation name
shell: bash
run: |
yq eval -i "(.name) = \"e2e-test\"" constellation-conf.yaml
- name: Set Azure SNP enforcement policy
if: inputs.azureSNPEnforcementPolicy != ''
shell: bash
run: |
if [[ ${{ inputs.cloudProvider }} != 'azure' ]]; then
echo "SNP enforcement policy is only supported for Azure"
exit 1
fi
yq eval -i "(.attestation.azureSEVSNP.firmwareSignerConfig.enforcementPolicy) \
= \"${{ inputs.azureSNPEnforcementPolicy }}\"" constellation-conf.yaml
- name: Set image
id: setImage
shell: bash
env:
imageInput: ${{ inputs.osImage }}
run: |
if [[ -z "${imageInput}" ]]; then
echo "No image specified. Using default image from config."
image=$(yq eval ".image" constellation-conf.yaml)
echo "image=${image}" | tee -a "$GITHUB_OUTPUT"
exit 0
fi
yq eval -i "(.image) = \"${imageInput}\"" constellation-conf.yaml
echo "image=${imageInput}" | tee -a "$GITHUB_OUTPUT"
- name: Set marketplace image flag (Azure)
if: inputs.marketplaceImageVersion != '' && inputs.cloudProvider == 'azure'
shell: bash
run: |
yq eval -i "(.provider.azure.useMarketplaceImage) = true" constellation-conf.yaml
yq eval -i "(.image) = \"${{ inputs.marketplaceImageVersion }}\"" constellation-conf.yaml
- name: Update measurements for non-stable images
if: inputs.fetchMeasurements
shell: bash
run: |
constellation config fetch-measurements --debug --insecure
- name: Set instanceType
if: inputs.machineType && inputs.machineType != 'default'
shell: bash
run: |
yq eval -i "(.nodeGroups[] | .instanceType) = \"${{ inputs.machineType }}\"" constellation-conf.yaml
- name: Set node count
shell: bash
run: |
yq eval -i "(.nodeGroups[] | select(.role == \"control-plane\") | .initialCount) = ${{ inputs.controlNodesCount }}" constellation-conf.yaml
yq eval -i "(.nodeGroups[] | select(.role == \"worker\") | .initialCount) = ${{ inputs.workerNodesCount }}" constellation-conf.yaml
- name: Enable debugCluster flag
if: inputs.isDebugImage == 'true'
shell: bash
run: |
yq eval -i '(.debugCluster) = true' constellation-conf.yaml
- name: Enable internalLoadBalancer flag
if: inputs.internalLoadBalancer == 'true'
shell: bash
run: |
yq eval -i '(.internalLoadBalancer) = true' constellation-conf.yaml
- name: Show Cluster Configuration
shell: bash
run: |
echo "Creating cluster using config:"
cat constellation-conf.yaml
sudo sh -c 'echo "127.0.0.1 license.confidential.cloud" >> /etc/hosts' || true
- name: Constellation create (CLI)
if : inputs.selfManagedInfra != 'true'
shell: bash
run: |
# TODO(v2.14): Remove workaround for CLIs not supporting apply command
cmd='apply --skip-phases=init,attestationconfig,certsans,helm,image,k8s'
if constellation --help | grep -q create; then
cmd=create
fi
constellation $cmd -y --debug --tf-log=DEBUG
- name: Constellation create (self-managed)
if : inputs.selfManagedInfra == 'true'
uses: ./.github/actions/self_managed_create
with:
cloudProvider: ${{ inputs.cloudProvider }}
- name: Cdbg deploy
if: inputs.isDebugImage == 'true'
uses: ./.github/actions/cdbg_deploy
with:
cloudProvider: ${{ inputs.cloudProvider }}
test: ${{ inputs.test }}
azureClusterCreateCredentials: ${{ inputs.azureClusterCreateCredentials }}
azureIAMCreateCredentials: ${{ inputs.azureIAMCreateCredentials }}
refStream: ${{ inputs.refStream }}
kubernetesVersion: ${{ inputs.kubernetesVersion }}
selfManagedInfra: ${{ inputs.selfManagedInfra }}
- name: Set force flag
id: set-force-flag
if: inputs.force == 'true'
shell: bash
run: |
echo "flag=--force" | tee -a $GITHUB_OUTPUT
- name: Constellation init
id: constellation-init
shell: bash
run: |
constellation apply --skip-phases=infrastructure --debug ${{ steps.set-force-flag.outputs.flag }}
echo "KUBECONFIG=$(pwd)/constellation-admin.conf" | tee -a $GITHUB_OUTPUT
- name: Wait for nodes to join and become ready
shell: bash
env:
KUBECONFIG: "${{ steps.constellation-init.outputs.KUBECONFIG }}"
JOINTIMEOUT: "1200" # 20 minutes timeout for all nodes to join
run: |
echo "::group::Wait for nodes"
NODES_COUNT=$((${{ inputs.controlNodesCount }} + ${{ inputs.workerNodesCount }}))
JOINWAIT=0
until [[ "$(kubectl get nodes -o json | jq '.items | length')" == "${NODES_COUNT}" ]] || [[ $JOINWAIT -gt $JOINTIMEOUT ]];
do
echo "$(kubectl get nodes -o json | jq '.items | length')/"${NODES_COUNT}" nodes have joined.. waiting.."
JOINWAIT=$((JOINWAIT+30))
sleep 30
done
if [[ $JOINWAIT -gt $JOINTIMEOUT ]]; then
echo "Timed out waiting for nodes to join"
exit 1
fi
echo "$(kubectl get nodes -o json | jq '.items | length')/"${NODES_COUNT}" nodes have joined"
if ! kubectl wait --for=condition=ready --all nodes --timeout=20m; then
kubectl get pods -n kube-system
kubectl get events -n kube-system
echo "::error::kubectl wait timed out before all nodes became ready"
echo "::endgroup::"
exit 1
fi
echo "::endgroup::"
- name: Download boot logs
if: always()
continue-on-error: true
shell: bash
env:
CSP: ${{ inputs.cloudProvider }}
run: |
echo "::group::Download boot logs"
CONSTELL_UID=$(yq '.infrastructure.uid' constellation-state.yaml)
case $CSP in
azure)
AZURE_RESOURCE_GROUP=$(yq eval ".provider.azure.resourceGroup" constellation-conf.yaml)
./.github/actions/constellation_create/az-logs.sh ${AZURE_RESOURCE_GROUP}
;;
gcp)
GCP_ZONE=$(yq eval ".provider.gcp.zone" constellation-conf.yaml)
./.github/actions/constellation_create/gcp-logs.sh ${GCP_ZONE} ${CONSTELL_UID}
;;
aws)
./.github/actions/constellation_create/aws-logs.sh us-east-2 ${CONSTELL_UID}
;;
esac
echo "::endgroup::"
- name: Upload boot logs
if: always() && !env.ACT
continue-on-error: true
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
with:
name: serial-logs-${{ inputs.artifactNameSuffix }}
path: |
*.log
!terraform.log