package google import ( "fmt" "log" "github.com/hashicorp/terraform/helper/schema" "google.golang.org/api/compute/v1" ) func resourceComputeProjectMetadata() *schema.Resource { return &schema.Resource{ Create: resourceComputeProjectMetadataCreateOrUpdate, Read: resourceComputeProjectMetadataRead, Update: resourceComputeProjectMetadataCreateOrUpdate, Delete: resourceComputeProjectMetadataDelete, Importer: &schema.ResourceImporter{ State: schema.ImportStatePassthrough, }, SchemaVersion: 0, Schema: map[string]*schema.Schema{ "metadata": { Type: schema.TypeMap, Required: true, Elem: &schema.Schema{Type: schema.TypeString}, }, "project": { Type: schema.TypeString, Optional: true, Computed: true, ForceNew: true, }, }, } } func resourceComputeProjectMetadataCreateOrUpdate(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) projectID, err := getProject(d, config) if err != nil { return err } md := &compute.Metadata{ Items: expandComputeMetadata(d.Get("metadata").(map[string]interface{})), } err = resourceComputeProjectMetadataSet(projectID, config, md) if err != nil { return fmt.Errorf("SetCommonInstanceMetadata failed: %s", err) } d.SetId(projectID) return resourceComputeProjectMetadataRead(d, meta) } func resourceComputeProjectMetadataRead(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) // At import time, we have no state to draw from. We'll wrongly pull the // provider default project if we use a normal getProject, so we need to // rely on the `id` field being set to the project. // At any other time we can use getProject, as state will have the correct // value; the project pulled from config / the provider / at import time. // // Note that if a user imports a project other than their provider project // and has left the project field unspecified, Terraform will not see a diff // but would create metadata for the provider project on a destroy/create. projectId := d.Id() project, err := config.clientCompute.Projects.Get(projectId).Do() if err != nil { return handleNotFoundError(err, d, fmt.Sprintf("Project metadata for project %q", projectId)) } err = d.Set("metadata", flattenMetadata(project.CommonInstanceMetadata)) if err != nil { return fmt.Errorf("Error setting metadata: %s", err) } d.Set("project", projectId) return nil } func resourceComputeProjectMetadataDelete(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) projectID, err := getProject(d, config) if err != nil { return err } md := &compute.Metadata{} err = resourceComputeProjectMetadataSet(projectID, config, md) if err != nil { return fmt.Errorf("SetCommonInstanceMetadata failed: %s", err) } return resourceComputeProjectMetadataRead(d, meta) } func resourceComputeProjectMetadataSet(projectID string, config *Config, md *compute.Metadata) error { createMD := func() error { log.Printf("[DEBUG] Loading project service: %s", projectID) project, err := config.clientCompute.Projects.Get(projectID).Do() if err != nil { return fmt.Errorf("Error loading project '%s': %s", projectID, err) } md.Fingerprint = project.CommonInstanceMetadata.Fingerprint op, err := config.clientCompute.Projects.SetCommonInstanceMetadata(projectID, md).Do() if err != nil { return fmt.Errorf("SetCommonInstanceMetadata failed: %s", err) } log.Printf("[DEBUG] SetCommonMetadata: %d (%s)", op.Id, op.SelfLink) return computeOperationWait(config.clientCompute, op, project.Name, "SetCommonMetadata") } err := MetadataRetryWrapper(createMD) return err }