Skip to content

Commit

Permalink
add node config shielded instance config
Browse files Browse the repository at this point in the history
  • Loading branch information
megan07 committed Oct 11, 2019
2 parents e18cfe9 + 6e56d74 commit 407f2b0
Show file tree
Hide file tree
Showing 5 changed files with 274 additions and 1 deletion.
42 changes: 42 additions & 0 deletions google-beta/node_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,27 @@ var schemaNodeConfig = &schema.Schema{
Elem: &schema.Schema{Type: schema.TypeString},
},

"shielded_instance_config": {
Type: schema.TypeList,
Optional: true,
Computed: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"enable_secure_boot": {
Type: schema.TypeBool,
Optional: true,
Default: false,
},
"enable_integrity_monitoring": {
Type: schema.TypeBool,
Optional: true,
Default: true,
},
},
},
},

"taint": {
Type: schema.TypeList,
Optional: true,
Expand Down Expand Up @@ -298,6 +319,15 @@ func expandNodeConfig(v interface{}) *containerBeta.NodeConfig {
}
nc.Tags = tags
}

if v, ok := nodeConfig["shielded_instance_config"]; ok && len(v.([]interface{})) > 0 {
conf := v.([]interface{})[0].(map[string]interface{})
nc.ShieldedInstanceConfig = &containerBeta.ShieldedInstanceConfig{
EnableSecureBoot: conf["enable_secure_boot"].(bool),
EnableIntegrityMonitoring: conf["enable_integrity_monitoring"].(bool),
}
}

// Preemptible Is Optional+Default, so it always has a value
nc.Preemptible = nodeConfig["preemptible"].(bool)

Expand Down Expand Up @@ -357,6 +387,7 @@ func flattenNodeConfig(c *containerBeta.NodeConfig) []map[string]interface{} {
"tags": c.Tags,
"preemptible": c.Preemptible,
"min_cpu_platform": c.MinCpuPlatform,
"shielded_instance_config": flattenShieldedInstanceConfig(c.ShieldedInstanceConfig),
"taint": flattenTaints(c.Taints),
"workload_metadata_config": flattenWorkloadMetadataConfig(c.WorkloadMetadataConfig),
"sandbox_config": flattenSandboxConfig(c.SandboxConfig),
Expand All @@ -380,6 +411,17 @@ func flattenContainerGuestAccelerators(c []*containerBeta.AcceleratorConfig) []m
return result
}

func flattenShieldedInstanceConfig(c *containerBeta.ShieldedInstanceConfig) []map[string]interface{} {
result := []map[string]interface{}{}
if c != nil {
result = append(result, map[string]interface{}{
"enable_secure_boot": c.EnableSecureBoot,
"enable_integrity_monitoring": c.EnableIntegrityMonitoring,
})
}
return result
}

