Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adding security_policy field to TargetInstance #6122

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
3 changes: 3 additions & 0 deletions .changelog/8357.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
compute: added `security_policy` field to `google_compute_target_instance` resource (beta)
```
122 changes: 122 additions & 0 deletions google-beta/services/compute/resource_compute_target_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ func ResourceComputeTargetInstance() *schema.Resource {
return &schema.Resource{
Create: resourceComputeTargetInstanceCreate,
Read: resourceComputeTargetInstanceRead,
Update: resourceComputeTargetInstanceUpdate,
Delete: resourceComputeTargetInstanceDelete,

Importer: &schema.ResourceImporter{
Expand All @@ -43,6 +44,7 @@ func ResourceComputeTargetInstance() *schema.Resource {

Timeouts: &schema.ResourceTimeout{
Create: schema.DefaultTimeout(20 * time.Minute),
Update: schema.DefaultTimeout(20 * time.Minute),
Delete: schema.DefaultTimeout(20 * time.Minute),
},

Expand Down Expand Up @@ -92,6 +94,11 @@ Currently only NO_NAT (default value) is supported. Default value: "NO_NAT" Poss
ForceNew: true,
Description: `The URL of the network this target instance uses to forward traffic. If not specified, the traffic will be forwarded to the network that the default network interface belongs to.`,
},
"security_policy": {
Type: schema.TypeString,
Optional: true,
Description: `The resource URL for the security policy associated with this target instance.`,
},
"zone": {
Type: schema.TypeString,
Computed: true,
Expand Down Expand Up @@ -158,6 +165,12 @@ func resourceComputeTargetInstanceCreate(d *schema.ResourceData, meta interface{
} else if v, ok := d.GetOkExists("nat_policy"); !tpgresource.IsEmptyValue(reflect.ValueOf(natPolicyProp)) && (ok || !reflect.DeepEqual(v, natPolicyProp)) {
obj["natPolicy"] = natPolicyProp
}
securityPolicyProp, err := expandComputeTargetInstanceSecurityPolicy(d.Get("security_policy"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("security_policy"); !tpgresource.IsEmptyValue(reflect.ValueOf(securityPolicyProp)) && (ok || !reflect.DeepEqual(v, securityPolicyProp)) {
obj["securityPolicy"] = securityPolicyProp
}
zoneProp, err := expandComputeTargetInstanceZone(d.Get("zone"), d, config)
if err != nil {
return err
Expand Down Expand Up @@ -214,6 +227,39 @@ func resourceComputeTargetInstanceCreate(d *schema.ResourceData, meta interface{
return fmt.Errorf("Error waiting to create TargetInstance: %s", err)
}

// security_policy isn't set by Create
if v, ok := d.GetOkExists("security_policy"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, securityPolicyProp)) {
obj := make(map[string]interface{})
securityPolicyProp, err := expandComputeTargetInstanceSecurityPolicy(v, d, config)
if err != nil {
return err
}
obj["security_policy"] = securityPolicyProp

url, err := tpgresource.ReplaceVars(d, config, "{{ComputeBasePath}}projects/{{project}}/zones/{{zone}}/targetInstances/{{name}}/setSecurityPolicy")
if err != nil {
return err
}

res, err = transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
Config: config,
Method: "POST",
Project: project,
RawURL: url,
UserAgent: userAgent,
Body: obj,
})

if err != nil {
return fmt.Errorf("Error adding SecurityPolicy to TargetInstance %q: %s", d.Id(), err)
}

err = ComputeOperationWaitTime(config, res, project, "Updating TargetInstance SecurityPolicy", userAgent, d.Timeout(schema.TimeoutUpdate))
if err != nil {
return err
}
}

log.Printf("[DEBUG] Finished creating TargetInstance %q: %#v", d.Id(), res)

return resourceComputeTargetInstanceRead(d, meta)
Expand Down Expand Up @@ -277,6 +323,9 @@ func resourceComputeTargetInstanceRead(d *schema.ResourceData, meta interface{})
if err := d.Set("nat_policy", flattenComputeTargetInstanceNatPolicy(res["natPolicy"], d, config)); err != nil {
return fmt.Errorf("Error reading TargetInstance: %s", err)
}
if err := d.Set("security_policy", flattenComputeTargetInstanceSecurityPolicy(res["securityPolicy"], d, config)); err != nil {
return fmt.Errorf("Error reading TargetInstance: %s", err)
}
if err := d.Set("zone", flattenComputeTargetInstanceZone(res["zone"], d, config)); err != nil {
return fmt.Errorf("Error reading TargetInstance: %s", err)
}
Expand All @@ -287,6 +336,71 @@ func resourceComputeTargetInstanceRead(d *schema.ResourceData, meta interface{})
return nil
}

func resourceComputeTargetInstanceUpdate(d *schema.ResourceData, meta interface{}) error {
config := meta.(*transport_tpg.Config)
userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent)
if err != nil {
return err
}

billingProject := ""

project, err := tpgresource.GetProject(d, config)
if err != nil {
return fmt.Errorf("Error fetching project for TargetInstance: %s", err)
}
billingProject = project

d.Partial(true)

if d.HasChange("security_policy") {
obj := make(map[string]interface{})

securityPolicyProp, err := expandComputeTargetInstanceSecurityPolicy(d.Get("security_policy"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("security_policy"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, securityPolicyProp)) {
obj["securityPolicy"] = securityPolicyProp
}

url, err := tpgresource.ReplaceVars(d, config, "{{ComputeBasePath}}projects/{{project}}/zones/{{zone}}/targetInstances/{{name}}/setSecurityPolicy")
if err != nil {
return err
}

// err == nil indicates that the billing_project value was found
if bp, err := tpgresource.GetBillingProject(d, config); err == nil {
billingProject = bp
}

res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
Config: config,
Method: "POST",
Project: billingProject,
RawURL: url,
UserAgent: userAgent,
Body: obj,
Timeout: d.Timeout(schema.TimeoutUpdate),
})
if err != nil {
return fmt.Errorf("Error updating TargetInstance %q: %s", d.Id(), err)
} else {
log.Printf("[DEBUG] Finished updating TargetInstance %q: %#v", d.Id(), res)
}

err = ComputeOperationWaitTime(
config, res, project, "Updating TargetInstance", userAgent,
d.Timeout(schema.TimeoutUpdate))
if err != nil {
return err
}
}

d.Partial(false)

return resourceComputeTargetInstanceRead(d, meta)
}

func resourceComputeTargetInstanceDelete(d *schema.ResourceData, meta interface{}) error {
config := meta.(*transport_tpg.Config)
userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent)
Expand Down Expand Up @@ -388,6 +502,10 @@ func flattenComputeTargetInstanceNatPolicy(v interface{}, d *schema.ResourceData
return v
}

func flattenComputeTargetInstanceSecurityPolicy(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}

func flattenComputeTargetInstanceZone(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
if v == nil {
return v
Expand Down Expand Up @@ -444,6 +562,10 @@ func expandComputeTargetInstanceNatPolicy(v interface{}, d tpgresource.Terraform
return v, nil
}

func expandComputeTargetInstanceSecurityPolicy(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
return v, nil
}

func expandComputeTargetInstanceZone(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
f, err := tpgresource.ParseGlobalFieldValue("zones", v.(string), "project", d, config, true)
if err != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,114 @@ resource "google_compute_instance" "target-vm" {
`, context)
}

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

