Skip to content

Commit

Permalink
config: pass VM service account from iam create to cluster create via…
Browse files Browse the repository at this point in the history
… config
  • Loading branch information
3u13r committed Mar 10, 2025
1 parent 73a63b7 commit b1b1b65
Show file tree
Hide file tree
Showing 14 changed files with 75 additions and 49 deletions.
1 change: 1 addition & 0 deletions cli/internal/cloudcmd/tfvars.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ func gcpTerraformVars(conf *config.Config, imageRef string) *terraform.GCPCluste
InternalLoadBalancer: conf.InternalLoadBalancer,
CCTechnology: ccTech,
AdditionalLabels: conf.Tags,
IAMServiceAccountVM: conf.Provider.GCP.IAMServiceAccountVM,
}
}

Expand Down
1 change: 1 addition & 0 deletions cli/internal/cmd/apply_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@ func TestValidateInputs(t *testing.T) {
ClientX509CertURL: "client_cert",
}))
cfg.Provider.GCP.ServiceAccountKeyPath = "saKey.json"
cfg.Provider.GCP.IAMServiceAccountVM = "[email protected]"
}

require.NoError(fh.WriteYAML(constants.ConfigFilename, cfg))
Expand Down
3 changes: 2 additions & 1 deletion cli/internal/cmd/iamcreategcp.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,11 +140,12 @@ func (c *gcpIAMCreator) printOutputValues(cmd *cobra.Command, _ cloudcmd.IAMOutp
cmd.Printf("serviceAccountKeyPath:\t%s\n\n", c.flags.pathPrefixer.PrefixPrintablePath(constants.GCPServiceAccountKeyFilename))
}