func flattenTaints(c []*containerBeta.NodeTaint) []map[string]interface{} {
result := []map[string]interface{}{}
for _, taint := range c {
Expand Down
35 changes: 34 additions & 1 deletion google-beta/resource_container_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,12 @@ func resourceContainerCluster() *schema.Resource {
Default: false,
},

"enable_shielded_nodes": {
Type: schema.TypeBool,
Optional: true,
Default: false,
},

"authenticator_groups_config": {
Type: schema.TypeList,
Optional: true,
Expand Down Expand Up @@ -916,7 +922,11 @@ func resourceContainerClusterCreate(d *schema.ResourceData, meta interface{}) er
EnableKubernetesAlpha: d.Get("enable_kubernetes_alpha").(bool),
IpAllocationPolicy: expandIPAllocationPolicy(d.Get("ip_allocation_policy")),
PodSecurityPolicyConfig: expandPodSecurityPolicyConfig(d.Get("pod_security_policy_config")),
EnableTpu: d.Get("enable_tpu").(bool),
ShieldedNodes: &containerBeta.ShieldedNodes{
Enabled: d.Get("enable_shielded_nodes").(bool),
ForceSendFields: []string{"Enabled"},
},
EnableTpu: d.Get("enable_tpu").(bool),
BinaryAuthorization: &containerBeta.BinaryAuthorization{
Enabled: d.Get("enable_binary_authorization").(bool),
ForceSendFields: []string{"Enabled"},
Expand Down Expand Up @@ -1163,6 +1173,7 @@ func resourceContainerClusterRead(d *schema.ResourceData, meta interface{}) erro
d.Set("monitoring_service", cluster.MonitoringService)
d.Set("network", cluster.NetworkConfig.Network)
d.Set("subnetwork", cluster.NetworkConfig.Subnetwork)
d.Set("enable_shielded_nodes", cluster.ShieldedNodes.Enabled)
d.Set("enable_binary_authorization", cluster.BinaryAuthorization != nil && cluster.BinaryAuthorization.Enabled)
d.Set("enable_tpu", cluster.EnableTpu)
d.Set("tpu_ipv4_cidr_block", cluster.TpuIpv4CidrBlock)
Expand Down Expand Up @@ -1306,6 +1317,28 @@ func resourceContainerClusterUpdate(d *schema.ResourceData, meta interface{}) er
d.SetPartial("addons_config")
}
}
if d.HasChange("enable_shielded_nodes") {
enabled := d.Get("enable_shielded_nodes").(bool)
req := &containerBeta.UpdateClusterRequest{
Update: &containerBeta.ClusterUpdate{
DesiredShieldedNodes: &containerBeta.ShieldedNodes{
Enabled: enabled,
ForceSendFields: []string{"Enabled"},
},
},
}

updateF := updateFunc(req, "updating GKE shielded nodes")
// Call update serially.
if err := lockedCall(lockKey, updateF); err != nil {
return err
}

log.Printf("[INFO] GKE cluster %s's shielded nodes has been updated to %v", d.Id(), enabled)

d.SetPartial("enable_shielded_nodes")
}

if d.HasChange("enable_binary_authorization") {
enabled := d.Get("enable_binary_authorization").(bool)
req := &containerBeta.UpdateClusterRequest{
Expand Down
108 changes: 108 additions & 0 deletions google-beta/resource_container_cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -744,6 +744,29 @@ func TestAccContainerCluster_withNodeConfigTaints(t *testing.T) {
})
}

func TestAccContainerCluster_withNodeConfigShieldedInstanceConfig(t *testing.T) {
t.Parallel()

clusterName := fmt.Sprintf("cluster-test-%s", acctest.RandString(10))

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckContainerClusterDestroy,
Steps: []resource.TestStep{
{
Config: testAccContainerCluster_withNodeConfigShieldedInstanceConfig(clusterName),
},
{
ResourceName: "google_container_cluster.with_node_config",
ImportStateIdPrefix: "us-central1-f/",
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func TestAccContainerCluster_withWorkloadMetadataConfig(t *testing.T) {
t.Parallel()

Expand Down Expand Up @@ -1389,6 +1412,38 @@ func TestAccContainerCluster_withBinaryAuthorization(t *testing.T) {
})
}

func TestAccContainerCluster_withShieldedNodes(t *testing.T) {
t.Parallel()

clusterName := fmt.Sprintf("cluster-test-%s", acctest.RandString(10))

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckContainerClusterDestroy,
Steps: []resource.TestStep{
{
Config: testAccContainerCluster_withShieldedNodes(clusterName, true),
},
{
ResourceName: "google_container_cluster.with_shielded_nodes",
ImportStateIdPrefix: "us-central1-a/",
ImportState: true,
ImportStateVerify: true,
},
{
Config: testAccContainerCluster_withShieldedNodes(clusterName, false),
},
{
ResourceName: "google_container_cluster.with_shielded_nodes",
ImportStateIdPrefix: "us-central1-a/",
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func TestAccContainerCluster_withFlexiblePodCIDR(t *testing.T) {
t.Parallel()

Expand Down Expand Up @@ -2283,6 +2338,47 @@ resource "google_container_cluster" "with_node_config" {
}`, acctest.RandString(10))
}

func testAccContainerCluster_withNodeConfigShieldedInstanceConfig(clusterName string) string {
return fmt.Sprintf(`
resource "google_container_cluster" "with_node_config" {
name = "%s"
zone = "us-central1-f"
initial_node_count = 1
node_config {
machine_type = "n1-standard-1"
disk_size_gb = 15
disk_type = "pd-ssd"
local_ssd_count = 1
oauth_scopes = [
"https://www.googleapis.com/auth/monitoring",
"https://www.googleapis.com/auth/compute",
"https://www.googleapis.com/auth/devstorage.read_only",
"https://www.googleapis.com/auth/logging.write"
]
service_account = "default"
metadata = {
foo = "bar"
disable-legacy-endpoints = "true"
}
labels = {
foo = "bar"
}
tags = ["foo", "bar"]
preemptible = true
min_cpu_platform = "Intel Broadwell"
// Updatable fields
image_type = "COS"
shielded_instance_config {
enable_secure_boot = true
enable_integrity_monitoring = true
}
}
}`, clusterName)
}

func testAccContainerCluster_withWorkloadMetadataConfig() string {
return fmt.Sprintf(`
data "google_container_engine_versions" "central1a" {
Expand Down Expand Up @@ -3084,6 +3180,18 @@ resource "google_container_cluster" "with_binary_authorization" {
`, clusterName, enabled)
}

func testAccContainerCluster_withShieldedNodes(clusterName string, enabled bool) string {
return fmt.Sprintf(`
resource "google_container_cluster" "with_shielded_nodes" {
name = "%s"
zone = "us-central1-a"
initial_node_count = 1
enable_shielded_nodes = %v
}
`, clusterName, enabled)
}

func testAccContainerCluster_withFlexiblePodCIDR(cluster string) string {
return fmt.Sprintf(`
resource "google_compute_network" "container_network" {
Expand Down
76 changes: 76 additions & 0 deletions google-beta/resource_container_node_pool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,39 @@ func TestAccContainerNodePool_EmptyGuestAccelerator(t *testing.T) {
})
}

func TestAccContainerNodePool_shieldedInstanceConfig(t *testing.T) {
t.Parallel()

cluster := fmt.Sprintf("tf-nodepool-test-%s", acctest.RandString(10))
np := fmt.Sprintf("tf-nodepool-test-%s", acctest.RandString(10))

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckContainerNodePoolDestroy,
Steps: []resource.TestStep{
{
Config: testAccContainerNodePool_shieldedInstanceConfig(cluster, np),
},
{
ResourceName: "google_container_node_pool.np",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"max_pods_per_node"},
},
{
Config: testAccContainerNodePool_updateShieldedInstanceConfig(cluster, np),
},
{
ResourceName: "google_container_node_pool.np",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"max_pods_per_node"},
},
},
})
}

func testAccCheckContainerNodePoolDestroy(s *terraform.State) error {
config := testAccProvider.Meta().(*Config)

Expand Down Expand Up @@ -1406,3 +1439,46 @@ resource "google_container_node_pool" "np" {
}
}`, cluster, np)
}

func testAccContainerNodePool_shieldedInstanceConfig(cluster, np string) string {
return fmt.Sprintf(`
resource "google_container_cluster" "cluster" {
name = "%s"
location = "us-central1-a"
initial_node_count = 1
}
resource "google_container_node_pool" "np" {
name = "%s"
location = "us-central1-a"
cluster = "${google_container_cluster.cluster.name}"
initial_node_count = 2
node_config {
shielded_instance_config {
enable_integrity_monitoring = true
}
}
}`, cluster, np)
}

func testAccContainerNodePool_updateShieldedInstanceConfig(cluster, np string) string {
return fmt.Sprintf(`
resource "google_container_cluster" "cluster" {
name = "%s"
location = "us-central1-a"
initial_node_count = 1
}
resource "google_container_node_pool" "np" {
name = "%s"
location = "us-central1-a"
cluster = "${google_container_cluster.cluster.name}"
initial_node_count = 2
node_config {
shielded_instance_config {
enable_secure_boot = true
enable_integrity_monitoring = true
}
}
}`, cluster, np)
}
14 changes: 14 additions & 0 deletions website/docs/r/container_cluster.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,8 @@ for more details. Structure is documented below.
will have statically granted permissions beyond those provided by the RBAC configuration or IAM.
Defaults to `false`

* `enable_shielded_nodes` - (Optional, [Beta](https://terraform.io/docs/providers/google/provider_versions.html)) Enable Shielded Nodes features on all nodes in this cluster. Defaults to `false`.

* `initial_node_count` - (Optional) The number of nodes to create in this
cluster's default node pool. In regional or multi-zonal clusters, this is the
number of nodes per zone. Must be set if `node_pool` is not set. If you're using
Expand Down Expand Up @@ -557,6 +559,8 @@ The `node_config` block supports:

-> Projects that enable the [Cloud Compute Engine API](https://cloud.google.com/compute/) with Terraform may need these roles added manually to the service account. Projects that enable the API in the Cloud Console should have them added automatically.

* `shielded_instance_config` - (Optional) Shielded Instance options. Structure is documented below.

* `tags` - (Optional) The list of instance tags applied to all nodes. Tags are used to identify
valid sources or targets for network firewalls.

Expand Down Expand Up @@ -629,6 +633,16 @@ resource_usage_export_config {
}
```

The `shielded_instance_config` block supports:

* `enable_secure_boot` (Optional) - Defines if the instance has Secure Boot enabled.

Secure Boot helps ensure that the system only runs authentic software by verifying the digital signature of all boot components, and halting the boot process if signature verification fails. Defaults to `false`.

* `enable_integrity_monitoring` (Optional) - Defines if the instance has integrity monitoring enabled.

Enables monitoring and attestation of the boot integrity of the instance. The attestation is performed against the integrity policy baseline. This baseline is initially derived from the implicitly trusted boot image when the instance is created. Defaults to `true`.

The `taint` block supports:

* `key` (Required) Key for taint.
Expand Down

0 comments on commit 407f2b0

Please sign in to comment.