mirror of
https://github.com/edgelesssys/constellation.git
synced 2025-01-12 16:09:39 -05:00
terraform: Terraform module for GCP (#2553)
This commit is contained in:
parent
b765231175
commit
22d82a59ed
@ -21,4 +21,4 @@ runs:
|
||||
- name: Cleanup Terraform module dir
|
||||
shell: bash
|
||||
run: |
|
||||
rm -r terraform-module
|
||||
rm -r terraform-module terraform-module.zip
|
||||
|
57
.github/workflows/e2e-test-tf-module.yml
vendored
57
.github/workflows/e2e-test-tf-module.yml
vendored
@ -12,12 +12,11 @@ on:
|
||||
type: choice
|
||||
options:
|
||||
- "aws"
|
||||
default: "aws"
|
||||
- "gcp"
|
||||
required: true
|
||||
regionZone:
|
||||
description: "Region or zone to create the cluster in. Leave empty for default region/zone."
|
||||
type: string
|
||||
required: false
|
||||
image:
|
||||
description: "Node image version of the cluster."
|
||||
type: string
|
||||
@ -36,7 +35,7 @@ on:
|
||||
cloudProvider:
|
||||
description: "Which cloud provider to use."
|
||||
type: string
|
||||
default: "aws"
|
||||
required: true
|
||||
regionZone:
|
||||
description: "Which zone to use."
|
||||
type: string
|
||||
@ -82,7 +81,7 @@ jobs:
|
||||
last_three="${run_id: -3}"
|
||||
echo "prefix=e2e-${last_three}-${{ github.run_attempt }}" | tee -a "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Create Terraform variable input file
|
||||
- name: Create AWS Terraform variable input file
|
||||
if: inputs.cloudProvider == 'aws'
|
||||
working-directory: ./terraform-module/aws-constellation
|
||||
run: |
|
||||
@ -112,6 +111,37 @@ jobs:
|
||||
EOF
|
||||
cat terraform.tfvars
|
||||
|
||||
- name: Create GCP Terraform variable input file
|
||||
if: inputs.cloudProvider == 'gcp'
|
||||
working-directory: ./terraform-module/gcp-constellation
|
||||
run: |
|
||||
cat > terraform.tfvars <<EOF
|
||||
name = "${{ steps.create-prefix.outputs.prefix }}"
|
||||
project = "${{ secrets.GCP_E2E_PROJECT }}"
|
||||
service_account_id = "${{ steps.create-prefix.outputs.prefix }}-sa"
|
||||
image = "${{ inputs.image }}"
|
||||
zone = "${{ inputs.regionZone || 'europe-west3-b' }}"
|
||||
node_groups = {
|
||||
control_plane_default = {
|
||||
role = "control-plane"
|
||||
zone = "${{ inputs.regionZone || 'europe-west3-b' }}"
|
||||
instance_type = "n2d-standard-4"
|
||||
disk_size = 30
|
||||
disk_type = "pd-ssd"
|
||||
initial_count = 2
|
||||
},
|
||||
worker_default = {
|
||||
role = "worker"
|
||||
zone = "${{ inputs.regionZone || 'europe-west3-b' }}"
|
||||
instance_type = "n2d-standard-4"
|
||||
disk_size = 30
|
||||
disk_type = "pd-ssd"
|
||||
initial_count = 2
|
||||
}
|
||||
}
|
||||
EOF
|
||||
cat terraform.tfvars
|
||||
|
||||
- name: Install dependencies (Terraform)
|
||||
run: |
|
||||
sudo apt update && sudo apt install gpg
|
||||
@ -121,12 +151,6 @@ jobs:
|
||||
sudo apt update
|
||||
sudo apt install terraform=1.4.4-*
|
||||
|
||||
- name: Setup bazel
|
||||
uses: ./.github/actions/setup_bazel_nix
|
||||
with:
|
||||
useCache: "true"
|
||||
buildBuddyApiKey: ${{ secrets.BUILDBUDDY_ORG_API_KEY }}
|
||||
|
||||
- name: Log in to the Container registry
|
||||
uses: ./.github/actions/container_registry_login
|
||||
with:
|
||||
@ -134,6 +158,13 @@ jobs:
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Setup bazel
|
||||
if: inputs.cliVersion == ''
|
||||
uses: ./.github/actions/setup_bazel_nix
|
||||
with:
|
||||
useCache: "true"
|
||||
buildBuddyApiKey: ${{ secrets.BUILDBUDDY_ORG_API_KEY }}
|
||||
|
||||
- name: Build CLI
|
||||
if: inputs.cliVersion == ''
|
||||
uses: ./.github/actions/build_cli
|
||||
@ -160,6 +191,12 @@ jobs:
|
||||
# extend token expiry to 6 hours to ensure constellation can terminate
|
||||
role-duration-seconds: 21600
|
||||
|
||||
- name: Login to GCP (IAM + Cluster service account)
|
||||
if: inputs.cloudProvider == 'gcp'
|
||||
uses: ./.github/actions/login_gcp
|
||||
with:
|
||||
service_account: "constellation-e2e-tf@constellation-331613.iam.gserviceaccount.com"
|
||||
|
||||
- name: Apply Terraform Cluster
|
||||
id: apply_terraform
|
||||
working-directory: ./terraform-module/${{ inputs.cloudProvider }}-constellation
|
||||
|
15
.github/workflows/e2e-test-weekly.yml
vendored
15
.github/workflows/e2e-test-weekly.yml
vendored
@ -371,6 +371,17 @@ jobs:
|
||||
|
||||
e2e-tf-module:
|
||||
name: Test Terraform Module
|
||||
strategy:
|
||||
fail-fast: false
|
||||
max-parallel: 5
|
||||
matrix:
|
||||
include:
|
||||
- test: "GCP"
|
||||
provider: "gcp"
|
||||
regionZone: "europe-west2-a"
|
||||
- test: "AWS"
|
||||
provider: "aws"
|
||||
regionZone: "us-east-2c"
|
||||
permissions:
|
||||
id-token: write
|
||||
contents: read
|
||||
@ -379,6 +390,6 @@ jobs:
|
||||
secrets: inherit
|
||||
uses: ./.github/workflows/e2e-test-tf-module.yml
|
||||
with:
|
||||
cloudProvider: "aws"
|
||||
regionZone: "eu-west-1b"
|
||||
cloudProvider: "${{ matrix.provider }}"
|
||||
regionZone: "${{ matrix.regionZone }}"
|
||||
image: ${{ needs.find-latest-image.outputs.image-main-nightly }}
|
||||
|
25
.github/workflows/release-cli.yml
vendored
25
.github/workflows/release-cli.yml
vendored
@ -76,6 +76,9 @@ jobs:
|
||||
with:
|
||||
ref: ${{ inputs.ref || github.head_ref }}
|
||||
|
||||
- name: Upload Terraform module
|
||||
uses: ./.github/actions/upload_terraform_module
|
||||
|
||||
- name: Setup bazel
|
||||
uses: ./.github/actions/setup_bazel_nix
|
||||
with:
|
||||
@ -178,6 +181,11 @@ jobs:
|
||||
with:
|
||||
name: constellation.spdx.sbom
|
||||
|
||||
- name: Download Terraform module
|
||||
uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2
|
||||
with:
|
||||
name: terraform-module
|
||||
|
||||
- name: Generate provenance subjects
|
||||
id: provenance-subjects
|
||||
run: |
|
||||
@ -187,7 +195,8 @@ jobs:
|
||||
constellation-linux-amd64 \
|
||||
constellation-linux-arm64 \
|
||||
constellation-windows-amd64.exe \
|
||||
constellation.spdx.sbom)
|
||||
constellation.spdx.sbom \
|
||||
terraform-module.zip)
|
||||
HASHESB64=$(echo "${HASHES}" | base64 -w0)
|
||||
echo "${HASHES}"
|
||||
echo "${HASHESB64}"
|
||||
@ -300,6 +309,11 @@ jobs:
|
||||
with:
|
||||
name: constellation.spdx.sbom
|
||||
|
||||
- name: Download Terraform module
|
||||
uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2
|
||||
with:
|
||||
name: terraform-module
|
||||
|
||||
- name: Download provenance
|
||||
uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2
|
||||
with:
|
||||
@ -330,6 +344,9 @@ jobs:
|
||||
slsa-verifier verify-artifact constellation.spdx.sbom \
|
||||
--provenance-path ${{ needs.provenance.outputs.provenance-name }} \
|
||||
--source-uri github.com/edgelesssys/constellation
|
||||
slsa-verifier verify-artifact terraform-module.zip \
|
||||
--provenance-path ${{ needs.provenance.outputs.provenance-name }} \
|
||||
--source-uri github.com/edgelesssys/constellation
|
||||
|
||||
release:
|
||||
permissions:
|
||||
@ -385,6 +402,11 @@ jobs:
|
||||
with:
|
||||
name: ${{ needs.provenance.outputs.provenance-name }}
|
||||
|
||||
- name: Download Terraform module
|
||||
uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2
|
||||
with:
|
||||
name: terraform-module
|
||||
|
||||
- name: Rename provenance file
|
||||
run: |
|
||||
mv ${{ needs.provenance.outputs.provenance-name }} constellation.intoto.jsonl
|
||||
@ -402,3 +424,4 @@ jobs:
|
||||
constellation.spdx.sbom
|
||||
constellation.spdx.sbom.sig
|
||||
constellation.intoto.jsonl
|
||||
terraform-module.zip
|
||||
|
@ -1,28 +0,0 @@
|
||||
locals {
|
||||
|
||||
image_ref = startswith(var.image, "v") ? "ref/-/stream/stable/${var.image}" : var.image
|
||||
fetch_ami_command = <<EOT
|
||||
curl -s https://cdn.confidential.cloud/constellation/v2/${local.image_ref}/image/info.json | \
|
||||
./yq eval '.list[] | select(.csp == "aws" and .attestationVariant == "${var.attestation_variant}" and .region == "${var.region}") | .reference' - | tr -d '\n' > "${path.module}/ami.txt"
|
||||
echo -n "AMI: "
|
||||
cat "${path.module}/ami.txt"
|
||||
EOT
|
||||
}
|
||||
|
||||
resource "null_resource" "fetch_ami" {
|
||||
provisioner "local-exec" {
|
||||
command = local.fetch_ami_command
|
||||
|
||||
environment = {
|
||||
attestation_variant = var.attestation_variant
|
||||
}
|
||||
}
|
||||
triggers = {
|
||||
always_run = "${timestamp()}"
|
||||
}
|
||||
}
|
||||
|
||||
data "local_file" "ami" {
|
||||
filename = "${path.module}/ami.txt"
|
||||
depends_on = [null_resource.fetch_ami]
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
output "ami" {
|
||||
description = "The fetched AMI."
|
||||
value = data.local_file.ami.content
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
variable "attestation_variant" {
|
||||
description = "The attestation variant to fetch AMI data for."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "region" {
|
||||
description = "The AWS region to fetch AMI data for."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "image" {
|
||||
description = "The image reference or semantical release version to fetch AMI data for."
|
||||
type = string
|
||||
}
|
@ -12,7 +12,7 @@ module "aws_iam" {
|
||||
resource "null_resource" "ensure_yq" {
|
||||
provisioner "local-exec" {
|
||||
command = <<EOT
|
||||
${path.module}/install-yq.sh
|
||||
../constellation-cluster/install-yq.sh
|
||||
EOT
|
||||
}
|
||||
triggers = {
|
||||
@ -20,8 +20,9 @@ resource "null_resource" "ensure_yq" {
|
||||
}
|
||||
}
|
||||
|
||||
module "fetch_ami" {
|
||||
source = "./fetch-ami"
|
||||
module "fetch_image" {
|
||||
source = "../fetch-image"
|
||||
csp = "aws"
|
||||
attestation_variant = var.enable_snp ? "aws-sev-snp" : "aws-nitro-tpm"
|
||||
region = local.region
|
||||
image = var.image
|
||||
@ -35,7 +36,7 @@ module "aws" {
|
||||
node_groups = var.node_groups
|
||||
iam_instance_profile_worker_nodes = module.aws_iam.worker_nodes_instance_profile
|
||||
iam_instance_profile_control_plane = module.aws_iam.control_plane_instance_profile
|
||||
ami = module.fetch_ami.ami
|
||||
ami = module.fetch_image.image
|
||||
region = local.region
|
||||
zone = var.zone
|
||||
debug = var.debug
|
||||
|
@ -9,6 +9,7 @@ locals {
|
||||
"./yq eval '.nodeGroups.${name}.initialCount = ${group.initial_count}' -i constellation-conf.yaml"
|
||||
]
|
||||
]))
|
||||
gcp_sa_file_path = "service_account_file.json"
|
||||
}
|
||||
|
||||
resource "null_resource" "ensure_cli" {
|
||||
@ -34,16 +35,68 @@ resource "terraform_data" "config_generate" {
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
resource "null_resource" "config" {
|
||||
resource "null_resource" "aws_config" {
|
||||
count = var.aws_config != null ? 1 : 0
|
||||
provisioner "local-exec" {
|
||||
command = <<EOT
|
||||
if [ "${var.csp}" = "aws" ]; then
|
||||
./yq eval '.provider.aws.region = "${var.aws_config.region}"' -i constellation-conf.yaml
|
||||
./yq eval '.provider.aws.zone = "${var.aws_config.zone}"' -i constellation-conf.yaml
|
||||
./yq eval '.provider.aws.iamProfileControlPlane = "${var.aws_config.iam_instance_profile_control_plane}"' -i constellation-conf.yaml
|
||||
./yq eval '.provider.aws.iamProfileWorkerNodes = "${var.aws_config.iam_instance_profile_worker_nodes}"' -i constellation-conf.yaml
|
||||
fi
|
||||
EOT
|
||||
}
|
||||
triggers = {
|
||||
always_run = timestamp()
|
||||
}
|
||||
depends_on = [
|
||||
terraform_data.config_generate
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
|
||||
resource "null_resource" "service_account_file" {
|
||||
count = var.gcp_config != null ? 1 : 0
|
||||
provisioner "local-exec" {
|
||||
command = <<EOT
|
||||
echo ${var.gcp_config.serviceAccountKey} | base64 -d > "${local.gcp_sa_file_path}"
|
||||
|
||||
EOT
|
||||
}
|
||||
provisioner "local-exec" {
|
||||
when = destroy
|
||||
command = "rm ${self.triggers.file_path}"
|
||||
}
|
||||
triggers = {
|
||||
always_run = timestamp()
|
||||
file_path = local.gcp_sa_file_path
|
||||
}
|
||||
}
|
||||
|
||||
resource "null_resource" "gcp_config" {
|
||||
count = var.gcp_config != null ? 1 : 0
|
||||
provisioner "local-exec" {
|
||||
command = <<EOT
|
||||
./yq eval '.provider.gcp.project = "${var.gcp_config.project}"' -i constellation-conf.yaml
|
||||
./yq eval '.provider.gcp.region = "${var.gcp_config.region}"' -i constellation-conf.yaml
|
||||
./yq eval '.provider.gcp.zone = "${var.gcp_config.zone}"' -i constellation-conf.yaml
|
||||
./yq eval '.provider.gcp.serviceAccountKeyPath = "${local.gcp_sa_file_path}"' -i constellation-conf.yaml
|
||||
|
||||
./yq eval '.infrastructure.gcp.projectID = "${var.gcp_config.project}"' -i constellation-state.yaml
|
||||
./yq eval '.infrastructure.gcp.ipCidrPod = "${var.gcp_config.ipCidrPod}"' -i constellation-state.yaml
|
||||
EOT
|
||||
}
|
||||
triggers = {
|
||||
always_run = timestamp()
|
||||
}
|
||||
depends_on = [
|
||||
terraform_data.config_generate, null_resource.service_account_file
|
||||
]
|
||||
}
|
||||
|
||||
resource "null_resource" "config" {
|
||||
provisioner "local-exec" {
|
||||
command = <<EOT
|
||||
./yq eval '.name = "${var.name}"' -i constellation-conf.yaml
|
||||
if [ "${var.image}" != "" ]; then
|
||||
./yq eval '.image = "${var.image}"' -i constellation-conf.yaml
|
||||
@ -60,7 +113,7 @@ resource "null_resource" "config" {
|
||||
}
|
||||
|
||||
depends_on = [
|
||||
terraform_data.config_generate
|
||||
null_resource.aws_config, null_resource.gcp_config
|
||||
]
|
||||
|
||||
triggers = {
|
||||
@ -97,7 +150,7 @@ resource "null_resource" "apply" {
|
||||
|
||||
provisioner "local-exec" {
|
||||
when = destroy
|
||||
command = "./constellation terminate --yes && rm constellation-conf.yaml constellation-mastersecret.json ./fetch-ami/ami.txt && rm -r constellation-upgrade"
|
||||
command = "./constellation terminate --yes && rm constellation-conf.yaml constellation-mastersecret.json && rm -r constellation-upgrade"
|
||||
}
|
||||
|
||||
depends_on = [
|
||||
|
@ -1,9 +1,9 @@
|
||||
variable "csp" {
|
||||
type = string
|
||||
description = "The CSP to create the cluster in."
|
||||
description = "The cloud service provider to use."
|
||||
validation {
|
||||
condition = var.csp == "aws"
|
||||
error_message = "The CSP must be 'aws'."
|
||||
condition = var.csp == "aws" || var.csp == "gcp"
|
||||
error_message = "The CSP must be one of {aws|gcp}."
|
||||
}
|
||||
}
|
||||
|
||||
@ -70,9 +70,25 @@ variable "aws_config" {
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "gcp_config" {
|
||||
type = object({
|
||||
region = string
|
||||
zone = string
|
||||
project = string
|
||||
ipCidrPod = string
|
||||
serviceAccountKey = string
|
||||
})
|
||||
description = "The cluster config for GCP."
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "image" {
|
||||
type = string
|
||||
description = "The node image reference or semantical release version."
|
||||
validation {
|
||||
condition = length(var.image) > 0
|
||||
error_message = "The image variable must not be empty."
|
||||
}
|
||||
}
|
||||
|
||||
variable "kubernetes_version" {
|
||||
|
48
terraform/fetch-image/.terraform.lock.hcl
generated
Normal file
48
terraform/fetch-image/.terraform.lock.hcl
generated
Normal file
@ -0,0 +1,48 @@
|
||||
# This file is maintained automatically by "terraform init".
|
||||
# Manual edits may be lost in future updates.
|
||||
|
||||
provider "registry.terraform.io/hashicorp/local" {
|
||||
version = "2.4.0"
|
||||
hashes = [
|
||||
"h1:7RnIbO3CFakblTJs7o0mUiY44dc9xGYsLhSNFSNS1Ds=",
|
||||
"h1:Bs7LAkV/iQTLv72j+cTMrvx2U3KyXrcVHaGbdns1NcE=",
|
||||
"h1:OMqURhlP2IgLEgUCzSlaKXyb/IbnKForgDSjZF/NY4Y=",
|
||||
"h1:R97FTYETo88sT2VHfMgkPU3lzCsZLunPftjSI5vfKe8=",
|
||||
"h1:ZUEYUmm2t4vxwzxy1BvN1wL6SDWrDxfH7pxtzX8c6d0=",
|
||||
"zh:53604cd29cb92538668fe09565c739358dc53ca56f9f11312b9d7de81e48fab9",
|
||||
"zh:66a46e9c508716a1c98efbf793092f03d50049fa4a83cd6b2251e9a06aca2acf",
|
||||
"zh:70a6f6a852dd83768d0778ce9817d81d4b3f073fab8fa570bff92dcb0824f732",
|
||||
"zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3",
|
||||
"zh:82a803f2f484c8b766e2e9c32343e9c89b91997b9f8d2697f9f3837f62926b35",
|
||||
"zh:9708a4e40d6cc4b8afd1352e5186e6e1502f6ae599867c120967aebe9d90ed04",
|
||||
"zh:973f65ce0d67c585f4ec250c1e634c9b22d9c4288b484ee2a871d7fa1e317406",
|
||||
"zh:c8fa0f98f9316e4cfef082aa9b785ba16e36ff754d6aba8b456dab9500e671c6",
|
||||
"zh:cfa5342a5f5188b20db246c73ac823918c189468e1382cb3c48a9c0c08fc5bf7",
|
||||
"zh:e0e2b477c7e899c63b06b38cd8684a893d834d6d0b5e9b033cedc06dd7ffe9e2",
|
||||
"zh:f62d7d05ea1ee566f732505200ab38d94315a4add27947a60afa29860822d3fc",
|
||||
"zh:fa7ce69dde358e172bd719014ad637634bbdabc49363104f4fca759b4b73f2ce",
|
||||
]
|
||||
}
|
||||
|
||||
provider "registry.terraform.io/hashicorp/null" {
|
||||
version = "3.2.1"
|
||||
hashes = [
|
||||
"h1:FbGfc+muBsC17Ohy5g806iuI1hQc4SIexpYCrQHQd8w=",
|
||||
"h1:tSj1mL6OQ8ILGqR2mDu7OYYYWf+hoir0pf9KAQ8IzO8=",
|
||||
"h1:vUW21lLLsKlxtBf0QF7LKJreKxs0CM7YXGzqW1N/ODY=",
|
||||
"h1:wqgRvlyVIbkCeCQs+5jj6zVuQL0KDxZZtNofGqqlSdI=",
|
||||
"h1:ydA0/SNRVB1o95btfshvYsmxA+jZFRZcvKzZSB+4S1M=",
|
||||
"zh:58ed64389620cc7b82f01332e27723856422820cfd302e304b5f6c3436fb9840",
|
||||
"zh:62a5cc82c3b2ddef7ef3a6f2fedb7b9b3deff4ab7b414938b08e51d6e8be87cb",
|
||||
"zh:63cff4de03af983175a7e37e52d4bd89d990be256b16b5c7f919aff5ad485aa5",
|
||||
"zh:74cb22c6700e48486b7cabefa10b33b801dfcab56f1a6ac9b6624531f3d36ea3",
|
||||
"zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3",
|
||||
"zh:79e553aff77f1cfa9012a2218b8238dd672ea5e1b2924775ac9ac24d2a75c238",
|
||||
"zh:a1e06ddda0b5ac48f7e7c7d59e1ab5a4073bbcf876c73c0299e4610ed53859dc",
|
||||
"zh:c37a97090f1a82222925d45d84483b2aa702ef7ab66532af6cbcfb567818b970",
|
||||
"zh:e4453fbebf90c53ca3323a92e7ca0f9961427d2f0ce0d2b65523cc04d5d999c2",
|
||||
"zh:e80a746921946d8b6761e77305b752ad188da60688cfd2059322875d363be5f5",
|
||||
"zh:fbdb892d9822ed0e4cb60f2fedbdbb556e4da0d88d3b942ae963ed6ff091e48f",
|
||||
"zh:fca01a623d90d0cad0843102f9b8b9fe0d3ff8244593bd817f126582b52dd694",
|
||||
]
|
||||
}
|
31
terraform/fetch-image/main.tf
Normal file
31
terraform/fetch-image/main.tf
Normal file
@ -0,0 +1,31 @@
|
||||
locals {
|
||||
image_ref = startswith(var.image, "v") ? "ref/-/stream/stable/${var.image}" : var.image
|
||||
region_filter = var.region != "" ? " and .region == \"${var.region}\"" : "" # apply region filter only if region field exists for the CSP
|
||||
|
||||
fetch_image_command = <<EOT
|
||||
curl -s https://cdn.confidential.cloud/constellation/v2/${local.image_ref}/image/info.json | \
|
||||
./yq eval '.list[] | select(.csp == "${var.csp}" and .attestationVariant == "${var.attestation_variant}"${local.region_filter}) | .reference' - | tr -d '\n' > "image.txt"
|
||||
EOT
|
||||
}
|
||||
|
||||
resource "null_resource" "fetch_image" {
|
||||
provisioner "local-exec" {
|
||||
command = local.fetch_image_command
|
||||
|
||||
environment = {
|
||||
attestation_variant = var.attestation_variant
|
||||
}
|
||||
}
|
||||
provisioner "local-exec" {
|
||||
when = destroy
|
||||
command = "rm image.txt"
|
||||
}
|
||||
triggers = {
|
||||
always_run = "${timestamp()}"
|
||||
}
|
||||
}
|
||||
|
||||
data "local_file" "image" {
|
||||
filename = "image.txt"
|
||||
depends_on = [null_resource.fetch_image]
|
||||
}
|
4
terraform/fetch-image/output.tf
Normal file
4
terraform/fetch-image/output.tf
Normal file
@ -0,0 +1,4 @@
|
||||
output "image" {
|
||||
description = "The resolved image ID of the CSP."
|
||||
value = data.local_file.image.content
|
||||
}
|
20
terraform/fetch-image/variables.tf
Normal file
20
terraform/fetch-image/variables.tf
Normal file
@ -0,0 +1,20 @@
|
||||
variable "csp" {
|
||||
description = "The cloud service provider to fetch image data for."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "attestation_variant" {
|
||||
description = "The attestation variant to fetch image data for."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "region" {
|
||||
description = "The region to fetch image data for."
|
||||
type = string
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "image" {
|
||||
description = "The image reference or semantical release version to fetch image data for."
|
||||
type = string
|
||||
}
|
120
terraform/gcp-constellation/.terraform.lock.hcl
generated
Normal file
120
terraform/gcp-constellation/.terraform.lock.hcl
generated
Normal file
@ -0,0 +1,120 @@
|
||||
# This file is maintained automatically by "terraform init".
|
||||
# Manual edits may be lost in future updates.
|
||||
|
||||
provider "registry.terraform.io/hashicorp/google" {
|
||||
version = "4.83.0"
|
||||
constraints = "4.83.0"
|
||||
hashes = [
|
||||
"h1:BOrMAGh1FwA290rqwOHJKdfYOhOyqcKiqunZ6K/qA6k=",
|
||||
"h1:cWBKJt7QJ+MKerSq73qFICJkIsxHn1JepalZzR/eRk4=",
|
||||
"h1:lvCQfxljF0bY15qI78bxl9d1pW6o60WcyNp9ZQcx3DU=",
|
||||
"h1:nyeDdFmfYBFj3+Ng6IwfdSgo+D4fsCAbbTPmwPidQC8=",
|
||||
"h1:x9rGt85+aTXPVhTtNJ4bdV5Wy3uJDJbVg+D0e0h/uiY=",
|
||||
"zh:0310360982c3d42449ef103fab0819770aa96c7813507778d71ed016942bed96",
|
||||
"zh:0d0f82ce5e54267641b1f1d494a3ad1ddd41a7553910dd33abd6a114feab6881",
|
||||
"zh:0eda79e53a1833e8692273f5d7224344200e49303e579aec7b53762f50f39210",
|
||||
"zh:3c0cf4abaf461238563132ab4564965bc6bd571eb3bbeedac89258a9a688b169",
|
||||
"zh:61d619e5163daeeb7909443cc0c67816939a1748aec2fe544ab3f380270aae92",
|
||||
"zh:66d9da66aec8575ee16b70b42a5ae082b2f43f4a84a844363a585806ac75cca0",
|
||||
"zh:875c5596f365130095ccc2150755b6fb8a6d9fe9af4af9f595029716be02cdef",
|
||||
"zh:a9af92cd6ea160618d6433c92297a4e3f3dc7a2e964516e1e7b51ce70f3ec178",
|
||||
"zh:b9566bd1910462b4d92c6976184c4408e42a3ef6a300962b49866aa0f6f29b11",
|
||||
"zh:bae735a81a04244893fd9e81d9b5d6c321d874cb37a7b5aab8a1c8c5044b362d",
|
||||
"zh:d97ae1676d793696498e0eda8324bc02edbd2fbbcd76eb103a949876ec1fe8c0",
|
||||
"zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c",
|
||||
]
|
||||
}
|
||||
|
||||
provider "registry.terraform.io/hashicorp/google-beta" {
|
||||
version = "4.83.0"
|
||||
constraints = "4.83.0"
|
||||
hashes = [
|
||||
"h1:IX3g+ndU9l8BQ/qU13yDk4vQuTxxUvyhYXBSTXmu1SQ=",
|
||||
"h1:J8MwreN/KrmeOWCVjbCm749EdeD/WnngXRIxPNbIBH4=",
|
||||
"h1:hxulmxS/QJyusZNl53N7bjwhVShQo7JxGuq5Tht08ZE=",
|
||||
"h1:tfTOCk0TCOeGfyeh8HX7MC2aYcsidgRykK9Wfqn1o8k=",
|
||||
"h1:uKmM3fJQyowwBV5qlAl4+qteXbsCEkwmGAwxaci+9cw=",
|
||||
"zh:006d2f02999598109ab0c6737495904e83bb78008defc7590d18d4a997dc7cbf",
|
||||
"zh:04455b025c1a5551187495125dd045d3c11334dcb68cc0c62d82574513f42eab",
|
||||
"zh:0b20f658e322c561bc6364240bc4169971e00efbbba8781b38c18dcf014e0788",
|
||||
"zh:2262b2ceb759427a0ec7fe994dd07fd1ee7c3cae2b1d87ef55aa7f005ffb6c52",
|
||||
"zh:3cf502334354b75334ff5b4285b2afcbef11b91c7cf1e18e16c2b1bb5a77e099",
|
||||
"zh:9469a3356b543894273beb2332cbf8f230cdbe810d5e3d18de3a461a726a20b2",
|
||||
"zh:968914382e310d0b41c012ec6435d796c40f5b95239f68ed8aad24be4dc705d6",
|
||||
"zh:aa70ee3f4dd1f433b965049f58c93c47e2f7f31cfd7848ec88afad71d14f7038",
|
||||
"zh:d2aa8fceb732886c2c80ff17237a6184fb3e7806e0280d4a1ab0e3d4a83b8fa9",
|
||||
"zh:e470be740b1854a157c1ff5d4f12a13548842135f0fddc1eda29571dc7c65327",
|
||||
"zh:e51e894c0bc9d9982de9ae42c1434c5397f77db41bb7e095996a715315018874",
|
||||
"zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c",
|
||||
]
|
||||
}
|
||||
|
||||
provider "registry.terraform.io/hashicorp/local" {
|
||||
version = "2.4.0"
|
||||
hashes = [
|
||||
"h1:7RnIbO3CFakblTJs7o0mUiY44dc9xGYsLhSNFSNS1Ds=",
|
||||
"h1:Bs7LAkV/iQTLv72j+cTMrvx2U3KyXrcVHaGbdns1NcE=",
|
||||
"h1:OMqURhlP2IgLEgUCzSlaKXyb/IbnKForgDSjZF/NY4Y=",
|
||||
"h1:R97FTYETo88sT2VHfMgkPU3lzCsZLunPftjSI5vfKe8=",
|
||||
"h1:ZUEYUmm2t4vxwzxy1BvN1wL6SDWrDxfH7pxtzX8c6d0=",
|
||||
"zh:53604cd29cb92538668fe09565c739358dc53ca56f9f11312b9d7de81e48fab9",
|
||||
"zh:66a46e9c508716a1c98efbf793092f03d50049fa4a83cd6b2251e9a06aca2acf",
|
||||
"zh:70a6f6a852dd83768d0778ce9817d81d4b3f073fab8fa570bff92dcb0824f732",
|
||||
"zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3",
|
||||
"zh:82a803f2f484c8b766e2e9c32343e9c89b91997b9f8d2697f9f3837f62926b35",
|
||||
"zh:9708a4e40d6cc4b8afd1352e5186e6e1502f6ae599867c120967aebe9d90ed04",
|
||||
"zh:973f65ce0d67c585f4ec250c1e634c9b22d9c4288b484ee2a871d7fa1e317406",
|
||||
"zh:c8fa0f98f9316e4cfef082aa9b785ba16e36ff754d6aba8b456dab9500e671c6",
|
||||
"zh:cfa5342a5f5188b20db246c73ac823918c189468e1382cb3c48a9c0c08fc5bf7",
|
||||
"zh:e0e2b477c7e899c63b06b38cd8684a893d834d6d0b5e9b033cedc06dd7ffe9e2",
|
||||
"zh:f62d7d05ea1ee566f732505200ab38d94315a4add27947a60afa29860822d3fc",
|
||||
"zh:fa7ce69dde358e172bd719014ad637634bbdabc49363104f4fca759b4b73f2ce",
|
||||
]
|
||||
}
|
||||
|
||||
provider "registry.terraform.io/hashicorp/null" {
|
||||
version = "3.2.1"
|
||||
hashes = [
|
||||
"h1:FbGfc+muBsC17Ohy5g806iuI1hQc4SIexpYCrQHQd8w=",
|
||||
"h1:tSj1mL6OQ8ILGqR2mDu7OYYYWf+hoir0pf9KAQ8IzO8=",
|
||||
"h1:vUW21lLLsKlxtBf0QF7LKJreKxs0CM7YXGzqW1N/ODY=",
|
||||
"h1:wqgRvlyVIbkCeCQs+5jj6zVuQL0KDxZZtNofGqqlSdI=",
|
||||
"h1:ydA0/SNRVB1o95btfshvYsmxA+jZFRZcvKzZSB+4S1M=",
|
||||
"zh:58ed64389620cc7b82f01332e27723856422820cfd302e304b5f6c3436fb9840",
|
||||
"zh:62a5cc82c3b2ddef7ef3a6f2fedb7b9b3deff4ab7b414938b08e51d6e8be87cb",
|
||||
"zh:63cff4de03af983175a7e37e52d4bd89d990be256b16b5c7f919aff5ad485aa5",
|
||||
"zh:74cb22c6700e48486b7cabefa10b33b801dfcab56f1a6ac9b6624531f3d36ea3",
|
||||
"zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3",
|
||||
"zh:79e553aff77f1cfa9012a2218b8238dd672ea5e1b2924775ac9ac24d2a75c238",
|
||||
"zh:a1e06ddda0b5ac48f7e7c7d59e1ab5a4073bbcf876c73c0299e4610ed53859dc",
|
||||
"zh:c37a97090f1a82222925d45d84483b2aa702ef7ab66532af6cbcfb567818b970",
|
||||
"zh:e4453fbebf90c53ca3323a92e7ca0f9961427d2f0ce0d2b65523cc04d5d999c2",
|
||||
"zh:e80a746921946d8b6761e77305b752ad188da60688cfd2059322875d363be5f5",
|
||||
"zh:fbdb892d9822ed0e4cb60f2fedbdbb556e4da0d88d3b942ae963ed6ff091e48f",
|
||||
"zh:fca01a623d90d0cad0843102f9b8b9fe0d3ff8244593bd817f126582b52dd694",
|
||||
]
|
||||
}
|
||||
|
||||
provider "registry.terraform.io/hashicorp/random" {
|
||||
version = "3.5.1"
|
||||
constraints = "3.5.1"
|
||||
hashes = [
|
||||
"h1:3hjTP5tQBspPcFAJlfafnWrNrKnr7J4Cp0qB9jbqf30=",
|
||||
"h1:6FVyQ/aG6tawPam6B+oFjgdidKd83uG9n7dOSQ66HBA=",
|
||||
"h1:IL9mSatmwov+e0+++YX2V6uel+dV6bn+fC/cnGDK3Ck=",
|
||||
"h1:VSnd9ZIPyfKHOObuQCaKfnjIHRtR7qTw19Rz8tJxm+k=",
|
||||
"h1:sZ7MTSD4FLekNN2wSNFGpM+5slfvpm5A/NLVZiB7CO0=",
|
||||
"zh:04e3fbd610cb52c1017d282531364b9c53ef72b6bc533acb2a90671957324a64",
|
||||
"zh:119197103301ebaf7efb91df8f0b6e0dd31e6ff943d231af35ee1831c599188d",
|
||||
"zh:4d2b219d09abf3b1bb4df93d399ed156cadd61f44ad3baf5cf2954df2fba0831",
|
||||
"zh:6130bdde527587bbe2dcaa7150363e96dbc5250ea20154176d82bc69df5d4ce3",
|
||||
"zh:6cc326cd4000f724d3086ee05587e7710f032f94fc9af35e96a386a1c6f2214f",
|
||||
"zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3",
|
||||
"zh:b6d88e1d28cf2dfa24e9fdcc3efc77adcdc1c3c3b5c7ce503a423efbdd6de57b",
|
||||
"zh:ba74c592622ecbcef9dc2a4d81ed321c4e44cddf7da799faa324da9bf52a22b2",
|
||||
"zh:c7c5cde98fe4ef1143bd1b3ec5dc04baf0d4cc3ca2c5c7d40d17c0e9b2076865",
|
||||
"zh:dac4bad52c940cd0dfc27893507c1e92393846b024c5a9db159a93c534a3da03",
|
||||
"zh:de8febe2a2acd9ac454b844a4106ed295ae9520ef54dc8ed2faf29f12716b602",
|
||||
"zh:eab0d0495e7e711cca367f7d4df6e322e6c562fc52151ec931176115b83ed014",
|
||||
]
|
||||
}
|
68
terraform/gcp-constellation/main.tf
Normal file
68
terraform/gcp-constellation/main.tf
Normal file
@ -0,0 +1,68 @@
|
||||
locals {
|
||||
region = substr(var.zone, 0, length(var.zone) - 2)
|
||||
}
|
||||
|
||||
module "gcp_iam" {
|
||||
source = "../infrastructure/iam/gcp"
|
||||
project_id = var.project
|
||||
service_account_id = var.service_account_id
|
||||
region = local.region
|
||||
zone = var.zone
|
||||
}
|
||||
|
||||
|
||||
resource "null_resource" "ensure_yq" {
|
||||
provisioner "local-exec" {
|
||||
command = <<EOT
|
||||
../constellation-cluster/install-yq.sh
|
||||
EOT
|
||||
}
|
||||
triggers = {
|
||||
always_run = timestamp()
|
||||
}
|
||||
}
|
||||
|
||||
module "fetch_image" {
|
||||
source = "../fetch-image"
|
||||
csp = "gcp"
|
||||
attestation_variant = "gcp-sev-es"
|
||||
image = var.image
|
||||
depends_on = [null_resource.ensure_yq]
|
||||
}
|
||||
|
||||
|
||||
module "gcp" {
|
||||
source = "../infrastructure/gcp"
|
||||
project = var.project
|
||||
image_id = module.fetch_image.image
|
||||
name = var.name
|
||||
node_groups = var.node_groups
|
||||
region = local.region
|
||||
zone = var.zone
|
||||
debug = var.debug
|
||||
custom_endpoint = var.custom_endpoint
|
||||
}
|
||||
|
||||
module "constellation" {
|
||||
source = "../constellation-cluster"
|
||||
csp = "gcp"
|
||||
name = var.name
|
||||
image = var.image
|
||||
microservice_version = var.microservice_version
|
||||
kubernetes_version = var.kubernetes_version
|
||||
uid = module.gcp.uid
|
||||
clusterEndpoint = module.gcp.out_of_cluster_endpoint
|
||||
inClusterEndpoint = module.gcp.in_cluster_endpoint
|
||||
initSecretHash = module.gcp.initSecret
|
||||
ipCidrNode = module.gcp.ip_cidr_nodes
|
||||
apiServerCertSANs = module.gcp.api_server_cert_sans
|
||||
node_groups = var.node_groups
|
||||
gcp_config = {
|
||||
region = local.region
|
||||
zone = var.zone
|
||||
project = var.project
|
||||
ipCidrPod = module.gcp.ip_cidr_pods
|
||||
serviceAccountKey = module.gcp_iam.sa_key
|
||||
}
|
||||
depends_on = [module.gcp, null_resource.ensure_yq]
|
||||
}
|
71
terraform/gcp-constellation/variables.tf
Normal file
71
terraform/gcp-constellation/variables.tf
Normal file
@ -0,0 +1,71 @@
|
||||
variable "name" {
|
||||
type = string
|
||||
description = "Name of the Constellation cluster."
|
||||
}
|
||||
|
||||
variable "project" {
|
||||
type = string
|
||||
description = "The project ID to deploy the cluster to."
|
||||
}
|
||||
|
||||
variable "service_account_id" {
|
||||
type = string
|
||||
description = "The service account ID to use for the cluster."
|
||||
}
|
||||
|
||||
variable "image" {
|
||||
type = string
|
||||
description = "Node image reference or semantical release version."
|
||||
} # is required resolve the AMI
|
||||
|
||||
variable "microservice_version" {
|
||||
type = string
|
||||
description = "Microservice version. When not set, the latest default version will be used."
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "kubernetes_version" {
|
||||
type = string
|
||||
description = "Kubernetes version. When not set, the latest default version will be used."
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "node_groups" {
|
||||
type = map(object({
|
||||
role = string
|
||||
initial_count = optional(number)
|
||||
instance_type = string
|
||||
disk_size = number
|
||||
disk_type = string
|
||||
zone = string
|
||||
}))
|
||||
description = "A map of node group names to node group configurations."
|
||||
validation {
|
||||
condition = can([for group in var.node_groups : group.role == "control-plane" || group.role == "worker"])
|
||||
error_message = "The role has to be 'control-plane' or 'worker'."
|
||||
}
|
||||
}
|
||||
|
||||
variable "zone" {
|
||||
type = string
|
||||
description = "The availability zone name to create the cluster in."
|
||||
}
|
||||
|
||||
variable "debug" {
|
||||
type = bool
|
||||
default = false
|
||||
description = "DON'T USE IN PRODUCTION: Enable debug mode and allow the use of debug images."
|
||||
}
|
||||
|
||||
|
||||
variable "custom_endpoint" {
|
||||
type = string
|
||||
default = ""
|
||||
description = "Custom endpoint (DNS Name) to use for the Constellation API server. If not set, the default endpoint will be used."
|
||||
}
|
||||
|
||||
variable "internal_load_balancer" {
|
||||
type = bool
|
||||
default = false
|
||||
description = "Use an internal load balancer."
|
||||
}
|
Loading…
Reference in New Issue
Block a user