context := map[string]interface{}{
"random_suffix": acctest.RandString(t, 10),
}

acctest.VcrTest(t, resource.TestCase{
PreCheck: func() { acctest.AccTestPreCheck(t) },
ProtoV5ProviderFactories: acctest.ProtoV5ProviderBetaFactories(t),
CheckDestroy: testAccCheckComputeTargetInstanceDestroyProducer(t),
Steps: []resource.TestStep{
{
Config: testAccComputeTargetInstance_targetInstanceWithSecurityPolicyExample(context),
},
{
ResourceName: "google_compute_target_instance.default",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"instance", "zone"},
},
},
})
}

func testAccComputeTargetInstance_targetInstanceWithSecurityPolicyExample(context map[string]interface{}) string {
return acctest.Nprintf(`
resource "google_compute_network" "default" {
provider = google-beta
name = "tf-test-custom-default-network%{random_suffix}"
auto_create_subnetworks = false
routing_mode = "REGIONAL"
}

resource "google_compute_subnetwork" "default" {
provider = google-beta
name = "tf-test-custom-default-subnet%{random_suffix}"
ip_cidr_range = "10.1.2.0/24"
network = google_compute_network.default.id
private_ipv6_google_access = "DISABLE_GOOGLE_ACCESS"
purpose = "PRIVATE"
region = "southamerica-west1"
stack_type = "IPV4_ONLY"
}

data "google_compute_image" "vmimage" {
provider = google-beta
family = "debian-11"
project = "debian-cloud"
}

resource "google_compute_instance" "target-vm" {
provider = google-beta
name = "tf-test-target-vm%{random_suffix}"
machine_type = "e2-medium"
zone = "southamerica-west1-a"

boot_disk {
initialize_params {
image = data.google_compute_image.vmimage.self_link
}
}

network_interface {
network = google_compute_network.default.self_link
subnetwork = google_compute_subnetwork.default.self_link
access_config {
}
}
}

resource "google_compute_region_security_policy" "policyddosprotection" {
provider = google-beta
region = "southamerica-west1"
name = "tf-test-policyddos%{random_suffix}"
description = "ddos protection security policy to set target instance"
type = "CLOUD_ARMOR_NETWORK"
ddos_protection_config {
ddos_protection = "ADVANCED_PREVIEW"
}
}

resource "google_compute_network_edge_security_service" "edge_sec_service" {
provider = google-beta
region = "southamerica-west1"
name = "tf-test-edgesec%{random_suffix}"
security_policy = google_compute_region_security_policy.policyddosprotection.self_link
}

resource "google_compute_region_security_policy" "regionsecuritypolicy" {
provider = google-beta
name = "tf-test-region-secpolicy%{random_suffix}"
region = "southamerica-west1"
description = "basic security policy for target instance"
type = "CLOUD_ARMOR_NETWORK"
depends_on = [google_compute_network_edge_security_service.edge_sec_service]
}

resource "google_compute_target_instance" "default" {
provider = google-beta
name = "tf-test-target-instance%{random_suffix}"
zone = "southamerica-west1-a"
instance = google_compute_instance.target-vm.id
security_policy = google_compute_region_security_policy.regionsecuritypolicy.self_link
}
`, context)
}

func testAccCheckComputeTargetInstanceDestroyProducer(t *testing.T) func(s *terraform.State) error {
return func(s *terraform.State) error {
for name, rs := range s.RootModule().Resources {
Expand Down
Loading