func (c *gcpIAMCreator) writeOutputValuesToConfig(conf *config.Config, _ cloudcmd.IAMOutput) {
func (c *gcpIAMCreator) writeOutputValuesToConfig(conf *config.Config, out cloudcmd.IAMOutput) {
conf.Provider.GCP.Project = c.flags.projectID
conf.Provider.GCP.ServiceAccountKeyPath = constants.GCPServiceAccountKeyFilename // File was created in workspace, so only the filename is needed.
conf.Provider.GCP.Region = c.flags.region
conf.Provider.GCP.Zone = c.flags.zone
conf.Provider.GCP.IAMServiceAccountVM = out.GCPOutput.IAMServiceAccountVM
for groupName, group := range conf.NodeGroups {
group.Zone = c.flags.zone
conf.NodeGroups[groupName] = group
Expand Down
1 change: 1 addition & 0 deletions cli/internal/cmd/init_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,7 @@ func defaultConfigWithExpectedMeasurements(t *testing.T, conf *config.Config, cs
conf.Provider.GCP.Project = "test-project"
conf.Provider.GCP.Zone = "test-zone"
conf.Provider.GCP.ServiceAccountKeyPath = "test-key-path"
conf.Provider.GCP.IAMServiceAccountVM = "[email protected]"
conf.Attestation.GCPSEVSNP.Measurements[4] = measurements.WithAllBytes(0x44, measurements.Enforce, measurements.PCRMeasurementLength)
conf.Attestation.GCPSEVSNP.Measurements[9] = measurements.WithAllBytes(0x11, measurements.Enforce, measurements.PCRMeasurementLength)
conf.Attestation.GCPSEVSNP.Measurements[12] = measurements.WithAllBytes(0xcc, measurements.Enforce, measurements.PCRMeasurementLength)
Expand Down
2 changes: 2 additions & 0 deletions cli/internal/terraform/variables.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,8 @@ type GCPClusterVariables struct {
InternalLoadBalancer bool `hcl:"internal_load_balancer" cty:"internal_load_balancer"`
// CCTechnology is the confidential computing technology to use on the VMs. (`SEV` or `SEV_SNP`)
CCTechnology string `hcl:"cc_technology" cty:"cc_technology"`
// IAMServiceAccountControlPlane is the IAM service account mail address to attach to VMs.
IAMServiceAccountVM string `hcl:"iam_service_account_vm" cty:"iam_service_account_vm"`
// AdditionalLables are (optional) additional labels that should be applied to created resources.
AdditionalLabels cloudprovider.Tags `hcl:"additional_labels" cty:"additional_labels"`
}
Expand Down
14 changes: 8 additions & 6 deletions cli/internal/terraform/variables_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,9 @@ func TestGCPClusterVariables(t *testing.T) {
DiskType: "pd-ssd",
},
},
CustomEndpoint: "example.com",
CCTechnology: "SEV_SNP",
CustomEndpoint: "example.com",
CCTechnology: "SEV_SNP",
IAMServiceAccountVM: "[email protected]",
}

// test that the variables are correctly rendered
Expand Down Expand Up @@ -151,10 +152,11 @@ node_groups = {
zone = "eu-central-1b"
}
}
custom_endpoint = "example.com"
internal_load_balancer = false
cc_technology = "SEV_SNP"
additional_labels = null
custom_endpoint = "example.com"
internal_load_balancer = false
cc_technology = "SEV_SNP"
iam_service_account_vm = "[email protected]"
additional_labels = null
`
got := vars.String()
assert.Equal(t, strings.Fields(want), strings.Fields(got)) // to ignore whitespace differences
Expand Down
4 changes: 4 additions & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,9 @@ type GCPConfig struct {
// Path of service account key file. For required service account roles, see https://docs.edgeless.systems/constellation/getting-started/install#authorization
ServiceAccountKeyPath string `yaml:"serviceAccountKeyPath" validate:"required"`
// description: |
// GCP service account mail address. This is being attached to the VMs for authorization.
IAMServiceAccountVM string `yaml:"IAMServiceAccountVM" validate:"required"`
// description: |
// Deploy Persistent Disk CSI driver with on-node encryption. For details see: https://docs.edgeless.systems/constellation/architecture/encrypted-storage
DeployCSIDriver *bool `yaml:"deployCSIDriver" validate:"required"`
// description: |
Expand Down Expand Up @@ -349,6 +352,7 @@ func Default() *Config {
Region: "",
Zone: "",
ServiceAccountKeyPath: "",
IAMServiceAccountVM: "",
DeployCSIDriver: toPtr(true),
UseMarketplaceImage: toPtr(false),
},
Expand Down
21 changes: 13 additions & 8 deletions internal/config/config_doc.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions internal/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -328,10 +328,10 @@ func TestFromFile(t *testing.T) {
}

func TestValidate(t *testing.T) {
const defaultErrCount = 33 // expect this number of error messages by default because user-specific values are not set and multiple providers are defined by default
const defaultErrCount = 34 // expect this number of error messages by default because user-specific values are not set and multiple providers are defined by default
const azErrCount = 7
const awsErrCount = 8
const gcpErrCount = 8
const gcpErrCount = 9

// TODO(AB#3132,3u13r): refactor config validation tests
// Note that the `cnf.Image = ""` is a hack to align `bazel test` with `go test` behavior
Expand Down Expand Up @@ -464,6 +464,7 @@ func TestValidate(t *testing.T) {
gcp.Project = "test-project"
gcp.Zone = "test-zone"
gcp.ServiceAccountKeyPath = "test-key-path"
gcp.IAMServiceAccountVM = "[email protected]"
cnf.Provider = ProviderConfig{}
cnf.Provider.GCP = gcp
cnf.Attestation.GCPSEVSNP.Measurements = measurements.M{
Expand Down
1 change: 1 addition & 0 deletions terraform-provider-constellation/examples/full/gcp/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ module "gcp_infrastructure" {
project = local.project_id
internal_load_balancer = false
cc_technology = local.cc_technology
iam_service_account_vm = module.gcp_iam.service_account_mail_vm
}

data "constellation_attestation" "foo" {
Expand Down
45 changes: 23 additions & 22 deletions terraform/infrastructure/gcp/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -160,28 +160,29 @@ resource "google_compute_firewall" "firewall_internal_pods" {
}

module "instance_group" {
source = "./modules/instance_group"
for_each = var.node_groups
base_name = local.name
node_group_name = each.key
role = each.value.role
zone = each.value.zone
uid = local.uid
instance_type = each.value.instance_type
initial_count = each.value.initial_count
image_id = var.image_id
disk_size = each.value.disk_size
disk_type = each.value.disk_type
network = google_compute_network.vpc_network.id
subnetwork = google_compute_subnetwork.vpc_subnetwork.id
alias_ip_range_name = google_compute_subnetwork.vpc_subnetwork.secondary_ip_range[0].range_name
kube_env = local.kube_env
debug = var.debug
named_ports = each.value.role == "control-plane" ? local.control_plane_named_ports : []
labels = local.labels
init_secret_hash = local.init_secret_hash
custom_endpoint = var.custom_endpoint
cc_technology = var.cc_technology
source = "./modules/instance_group"
for_each = var.node_groups
base_name = local.name
node_group_name = each.key
role = each.value.role
zone = each.value.zone
uid = local.uid
instance_type = each.value.instance_type
initial_count = each.value.initial_count
image_id = var.image_id
disk_size = each.value.disk_size
disk_type = each.value.disk_type
network = google_compute_network.vpc_network.id
subnetwork = google_compute_subnetwork.vpc_subnetwork.id
alias_ip_range_name = google_compute_subnetwork.vpc_subnetwork.secondary_ip_range[0].range_name
kube_env = local.kube_env
debug = var.debug
named_ports = each.value.role == "control-plane" ? local.control_plane_named_ports : []
labels = local.labels
init_secret_hash = local.init_secret_hash
custom_endpoint = var.custom_endpoint
cc_technology = var.cc_technology
iam_service_account_vm = var.iam_service_account_vm
}

resource "google_compute_address" "loadbalancer_ip_internal" {
Expand Down
14 changes: 4 additions & 10 deletions terraform/infrastructure/gcp/modules/instance_group/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -77,17 +77,11 @@ resource "google_compute_instance_template" "template" {
on_host_maintenance = "TERMINATE"
}

# Define all IAM access via the service account and not via scopes:
# See: https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_instance_template#nested_service_account
service_account {
scopes = [
"https://www.googleapis.com/auth/compute",
"https://www.googleapis.com/auth/servicecontrol",
"https://www.googleapis.com/auth/service.management.readonly",
"https://www.googleapis.com/auth/devstorage.read_only",
"https://www.googleapis.com/auth/logging.write",
"https://www.googleapis.com/auth/monitoring.write",
"https://www.googleapis.com/auth/trace.append",
"https://www.googleapis.com/auth/cloud-platform",
]
email = var.iam_service_account_vm
scopes = ["cloud-platform"]
}

shielded_instance_config {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,9 @@ variable "cc_technology" {
error_message = "The confidential computing technology has to be 'SEV' or 'SEV_SNP'."
}
}

variable "iam_service_account_vm" {
type = string
default = ""
description = "IAM service account used for the VMs"
}
6 changes: 6 additions & 0 deletions terraform/infrastructure/gcp/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,9 @@ variable "additional_labels" {
default = {}
description = "Additional labels that should be given to created recources."
}

variable "iam_service_account_vm" {
type = string
default = ""
description = "IAM service account used for the VMs"
}

0 comments on commit b1b1b65

Please sign in to comment.