Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions data/data/gcp/bootstrap/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -30,26 +30,29 @@ resource "google_storage_bucket_object" "ignition" {
}

resource "google_service_account" "bootstrap-node-sa" {
count = var.gcp_create_bootstrap_sa ? 1 : 0
account_id = "${var.cluster_id}-b"
display_name = "${var.cluster_id}-bootstrap-node"
description = local.description
}

resource "google_service_account_key" "bootstrap" {
service_account_id = google_service_account.bootstrap-node-sa.name
count = var.gcp_create_bootstrap_sa ? 1 : 0
service_account_id = google_service_account.bootstrap-node-sa[0].name
}

resource "google_project_iam_member" "bootstrap-storage-admin" {
count = var.gcp_create_bootstrap_sa ? 1 : 0
project = var.gcp_project_id
role = "roles/storage.admin"
member = "serviceAccount:${google_service_account.bootstrap-node-sa.email}"
member = "serviceAccount:${google_service_account.bootstrap-node-sa[0].email}"
}

data "google_storage_object_signed_url" "ignition_url" {
bucket = google_storage_bucket.ignition.name
path = "bootstrap.ign"
duration = "1h"
credentials = base64decode(google_service_account_key.bootstrap.private_key)
credentials = var.gcp_create_bootstrap_sa ? base64decode(google_service_account_key.bootstrap[0].private_key) : null
}

data "ignition_config" "redirect" {
Expand Down
6 changes: 6 additions & 0 deletions data/data/gcp/variables-gcp.tf
Original file line number Diff line number Diff line change
Expand Up @@ -163,3 +163,9 @@ variable "gcp_master_on_host_maintenance" {
description = "The behavior when a maintenance event occurs."
default = ""
}

variable "gcp_create_bootstrap_sa" {
type = bool
default = false
description = "Whether a service account should be created to sign the ignition URL."
}
36 changes: 9 additions & 27 deletions pkg/asset/cluster/tfvars.go
Original file line number Diff line number Diff line change
Expand Up @@ -392,23 +392,6 @@ func (t *TerraformVariables) Generate(parents asset.Parents) error {
return err
}

instanceServiceAccount := ""

// Passthrough service accounts are only needed for GCP XPN.
ic := installConfig.Config
if len(ic.GCP.NetworkProjectID) > 0 && ic.CredentialsMode == types.PassthroughCredentialsMode {
var found bool
serviceAccount := make(map[string]interface{})
err := json.Unmarshal([]byte(sess.Credentials.JSON), &serviceAccount)
if err != nil {
return err
}
instanceServiceAccount, found = serviceAccount["client_email"].(string)
if !found {
return errors.New("could not find google service account")
}
}

auth := gcptfvars.Auth{
ProjectID: installConfig.Config.GCP.ProjectID,
NetworkProjectID: installConfig.Config.GCP.NetworkProjectID,
Expand Down Expand Up @@ -475,16 +458,15 @@ func (t *TerraformVariables) Generate(parents asset.Parents) error {
imageURL := fmt.Sprintf("https://storage.googleapis.com/rhcos/rhcos/%s.tar.gz", img.Name)
data, err := gcptfvars.TFVars(
gcptfvars.TFVarsSources{
Auth: auth,
MasterConfigs: masterConfigs,
WorkerConfigs: workerConfigs,
CreateFirewallRules: createFirewallRules,
ImageURI: imageURL,
ImageLicenses: installConfig.Config.GCP.Licenses,
InstanceServiceAccount: instanceServiceAccount,
PreexistingNetwork: preexistingnetwork,
PublicZoneName: publicZone.Name,
PublishStrategy: installConfig.Config.Publish,
Auth: auth,
MasterConfigs: masterConfigs,
WorkerConfigs: workerConfigs,
CreateFirewallRules: createFirewallRules,
ImageURI: imageURL,
ImageLicenses: installConfig.Config.GCP.Licenses,
PreexistingNetwork: preexistingnetwork,
PublicZoneName: publicZone.Name,
PublishStrategy: installConfig.Config.Publish,
},
)
if err != nil {
Expand Down
45 changes: 34 additions & 11 deletions pkg/tfvars/gcp/gcp.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"encoding/json"
"fmt"

"github.com/pkg/errors"

machineapi "github.com/openshift/api/machine/v1beta1"
"github.com/openshift/installer/pkg/types"
)
Expand All @@ -23,6 +25,7 @@ type config struct {
Auth `json:",inline"`
Region string `json:"gcp_region,omitempty"`
BootstrapInstanceType string `json:"gcp_bootstrap_instance_type,omitempty"`
CreateBootstrapSA bool `json:"gcp_create_bootstrap_sa"`
CreateFirewallRules bool `json:"gcp_create_firewall_rules"`
MasterInstanceType string `json:"gcp_master_instance_type,omitempty"`
MasterAvailabilityZones []string `json:"gcp_master_availability_zones"`
Expand All @@ -48,16 +51,15 @@ type config struct {

// TFVarsSources contains the parameters to be converted into Terraform variables
type TFVarsSources struct {
Auth Auth
CreateFirewallRules bool
ImageURI string
ImageLicenses []string
InstanceServiceAccount string
MasterConfigs []*machineapi.GCPMachineProviderSpec
WorkerConfigs []*machineapi.GCPMachineProviderSpec
PublicZoneName string
PublishStrategy types.PublishingStrategy
PreexistingNetwork bool
Auth Auth
CreateFirewallRules bool
ImageURI string
ImageLicenses []string
MasterConfigs []*machineapi.GCPMachineProviderSpec
WorkerConfigs []*machineapi.GCPMachineProviderSpec
PublicZoneName string
PublishStrategy types.PublishingStrategy
PreexistingNetwork bool
}

// TFVars generates gcp-specific Terraform variables launching the cluster.
Expand All @@ -81,7 +83,6 @@ func TFVars(sources TFVarsSources) ([]byte, error) {
ImageURI: sources.ImageURI,
Image: masterConfig.Disks[0].Image,
ImageLicenses: sources.ImageLicenses,
InstanceServiceAccount: sources.InstanceServiceAccount,
PublicZoneName: sources.PublicZoneName,
PublishStrategy: string(sources.PublishStrategy),
ClusterNetwork: masterConfig.NetworkInterfaces[0].Network,
Expand All @@ -103,6 +104,28 @@ func TFVars(sources TFVarsSources) ([]byte, error) {
cfg.VolumeKMSKeyLink = generateDiskEncryptionKeyLink(masterConfig.Disks[0].EncryptionKey, masterConfig.ProjectID)
}

serviceAccount := make(map[string]interface{})

if err := json.Unmarshal([]byte(cfg.Auth.ServiceAccount), &serviceAccount); len(cfg.Auth.ServiceAccount) > 0 && err != nil {
return nil, errors.Wrapf(err, "unmarshaling service account")
}

instanceServiceAccount := ""
// Passthrough service accounts are only needed for GCP XPN.
if len(cfg.Auth.NetworkProjectID) > 0 {
var found bool
instanceServiceAccount, found = serviceAccount["client_email"].(string)
if !found {
return nil, errors.New("could not find google service account")
}
}
cfg.InstanceServiceAccount = instanceServiceAccount

// A private key is needed to sign the URL for bootstrap ignition.
// If there is no key in the credentials, we need to generate a new SA.
_, foundKey := serviceAccount["private_key"]
cfg.CreateBootstrapSA = !foundKey

return json.MarshalIndent(cfg, "", " ")
}

Expand Down