Skip to content

Commit 1eb129a

Browse files
committed
provider/azure: added local network gateway resource
1 parent 6017d0b commit 1eb129a

5 files changed

Lines changed: 322 additions & 4 deletions

File tree

builtin/providers/azurerm/provider.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,9 @@ func Provider() terraform.ResourceProvider {
3737
},
3838

3939
ResourcesMap: map[string]*schema.Resource{
40-
"azurerm_resource_group": resourceArmResourceGroup(),
41-
"azurerm_virtual_network": resourceArmVirtualNetwork(),
40+
"azurerm_resource_group": resourceArmResourceGroup(),
41+
"azurerm_virtual_network": resourceArmVirtualNetwork(),
42+
"azurerm_local_network_gateway": resourceArmLocalNetworkGateway(),
4243
},
4344

4445
ConfigureFunc: providerConfigure,
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
package azurerm
2+
3+
import (
4+
"fmt"
5+
"log"
6+
7+
"github.com/Azure/azure-sdk-for-go/arm/network"
8+
"github.com/Azure/azure-sdk-for-go/core/http"
9+
"github.com/hashicorp/terraform/helper/schema"
10+
)
11+
12+
// resourceArmLocalNetworkGateway returns the schema.Resource
13+
// associated to an Azure local network gateway.
14+
func resourceArmLocalNetworkGateway() *schema.Resource {
15+
return &schema.Resource{
16+
Create: resourceArmLocalNetworkGatewayCreate,
17+
Read: resourceArmLocalNetworkGatewayRead,
18+
Update: resourceArmLocalNetworkGatewayUpdate,
19+
Delete: resourceArmLocalNetworkGatewayDelete,
20+
21+
Schema: map[string]*schema.Schema{
22+
"name": &schema.Schema{
23+
Type: schema.TypeString,
24+
Required: true,
25+
ForceNew: true,
26+
},
27+
28+
"location": &schema.Schema{
29+
Type: schema.TypeString,
30+
Optional: true,
31+
ForceNew: true,
32+
StateFunc: azureRMNormalizeLocation,
33+
},
34+
35+
"resource_group_name": &schema.Schema{
36+
Type: schema.TypeString,
37+
Optional: true,
38+
ForceNew: true,
39+
},
40+
41+
"resource_guid": &schema.Schema{
42+
Type: schema.TypeString,
43+
Optional: true,
44+
},
45+
46+
"gateway_address": &schema.Schema{
47+
Type: schema.TypeString,
48+
Required: true,
49+
},
50+
51+
"address_space": &schema.Schema{
52+
Type: schema.TypeList,
53+
Required: true,
54+
Elem: &schema.Schema{
55+
Type: schema.TypeString,
56+
},
57+
},
58+
},
59+
}
60+
}
61+
62+
// resourceArmLocalNetworkGatewayCreate goes ahead and creates the specified ARM local network gateway.
63+
func resourceArmLocalNetworkGatewayCreate(d *schema.ResourceData, meta interface{}) error {
64+
lnetClient := meta.(*ArmClient).localNetConnClient
65+
66+
name := d.Get("name").(string)
67+
location := d.Get("location").(string)
68+
resGroup := d.Get("resource_group_name").(string)
69+
ipAddress := d.Get("gateway_address").(string)
70+
71+
// NOTE: due to the including-but-different relationship between the ASM
72+
// and ARM APIs, one may set the following local network gateway type to
73+
// "Classic" and basically get an old ASM local network connection through
74+
// the ARM API. This functionality is redundant with respect to the old
75+
// ASM-based implementation which we already have, so we just use the
76+
// new Resource Manager APIs here:
77+
typ := "Resource Manager"
78+
79+
// fetch the 'address_space_prefix'es:
80+
prefixes := []string{}
81+
for _, pref := range d.Get("addres_space").([]interface{}) {
82+
prefixes = append(prefixes, pref.(string))
83+
}
84+
85+
// NOTE: result ignored here; review below...
86+
resp, err := lnetClient.CreateOrUpdate(resGroup, name, network.LocalNetworkGateway{
87+
Name: &name,
88+
Location: &location,
89+
Type: &typ,
90+
Properties: &network.LocalNetworkGatewayPropertiesFormat{
91+
LocalNetworkAddressSpace: &network.AddressSpace{
92+
AddressPrefixes: &prefixes,
93+
},
94+
GatewayIPAddress: &ipAddress,
95+
},
96+
})
97+
if err != nil {
98+
return fmt.Errorf("Error reading the state of Azure ARM Local Network Gateway '%s': %s", name, err)
99+
}
100+
101+
// NOTE: we either call read here or basically repeat the reading process
102+
// with the ignored network.LocalNetworkGateway result of the above:
103+
d.SetId(*resp.ID)
104+
return resourceArmLocalNetworkGatewayRead(d, meta)
105+
}
106+
107+
// resourceArmLocalNetworkGatewayRead goes ahead and reads the state of the corresponding ARM local network gateway.
108+
func resourceArmLocalNetworkGatewayRead(d *schema.ResourceData, meta interface{}) error {
109+
lnetClient := meta.(*ArmClient).localNetConnClient
110+
111+
name := d.Get("name").(string)
112+
resGroup := d.Get("resource_group_name").(string)
113+
114+
log.Printf("[INFO] Sending GET request to Azure ARM for local network gateway '%s'.", name)
115+
lnet, err := lnetClient.Get(resGroup, name)
116+
if lnet.StatusCode == http.StatusNotFound {
117+
// it means that the resource has been deleted in the meantime...
118+
d.SetId("")
119+
return nil
120+
}
121+
if err != nil {
122+
return fmt.Errorf("Error reading the state of Azure ARM local network gateway '%s': %s", name, err)
123+
}
124+
125+
d.Set("resource_guid", *lnet.Properties.ResourceGUID)
126+
d.Set("gateway_address", *lnet.Properties.GatewayIPAddress)
127+
128+
prefs := []string{}
129+
if ps := *lnet.Properties.LocalNetworkAddressSpace.AddressPrefixes; ps != nil {
130+
prefs = ps
131+
}
132+
d.Set("address_space", prefs)
133+
134+
return nil
135+
}
136+
137+
// resourceArmLocalNetworkGatewayUpdate goes ahead and updates the corresponding ARM local network gateway.
138+
func resourceArmLocalNetworkGatewayUpdate(d *schema.ResourceData, meta interface{}) error {
139+
// NOTE: considering the idempotency, we can safely call create again on
140+
// update. This has been written out in order to ensure clarity,
141+
return resourceArmLocalNetworkGatewayCreate(d, meta)
142+
}
143+
144+
// resourceArmLocalNetworkGatewayDelete deletes the specified ARM local network gateway.
145+
func resourceArmLocalNetworkGatewayDelete(d *schema.ResourceData, meta interface{}) error {
146+
lnetClient := meta.(*ArmClient).localNetConnClient
147+
148+
name := d.Get("name").(string)
149+
resGroup := d.Get("resource_group_name").(string)
150+
151+
log.Printf("[INFO] Sending Azure ARM delete request for local network gateway '%s'.", name)
152+
_, err := lnetClient.Delete(resGroup, name)
153+
if err != nil {
154+
return fmt.Errorf("Error issuing Azure ARM delete request of local network gateway '%s': %s", name, err)
155+
}
156+
157+
return nil
158+
}
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
package azurerm
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
"github.com/Azure/azure-sdk-for-go/core/http"
8+
"github.com/hashicorp/terraform/helper/resource"
9+
"github.com/hashicorp/terraform/terraform"
10+
)
11+
12+
func TestAccAzureRMLocalNetworkGateway_basic(t *testing.T) {
13+
name := "azurerm_local_network_gateway.test"
14+
15+
resource.Test(t, resource.TestCase{
16+
PreCheck: func() { testAccPreCheck(t) },
17+
Providers: testAccProviders,
18+
CheckDestroy: testCheckAzureRMLocalNetworkGatewayDestroy,
19+
Steps: []resource.TestStep{
20+
resource.TestStep{
21+
Config: testAccAzureRMLocalNetworkGatewayConfig_basic,
22+
Check: resource.ComposeTestCheckFunc(
23+
testCheckAzureRMLocalNetworkGatewayExists(name),
24+
resource.TestCheckResourceAttr(name, "gateway_address", "127.0.0.1"),
25+
resource.TestCheckResourceAttr(name, "address_space.0", "127.0.0.0/8"),
26+
),
27+
},
28+
},
29+
})
30+
}
31+
32+
// testCheckAzureRMLocalNetworkGatewayExists returns the resurce.TestCheckFunc
33+
// which checks whether or not the expected local network gateway exists both
34+
// in the schema, and on Azure.
35+
func testCheckAzureRMLocalNetworkGatewayExists(name string) resource.TestCheckFunc {
36+
return func(s *terraform.State) error {
37+
// first check within the schema for the local network gateway:
38+
res, ok := s.RootModule().Resources[name]
39+
if !ok {
40+
return fmt.Errorf("Local network gateway '%s' not found.", name)
41+
}
42+
43+
// then, extranct the name and the resource group:
44+
localNetName := res.Primary.Attributes["name"]
45+
resGrp, hasResGrp := res.Primary.Attributes["resource_group_name"]
46+
if !hasResGrp {
47+
return fmt.Errorf("Local network gateway '%s' has no resource group set.", name)
48+
}
49+
50+
// and finally, check that it exists on Azure:
51+
lnetClient := testAccProvider.Meta().(*ArmClient).localNetConnClient
52+
53+
resp, err := lnetClient.Get(resGrp, name)
54+
if resp.StatusCode == http.StatusNotFound {
55+
return fmt.Errorf("Local network gateway '%s' (resource group '%s') does not exist on Azure.", localNetName, resGrp)
56+
}
57+
58+
if err != nil {
59+
return fmt.Errorf("Error reading the state of local network gateway '%s'.", localNetName)
60+
}
61+
62+
return nil
63+
}
64+
}
65+
66+
// testCheckAzureRMLocalNetworkGatewayDestroy is the resurce.TestCheckFunc
67+
// which checks whether or not the expected local network gateway still
68+
// exists on Azure.
69+
func testCheckAzureRMLocalNetworkGatewayDestroy(s *terraform.State) error {
70+
for _, rs := range s.RootModule().Resources {
71+
if rs.Type != "azurerm_local_network_gateway" {
72+
continue
73+
}
74+
75+
name := rs.Primary.Attributes["name"]
76+
resourceGroup := rs.Primary.Attributes["resource_group_name"]
77+
78+
lnetClient := testAccProvider.Meta().(*ArmClient).localNetConnClient
79+
resp, err := lnetClient.Get(resourceGroup, name)
80+
81+
if err != nil {
82+
return nil
83+
}
84+
85+
if resp.StatusCode != http.StatusNotFound {
86+
return fmt.Errorf("Local network gateway still exists:\n%#v", resp.Properties)
87+
}
88+
}
89+
90+
return nil
91+
}
92+
93+
var testAccAzureRMLocalNetworkGatewayConfig_basic = `
94+
resource "azurerm_resource_group" "test" {
95+
name = "tftestingResourceGroup"
96+
location = "West US"
97+
}
98+
99+
resource "azurerm_local_network_gateway" "test" {
100+
name = "tftestingLocalNetworkGateway"
101+
location = "${azurerm_resource_group.test.location}"
102+
resource_group_name = "${azurerm_resource_group.test.name}"
103+
gateway_address = "127.0.0.1"
104+
address_space = ["127.0.0.0/8"]
105+
}
106+
`
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
---
2+
layout: "azurerm"
3+
page_title: "Azure Resource Manager: azurerm_local_network_gateway"
4+
sidebar_current: "docs-azurerm-resource-local-network-gateway"
5+
description: |-
6+
Creates a new local network gateway connection over which specific connections can be configured.
7+
---
8+
9+
# azurerm\_local\_network\_gateway
10+
11+
Creates a new local network gateway connection over which specific connections can be configured.
12+
13+
## Example Usage
14+
15+
```
16+
resource "azurerm_local_network_gateway" "home" {
17+
name = "backHome"
18+
resource_group_name = "${azurerm_resource_group.test.name}"
19+
location = "${azurerm_resource_group.test.location}"
20+
gateway_address = "12.13.14.15"
21+
address_space = ["10.0.0.0/16"]
22+
}
23+
```
24+
25+
## Argument Reference
26+
27+
The following arguments are supported:
28+
29+
* `name` - (Required) The name of the local network gateway. Changing this
30+
forces a new resource to be created.
31+
32+
* `resource_group_name` - (Required) The name of the resource group in which to
33+
create the local network gateway.
34+
35+
* `location` - (Required) The location/region where the local network gatway is
36+
created. Changing this forces a new resource to be created.
37+
38+
* `gateway_address` - (Required) The IP address of the gatway to which to
39+
connect.
40+
41+
* `address_space` - (Required) The list of string CIDRs representing the
42+
addredss spaces the gateway exposes.
43+
44+
## Attributes Reference
45+
46+
The following attributes are exported:
47+
48+
* `id` - The local network gateway unique ID within Azure.

website/source/layouts/azurerm.erb

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,18 @@
1313
<li<%= sidebar_current(/^docs-azurerm-resource/) %>>
1414
<a href="#">Resources</a>
1515
<ul class="nav nav-visible">
16-
<li<%= sidebar_current("docs-azure-resource-resource-group") %>>
16+
<li<%= sidebar_current("docs-azurerm-resource-resource-group") %>>
1717
<a href="/docs/providers/azurerm/r/resource_group.html">azurerm_resource_group</a>
1818
</li>
1919

20-
<li<%= sidebar_current("docs-azure-resource-virtual-network") %>>
20+
<li<%= sidebar_current("docs-azurerm-resource-virtual-network") %>>
2121
<a href="/docs/providers/azurerm/r/virtual_network.html">azurerm_virtual_network</a>
2222
</li>
23+
24+
<li<%= sidebar_current("docs-azurerm-resource-local-network-gateway") %>>
25+
<a href="/docs/providers/azurerm/r/local_network_gateway.html">azurerm_local_network_gateway</a>
26+
</li>
27+
2328
</ul>
2429
</li>
2530
</ul>

0 commit comments

Comments
 (0)