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

Serial port datasource #1860

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/3247.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:new-datasource
`google_compute_instance_serial_port`
```
59 changes: 59 additions & 0 deletions google-beta/data_source_google_compute_instance_serial_port.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package google

import (
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)

func dataSourceGoogleComputeInstanceSerialPort() *schema.Resource {
return &schema.Resource{
Read: computeInstanceSerialPortRead,
Schema: map[string]*schema.Schema{
"port": {
Type: schema.TypeInt,
Required: true,
},
"instance": {
Type: schema.TypeString,
Required: true,
},
"zone": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"project": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"contents": {
Type: schema.TypeString,
Computed: true,
},
},
}
}

func computeInstanceSerialPortRead(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
project, err := getProject(d, config)
if err != nil {
return err
}
d.Set("project", project)
zone, err := getZone(d, config)
if err != nil {
return err
}
d.Set("zone", zone)

port := int64(d.Get("port").(int))
output, err := config.clientCompute.Instances.GetSerialPortOutput(project, zone, d.Get("instance").(string)).Port(port).Do()
if err != nil {
return err
}

d.Set("contents", output.Contents)
d.SetId(output.SelfLink)
return nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package google

import (
"fmt"
"regexp"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
)

func TestAccDataSourceComputeInstanceSerialPort_basic(t *testing.T) {
instanceName := fmt.Sprintf("tf-test-serial-data-%s", acctest.RandString(10))
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccComputeInstanceSerialPort(instanceName),
Check: resource.ComposeTestCheckFunc(
// Contents of serial port output include lots of initialization logging
resource.TestMatchResourceAttr("data.google_compute_instance_serial_port.serial", "contents",
regexp.MustCompile("Initializing cgroup subsys")),
),
},
},
})
}

func testAccComputeInstanceSerialPort(instanceName string) string {
return fmt.Sprintf(`
resource "google_compute_instance" "default" {
name = "%s"
machine_type = "n1-standard-1"
zone = "us-central1-a"

boot_disk {
initialize_params {
image = "debian-8-jessie-v20160803"
}
}

// Local SSD disk
scratch_disk {
interface = "SCSI"
}

network_interface {
network = "default"

access_config {
// Ephemeral IP
}
}

metadata = {
foo = "bar"
serial-port-logging-enable = "TRUE"
windows-keys = jsonencode(
{
email = "example.user@example.com"
expireOn = "2020-04-14T01:37:19Z"
exponent = "AQAB"
modulus = "wgsquN4IBNPqIUnu+h/5Za1kujb2YRhX1vCQVQAkBwnWigcCqOBVfRa5JoZfx6KIvEXjWqa77jPvlsxM4WPqnDIM2qiK36up3SKkYwFjff6F2ni/ry8vrwXCX3sGZ1hbIHlK0O012HpA3ISeEswVZmX2X67naOvJXfY5v0hGPWqCADao+xVxrmxsZD4IWnKl1UaZzI5lhAzr8fw6utHwx1EZ/MSgsEki6tujcZfN+GUDRnmJGQSnPTXmsf7Q4DKreTZk49cuyB3prV91S0x3DYjCUpSXrkVy1Ha5XicGD/q+ystuFsJnrrhbNXJbpSjM6sjo/aduAkZJl4FmOt0R7Q=="
userName = "example-user"
}
)
}

service_account {
scopes = ["userinfo-email", "compute-ro", "storage-ro"]
}
}

data "google_compute_instance_serial_port" "serial" {
instance = google_compute_instance.default.name
zone = google_compute_instance.default.zone
port = 1
}
`, instanceName)
}
1 change: 1 addition & 0 deletions google-beta/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,7 @@ func Provider() terraform.ResourceProvider {
"google_compute_global_address": dataSourceGoogleComputeGlobalAddress(),
"google_compute_image": dataSourceGoogleComputeImage(),
"google_compute_instance": dataSourceGoogleComputeInstance(),
"google_compute_instance_serial_port": dataSourceGoogleComputeInstanceSerialPort(),
"google_compute_instance_group": dataSourceGoogleComputeInstanceGroup(),
"google_compute_lb_ip_ranges": dataSourceGoogleComputeLbIpRanges(),
"google_compute_network": dataSourceGoogleComputeNetwork(),
Expand Down
102 changes: 102 additions & 0 deletions website/docs/d/datasource_compute_instance_serial_port.html.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
---
subcategory: "Compute Engine"
layout: "google"
page_title: "Google: google_compute_instance_serial_port"
sidebar_current: "docs-google-datasource-compute-instance-serial-port"
description: |-
Get the serial port output from a Compute Instance.
---

# google\_compute\_instance\_serial\_port

Get the serial port output from a Compute Instance. For more information see
the official [API](https://cloud.google.com/compute/docs/instances/viewing-serial-port-output) documentation.

## Example Usage

```hcl
data "google_compute_instance_serial_port" "serial" {
instance = "my-instance"
zone = "us-central1-a"
port = 1
}
output "serial_out" {
value = data.google_compute_instance_serial_port.serial.contents
}
```

Using the serial port output to generate a windows password, derived from the [official guide](https://cloud.google.com/compute/docs/instances/windows/automate-pw-generation):

```hcl
resource "google_compute_instance" "windows" {
name = "windows-instance"
machine_type = "n1-standard-1"
zone = "us-central1-a"
boot_disk {
initialize_params {
image = "gce-uefi-images/windows-2019"
}
}
network_interface {
network = "default"
access_config {
// Ephemeral IP
}
}
metadata = {
serial-port-logging-enable = "TRUE"
// Derived from https://cloud.google.com/compute/docs/instances/windows/automate-pw-generation
windows-keys = jsonencode(
{
email = "example.user@example.com"
expireOn = "2020-04-14T01:37:19Z"
exponent = "AQAB"
modulus = "wgsquN4IBNPqIUnu+h/5Za1kujb2YRhX1vCQVQAkBwnWigcCqOBVfRa5JoZfx6KIvEXjWqa77jPvlsxM4WPqnDIM2qiK36up3SKkYwFjff6F2ni/ry8vrwXCX3sGZ1hbIHlK0O012HpA3ISeEswVZmX2X67naOvJXfY5v0hGPWqCADao+xVxrmxsZD4IWnKl1UaZzI5lhAzr8fw6utHwx1EZ/MSgsEki6tujcZfN+GUDRnmJGQSnPTXmsf7Q4DKreTZk49cuyB3prV91S0x3DYjCUpSXrkVy1Ha5XicGD/q+ystuFsJnrrhbNXJbpSjM6sjo/aduAkZJl4FmOt0R7Q=="
userName = "example-user"
}
)
}
service_account {
scopes = ["userinfo-email", "compute-ro", "storage-ro"]
}
}
data "google_compute_instance_serial_port" "serial" {
instance = google_compute_instance.windows.name
zone = google_compute_instance.windows.zone
port = 4
}
output "serial_out" {
value = data.google_compute_instance_serial_port.serial.contents
}
```

## Argument Reference

The following arguments are supported:

* `instance` - (Required) The name of the Compute Instance to read output from.

* `port` - (Required) The number of the serial port to read output from. Possible values are 1-4.

- - -

* `project` - (Optional) The project in which the Compute Instance exists. If it
is not provided, the provider project is used.

* `zone` - (Optional) The zone in which the Compute Instance exists.
If it is not provided, the provider zone is used.

## Attributes Reference

In addition to the arguments listed above, the following computed attributes are
exported:

* `contents` - The output of the serial port. Serial port output is available only when the VM instance is running, and logs are limited to the most recent 1 MB of output per port.