provider/google: Support static private IP addresses (#6310)
* provider/google: Support static private IP addresses The private address of an instance's network interface may now be specified. If no value is provided, an address will be chosen by Google Compute Engine and that value will be read into Terraform state. * docs: GCE private static IP address information
This commit is contained in:
parent
25b49dfd51
commit
3ac3516371
|
@ -153,6 +153,8 @@ func resourceComputeInstance() *schema.Resource {
|
|||
|
||||
"address": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
ForceNew: true,
|
||||
Computed: true,
|
||||
},
|
||||
|
||||
|
@ -467,9 +469,10 @@ func resourceComputeInstanceCreate(d *schema.ResourceData, meta interface{}) err
|
|||
networkInterfaces = make([]*compute.NetworkInterface, 0, networkInterfacesCount)
|
||||
for i := 0; i < networkInterfacesCount; i++ {
|
||||
prefix := fmt.Sprintf("network_interface.%d", i)
|
||||
// Load up the name of this network_interfac
|
||||
// Load up the name of this network_interface
|
||||
networkName := d.Get(prefix + ".network").(string)
|
||||
subnetworkName := d.Get(prefix + ".subnetwork").(string)
|
||||
address := d.Get(prefix + ".address").(string)
|
||||
var networkLink, subnetworkLink string
|
||||
|
||||
if networkName != "" && subnetworkName != "" {
|
||||
|
@ -499,6 +502,7 @@ func resourceComputeInstanceCreate(d *schema.ResourceData, meta interface{}) err
|
|||
var iface compute.NetworkInterface
|
||||
iface.Network = networkLink
|
||||
iface.Subnetwork = subnetworkLink
|
||||
iface.NetworkIP = address
|
||||
|
||||
// Handle access_config structs
|
||||
accessConfigsCount := d.Get(prefix + ".access_config.#").(int)
|
||||
|
|
|
@ -371,6 +371,47 @@ func TestAccComputeInstance_subnet_custom(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestAccComputeInstance_address_auto(t *testing.T) {
|
||||
var instance compute.Instance
|
||||
var instanceName = fmt.Sprintf("instance-test-%s", acctest.RandString(10))
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckComputeInstanceDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
resource.TestStep{
|
||||
Config: testAccComputeInstance_address_auto(instanceName),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckComputeInstanceExists(
|
||||
"google_compute_instance.foobar", &instance),
|
||||
testAccCheckComputeInstanceHasAnyAddress(&instance),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccComputeInstance_address_custom(t *testing.T) {
|
||||
var instance compute.Instance
|
||||
var instanceName = fmt.Sprintf("instance-test-%s", acctest.RandString(10))
|
||||
var address = "10.0.200.200"
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckComputeInstanceDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
resource.TestStep{
|
||||
Config: testAccComputeInstance_address_custom(instanceName, address),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckComputeInstanceExists(
|
||||
"google_compute_instance.foobar", &instance),
|
||||
testAccCheckComputeInstanceHasAddress(&instance, address),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
func testAccCheckComputeInstanceDestroy(s *terraform.State) error {
|
||||
config := testAccProvider.Meta().(*Config)
|
||||
|
||||
|
@ -528,6 +569,30 @@ func testAccCheckComputeInstanceHasSubnet(instance *compute.Instance) resource.T
|
|||
}
|
||||
}
|
||||
|
||||
func testAccCheckComputeInstanceHasAnyAddress(instance *compute.Instance) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
for _, i := range instance.NetworkInterfaces {
|
||||
if i.NetworkIP == "" {
|
||||
return fmt.Errorf("no address")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func testAccCheckComputeInstanceHasAddress(instance *compute.Instance, address string) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
for _, i := range instance.NetworkInterfaces {
|
||||
if i.NetworkIP != address {
|
||||
return fmt.Errorf("Wrong address found: expected %v, got %v", address, i.NetworkIP)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func testAccComputeInstance_basic_deprecated_network(instance string) string {
|
||||
return fmt.Sprintf(`
|
||||
resource "google_compute_instance" "foobar" {
|
||||
|
@ -880,3 +945,60 @@ func testAccComputeInstance_subnet_custom(instance string) string {
|
|||
|
||||
}`, acctest.RandString(10), acctest.RandString(10), instance)
|
||||
}
|
||||
|
||||
func testAccComputeInstance_address_auto(instance string) string {
|
||||
return fmt.Sprintf(`
|
||||
resource "google_compute_network" "inst-test-network" {
|
||||
name = "inst-test-network-%s"
|
||||
}
|
||||
resource "google_compute_subnetwork" "inst-test-subnetwork" {
|
||||
name = "inst-test-subnetwork-%s"
|
||||
ip_cidr_range = "10.0.0.0/16"
|
||||
region = "us-central1"
|
||||
network = "${google_compute_network.inst-test-network.self_link}"
|
||||
}
|
||||
resource "google_compute_instance" "foobar" {
|
||||
name = "%s"
|
||||
machine_type = "n1-standard-1"
|
||||
zone = "us-central1-a"
|
||||
|
||||
disk {
|
||||
image = "debian-7-wheezy-v20160301"
|
||||
}
|
||||
|
||||
network_interface {
|
||||
subnetwork = "${google_compute_subnetwork.inst-test-subnetwork.name}"
|
||||
access_config { }
|
||||
}
|
||||
|
||||
}`, acctest.RandString(10), acctest.RandString(10), instance)
|
||||
}
|
||||
|
||||
func testAccComputeInstance_address_custom(instance, address string) string {
|
||||
return fmt.Sprintf(`
|
||||
resource "google_compute_network" "inst-test-network" {
|
||||
name = "inst-test-network-%s"
|
||||
}
|
||||
resource "google_compute_subnetwork" "inst-test-subnetwork" {
|
||||
name = "inst-test-subnetwork-%s"
|
||||
ip_cidr_range = "10.0.0.0/16"
|
||||
region = "us-central1"
|
||||
network = "${google_compute_network.inst-test-network.self_link}"
|
||||
}
|
||||
resource "google_compute_instance" "foobar" {
|
||||
name = "%s"
|
||||
machine_type = "n1-standard-1"
|
||||
zone = "us-central1-a"
|
||||
|
||||
disk {
|
||||
image = "debian-7-wheezy-v20160301"
|
||||
}
|
||||
|
||||
network_interface {
|
||||
subnetwork = "${google_compute_subnetwork.inst-test-subnetwork.name}"
|
||||
address = "%s"
|
||||
access_config { }
|
||||
}
|
||||
|
||||
}`, acctest.RandString(10), acctest.RandString(10), instance, address)
|
||||
}
|
||||
|
|
|
@ -139,6 +139,9 @@ The `network_interface` block supports:
|
|||
to. The subnetwork must exist in the same region this instance will be
|
||||
created in. Either `network` or `subnetwork` must be provided.
|
||||
|
||||
* `address` - (Optional) The private IP address to assign to the instance. If
|
||||
empty, the address will be automatically assigned.
|
||||
|
||||
* `access_config` - (Optional) Access configurations, i.e. IPs via which this
|
||||
instance can be accessed via the Internet. Omit to ensure that the instance
|
||||
is not accessible from the Internet (this means that ssh provisioners will
|
||||
|
@ -189,7 +192,7 @@ exported:
|
|||
|
||||
* `tags_fingerprint` - The unique fingerprint of the tags.
|
||||
|
||||
* `network_interface.0.address` - The internal ip address of the instance (usually on the 10.x.x.x range).
|
||||
* `network_interface.0.address` - The internal ip address of the instance, either manually or dynamically assigned.
|
||||
|
||||
* `network_interface.0.access_config.0.assigned_nat_ip` - If the instance has an access config, either the given external ip (in the `nat_ip` field) or the ephemeral (generated) ip (if you didn't provide one).
|
||||
|
||||
|
|
Loading…
Reference in New Issue