# Net Address Reservation Module

This module allows reserving Compute Engine external, global, and internal addresses. The module also supports managing VPC network attachments from service projects.

<!-- BEGIN TOC -->
- [Examples](#examples)
  - [External and global addresses](#external-and-global-addresses)
  - [Internal addresses](#internal-addresses)
  - [IPv6 addresses](#ipv6-addresses)
  - [PSA addresses](#psa-addresses)
  - [PSC addresses](#psc-addresses)
  - [IPSec Interconnect addresses](#ipsec-interconnect-addresses)
  - [PSC Network Attachments](#psc-network-attachments)
  - [Use contexts](#use-contexts)
- [Variables](#variables)
- [Outputs](#outputs)
- [Fixtures](#fixtures)
<!-- END TOC -->

## Examples

### External and global addresses

```hcl
module "addresses" {
  source     = "./fabric/modules/net-address"
  project_id = var.project_id
  external_addresses = {
    one = { region = "europe-west1" }
    two = {
      region = "europe-west2"
      tier   = "STANDARD"
    }
  }
  global_addresses = {
    app-1 = {}
    app-2 = {}
  }
}
# tftest modules=1 resources=4 inventory=external.yaml e2e
```

### Internal addresses

```hcl
module "addresses" {
  source     = "./fabric/modules/net-address"
  project_id = var.project_id
  internal_addresses = {
    ilb-1 = {
      purpose    = "SHARED_LOADBALANCER_VIP"
      region     = var.region
      subnetwork = var.subnet.self_link
    }
    ilb-2 = {
      address    = "10.0.16.102"
      region     = var.region
      subnetwork = var.subnet.self_link
    }
  }
}
# tftest modules=1 resources=2 inventory=internal.yaml e2e
```

### IPv6 addresses

You can reserve both external and internal IPv6 addresses.

```hcl
module "addresses" {
  source     = "./fabric/modules/net-address"
  project_id = var.project_id
  external_addresses = {
    nlb = {
      region     = var.region
      subnetwork = module.vpc.subnets["${var.region}/ipv6-external"].self_link
      ipv6 = {
        endpoint_type = "NETLB"
      }
    }
  }
  internal_addresses = {
    vm = {
      ipv6       = {}
      region     = var.region
      subnetwork = module.vpc.subnets["${var.region}/ipv6-internal"].self_link
    }
  }
}
# tftest modules=2 resources=8 fixtures=fixtures/net-vpc-ipv6.tf inventory=ipv6.yaml e2e
```

### PSA addresses

```hcl
module "addresses" {
  source     = "./fabric/modules/net-address"
  project_id = var.project_id
  psa_addresses = {
    cloudsql-mysql = {
      address       = "10.10.10.0"
      network       = var.vpc.self_link
      prefix_length = 24
    }
  }
}
# tftest modules=1 resources=1 inventory=psa.yaml e2e
```

### PSC addresses

```hcl
module "addresses" {
  source     = "./fabric/modules/net-address"
  project_id = var.project_id
  psc_addresses = {
    one = {
      address = "10.0.0.32"
      network = var.vpc.self_link
    }
  }
}
# tftest modules=1 resources=1 inventory=psc.yaml e2e
```

To create PSC address targeting a service regional provider use the `service_attachment` property.

```hcl
module "addresses" {
  source     = "./fabric/modules/net-address"
  project_id = var.project_id
  psc_addresses = {
    cloudsql-one = {
      address          = "10.0.16.32"
      subnet_self_link = var.subnet.self_link
      region           = var.region
      service_attachment = {
        psc_service_attachment_link = module.cloudsql-instance.psc_service_attachment_link
      }
    }
  }
}
# tftest modules=2 resources=3 fixtures=fixtures/cloudsql-instance.tf inventory=psc-service-attachment.yaml e2e
```

Specify `vpc-sc` or `all-apis` in `psc_service_attachment_link` to targe Google APIs.

```hcl
module "addresses" {
  source     = "./fabric/modules/net-address"
  project_id = var.project_id
  psc_addresses = {
    googleapis = {
      address = "10.0.32.32"
      network = var.vpc.self_link
      service_attachment = {
        psc_service_attachment_link = "all-apis"
      }
    }
  }
}
# tftest modules=1 resources=2 inventory=psc-service-attachment-all-apis.yaml e2e
```

Set `global_access` to true to enable global access for regional addresses used by a service attachment.

```hcl
module "addresses" {
  source     = "./fabric/modules/net-address"
  project_id = var.project_id
  psc_addresses = {
    cloudsql-one = {
      address          = "10.0.16.32"
      subnet_self_link = var.subnet.self_link
      region           = var.region
      service_attachment = {
        psc_service_attachment_link = module.cloudsql-instance.psc_service_attachment_link
        global_access               = true
      }
    }
  }
}
# tftest modules=2 resources=3 fixtures=fixtures/cloudsql-instance.tf inventory=psc-global.yaml e2e
```

### IPSec Interconnect addresses

```hcl
module "addresses" {
  source     = "./fabric/modules/net-address"
  project_id = var.project_id
  ipsec_interconnect_addresses = {
    vpn-gw-range-1 = {
      address       = "10.255.255.0"
      region        = var.region
      network       = var.vpc.self_link
      prefix_length = 29
    }
    vpn-gw-range-2 = {
      address       = "10.255.255.8"
      region        = var.region
      network       = var.vpc.self_link
      prefix_length = 29
    }
  }
}
# tftest modules=1 resources=2 inventory=ipsec-interconnect.yaml e2e
```

### PSC Network Attachments

The project where the network attachment is created must be either the VPC project, or a Shared VPC service project of the host owning the VPC.

```hcl
module "addresses" {
  source     = "./fabric/modules/net-address"
  project_id = var.project_id
  network_attachments = {
    gce-0 = {
      region = "europe-west8"
      subnet_self_link = (
        "projects/net-host/regions/europe-west8/subnetworks/gce"
      )
      producer_accept_lists = [var.project_id]
    }
  }
}
# tftest modules=1 resources=1 inventory=network-attachments.yaml
```

### Use contexts

The module supports the contexts interpolation. For example:

```hcl
module "addresses" {
  source     = "./fabric/modules/net-address"
  project_id = "$project_ids:my-prj"
  context = {
    locations = {
      primary-region   = "us-central1"
      secondary-region = "europe-west1"
    }
    networks = {
      shared-vpc = "projects/prj-host/global/networks/shared-vpc"
    }
    project_ids = {
      my-prj = "my-project-1"
    }
    subnets = {
      subnet-primary   = "projects/prj-host/regions/us-central1/subnetworks/sub-1"
      subnet-secondary = "projects/prj-host/regions/europe-west1/subnetworks/sub-2"
    }
  }
  internal_addresses = {
    ilb-1 = {
      purpose    = "SHARED_LOADBALANCER_VIP"
      region     = "$locations:primary-region"
      subnetwork = "$subnets:subnet-primary"
    }
    ilb-2 = {
      address    = "10.0.16.102"
      region     = "$locations:secondary-region"
      subnetwork = "$subnets:subnet-secondary"
    }
  }
  psc_addresses = {
    one = {
      address = "10.0.0.32"
      network = "$networks:shared-vpc"
    }
  }
}
# tftest modules=1 resources=3 inventory=context.yaml
```
<!-- BEGIN TFDOC -->
## Variables

| name | description | type | required | default |
|---|---|:---:|:---:|:---:|
| [project_id](variables.tf#L106) | Project where the addresses will be created. | <code>string</code> | ✓ |  |
| [context](variables.tf#L17) | Context-specific interpolations. | <code>object&#40;&#123;&#8230;&#125;&#41;</code> |  | <code>&#123;&#125;</code> |
| [external_addresses](variables.tf#L29) | Map of external addresses, keyed by name. | <code>map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> |  | <code>&#123;&#125;</code> |
| [global_addresses](variables.tf#L55) | List of global addresses to create. | <code>map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> |  | <code>&#123;&#125;</code> |
| [internal_addresses](variables.tf#L65) | Map of internal addresses to create, keyed by name. | <code>map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> |  | <code>&#123;&#125;</code> |
| [ipsec_interconnect_addresses](variables.tf#L80) | Map of internal addresses used for HPA VPN over Cloud Interconnect. | <code>map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> |  | <code>&#123;&#125;</code> |
| [network_attachments](variables.tf#L93) | PSC network attachments, names as keys. | <code>map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> |  | <code>&#123;&#125;</code> |
| [psa_addresses](variables.tf#L111) | Map of internal addresses used for Private Service Access. | <code>map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> |  | <code>&#123;&#125;</code> |
| [psc_addresses](variables.tf#L123) | Map of internal addresses used for Private Service Connect. | <code>map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> |  | <code>&#123;&#125;</code> |

## Outputs

| name | description | sensitive |
|---|---|:---:|
| [external_addresses](outputs.tf#L17) | Allocated external addresses. |  |
| [global_addresses](outputs.tf#L25) | Allocated global external addresses. |  |
| [internal_addresses](outputs.tf#L33) | Allocated internal addresses. |  |
| [ipsec_interconnect_addresses](outputs.tf#L41) | Allocated internal addresses for HA VPN over Cloud Interconnect. |  |
| [network_attachment_ids](outputs.tf#L49) | IDs of network attachments. |  |
| [psa_addresses](outputs.tf#L57) | Allocated internal addresses for PSA endpoints. |  |
| [psc](outputs.tf#L65) | Allocated resources for PSC endpoints. |  |
| [psc_addresses](outputs.tf#L101) | Allocated internal addresses for PSC endpoints. |  |

## Fixtures

- [cloudsql-instance.tf](../../tests/fixtures/cloudsql-instance.tf)
- [net-vpc-ipv6.tf](../../tests/fixtures/net-vpc-ipv6.tf)
<!-- END TFDOC -->
