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

Add azuread auth to vnet gateway vpn client #8294

Merged
Merged
Show file tree
Hide file tree
Changes from 4 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
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,28 @@ func TestAccAzureRMVirtualNetworkGateway_vpnClientConfig(t *testing.T) {
})
}

func TestAccAzureRMVirtualNetworkGateway_vpnClientConfigAzureAdAuth(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_virtual_network_gateway", "test")

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acceptance.PreCheck(t) },
Providers: acceptance.SupportedProviders,
CheckDestroy: testCheckAzureRMVirtualNetworkGatewayDestroy,
Steps: []resource.TestStep{
{
Config: testAccAzureRMVirtualNetworkGateway_vpnClientConfigAzureAdAuth(data),
Check: resource.ComposeTestCheckFunc(
testCheckAzureRMVirtualNetworkGatewayExists(data.ResourceName),
resource.TestCheckResourceAttr(data.ResourceName, "vpn_client_configuration.0.aad_tenant", fmt.Sprintf("https://login.microsoftonline.com/%s/", data.Client().TenantID)),
resource.TestCheckResourceAttr(data.ResourceName, "vpn_client_configuration.0.aad_audience", "41b23e61-6c1e-4545-b367-cd054e0ed4b4"),
resource.TestCheckResourceAttr(data.ResourceName, "vpn_client_configuration.0.aad_issuer", fmt.Sprintf("https://sts.windows.net/%s/", data.Client().TenantID)),
resource.TestCheckResourceAttr(data.ResourceName, "vpn_client_configuration.0.vpn_client_protocols.#", "1"),
),
},
},
})
}

func TestAccAzureRMVirtualNetworkGateway_vpnClientConfigOpenVPN(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_virtual_network_gateway", "test")

Expand Down Expand Up @@ -625,6 +647,66 @@ resource "azurerm_virtual_network_gateway" "test" {
`, data.RandomInteger, data.Locations.Primary, data.RandomInteger, data.RandomInteger, data.RandomInteger)
}

func testAccAzureRMVirtualNetworkGateway_vpnClientConfigAzureAdAuth(data acceptance.TestData) string {
return fmt.Sprintf(`
provider "azurerm" {
features {}
}

resource "azurerm_resource_group" "test" {
name = "acctestRG-%d"
location = "%s"
}

resource "azurerm_virtual_network" "test" {
name = "acctestvn-%d"
location = azurerm_resource_group.test.location
resource_group_name = azurerm_resource_group.test.name
address_space = ["10.0.0.0/16"]
}

resource "azurerm_subnet" "test" {
name = "GatewaySubnet"
resource_group_name = azurerm_resource_group.test.name
virtual_network_name = azurerm_virtual_network.test.name
address_prefix = "10.0.1.0/24"
}

resource "azurerm_public_ip" "test" {
name = "acctestpip-%d"
location = azurerm_resource_group.test.location
resource_group_name = azurerm_resource_group.test.name
allocation_method = "Dynamic"
}

resource "azurerm_virtual_network_gateway" "test" {
depends_on = [azurerm_public_ip.test]
tombuildsstuff marked this conversation as resolved.
Show resolved Hide resolved
name = "acctestvng-%d"
location = azurerm_resource_group.test.location
resource_group_name = azurerm_resource_group.test.name

type = "Vpn"
vpn_type = "RouteBased"
sku = "VpnGw1"

ip_configuration {
public_ip_address_id = azurerm_public_ip.test.id
private_ip_address_allocation = "Dynamic"
subnet_id = azurerm_subnet.test.id
}

vpn_client_configuration {
address_space = ["10.2.0.0/24"]
vpn_client_protocols = ["OpenVPN"]

aad_tenant = "https://login.microsoftonline.com/%s/"
aad_audience = "41b23e61-6c1e-4545-b367-cd054e0ed4b4"
aad_issuer = "https://sts.windows.net/%s/"
}
}
`, data.RandomInteger, data.Locations.Primary, data.RandomInteger, data.RandomInteger, data.RandomInteger, data.Client().TenantID, data.Client().TenantID)
}

func testAccAzureRMVirtualNetworkGateway_vpnClientConfigOpenVPN(data acceptance.TestData) string {
return fmt.Sprintf(`
provider "azurerm" {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,21 @@ func dataSourceArmVirtualNetworkGateway() *schema.Resource {
},
},

"aad_tenant": {
Type: schema.TypeString,
Computed: true,
},

"aad_audience": {
Type: schema.TypeString,
Computed: true,
},

"aad_issuer": {
Type: schema.TypeString,
Computed: true,
},

"root_certificate": {
Type: schema.TypeList,
Computed: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,11 +171,45 @@ func resourceArmVirtualNetworkGateway() *schema.Resource {
},
},

"aad_tenant": {
Type: schema.TypeString,
Optional: true,
ConflictsWith: []string{
"vpn_client_configuration.0.radius_server_address",
"vpn_client_configuration.0.radius_server_secret",
"vpn_client_configuration.0.root_certificate",
"vpn_client_configuration.0.revoked_certificate",
},
},
"aad_audience": {
Type: schema.TypeString,
Optional: true,
ConflictsWith: []string{
"vpn_client_configuration.0.radius_server_address",
"vpn_client_configuration.0.radius_server_secret",
"vpn_client_configuration.0.root_certificate",
"vpn_client_configuration.0.revoked_certificate",
},
},
"aad_issuer": {
jon-walton marked this conversation as resolved.
Show resolved Hide resolved
Type: schema.TypeString,
Optional: true,
ConflictsWith: []string{
"vpn_client_configuration.0.radius_server_address",
"vpn_client_configuration.0.radius_server_secret",
"vpn_client_configuration.0.root_certificate",
"vpn_client_configuration.0.revoked_certificate",
},
},

"root_certificate": {
Type: schema.TypeSet,
Optional: true,

ConflictsWith: []string{
"vpn_client_configuration.0.aad_tenant",
"vpn_client_configuration.0.aad_audience",
"vpn_client_configuration.0.aad_issuer",
"vpn_client_configuration.0.radius_server_address",
"vpn_client_configuration.0.radius_server_secret",
},
Expand All @@ -198,6 +232,9 @@ func resourceArmVirtualNetworkGateway() *schema.Resource {
Type: schema.TypeSet,
Optional: true,
ConflictsWith: []string{
"vpn_client_configuration.0.aad_tenant",
"vpn_client_configuration.0.aad_audience",
"vpn_client_configuration.0.aad_issuer",
"vpn_client_configuration.0.radius_server_address",
"vpn_client_configuration.0.radius_server_secret",
},
Expand All @@ -220,6 +257,9 @@ func resourceArmVirtualNetworkGateway() *schema.Resource {
Type: schema.TypeString,
Optional: true,
ConflictsWith: []string{
"vpn_client_configuration.0.aad_tenant",
"vpn_client_configuration.0.aad_audience",
"vpn_client_configuration.0.aad_issuer",
"vpn_client_configuration.0.root_certificate",
"vpn_client_configuration.0.revoked_certificate",
},
Expand All @@ -230,6 +270,9 @@ func resourceArmVirtualNetworkGateway() *schema.Resource {
Type: schema.TypeString,
Optional: true,
ConflictsWith: []string{
"vpn_client_configuration.0.aad_tenant",
"vpn_client_configuration.0.aad_audience",
"vpn_client_configuration.0.aad_issuer",
"vpn_client_configuration.0.root_certificate",
"vpn_client_configuration.0.revoked_certificate",
},
Expand Down Expand Up @@ -559,6 +602,10 @@ func expandArmVirtualNetworkGatewayVpnClientConfig(d *schema.ResourceData) *netw
addresses = append(addresses, addr.(string))
}

confAadTenant := conf["aad_tenant"].(string)
confAadAudience := conf["aad_audience"].(string)
confAadIssuer := conf["aad_issuer"].(string)

var rootCerts []network.VpnClientRootCertificate
for _, rootCertSet := range conf["root_certificate"].(*schema.Set).List() {
rootCert := rootCertSet.(map[string]interface{})
Expand Down Expand Up @@ -600,6 +647,9 @@ func expandArmVirtualNetworkGatewayVpnClientConfig(d *schema.ResourceData) *netw
VpnClientAddressPool: &network.AddressSpace{
AddressPrefixes: &addresses,
},
AadTenant: &confAadTenant,
AadAudience: &confAadAudience,
AadIssuer: &confAadIssuer,
VpnClientRootCertificates: &rootCerts,
VpnClientRevokedCertificates: &revokedCerts,
VpnClientProtocols: &vpnClientProtocols,
Expand Down Expand Up @@ -683,6 +733,18 @@ func flattenArmVirtualNetworkGatewayVpnClientConfig(cfg *network.VpnClientConfig
flat["address_space"] = []interface{}{}
}

if v := cfg.AadTenant; v != nil {
flat["aad_tenant"] = *v
}

if v := cfg.AadAudience; v != nil {
flat["aad_audience"] = *v
}

if v := cfg.AadIssuer; v != nil {
flat["aad_issuer"] = *v
}

rootCerts := make([]interface{}, 0)
if certs := cfg.VpnClientRootCertificates; certs != nil {
for _, cert := range *certs {
Expand Down Expand Up @@ -830,6 +892,20 @@ func validateArmVirtualNetworkGatewayExpressRouteSku() schema.SchemaValidateFunc
func resourceArmVirtualNetworkGatewayCustomizeDiff(diff *schema.ResourceDiff, _ interface{}) error {
if vpnClient, ok := diff.GetOk("vpn_client_configuration"); ok {
if vpnClientConfig, ok := vpnClient.([]interface{})[0].(map[string]interface{}); ok {
hasAadTenant := vpnClientConfig["aad_tenant"] != ""
hasAadAudience := vpnClientConfig["aad_audience"] != ""
hasAadIssuer := vpnClientConfig["aad_issuer"] != ""

if hasAadTenant && (!hasAadAudience || !hasAadIssuer) {
return fmt.Errorf("if aad_tenant is set aad_audience and aad_issuer must also be set")
}
if hasAadAudience && (!hasAadTenant || !hasAadIssuer) {
return fmt.Errorf("if aad_audience is set aad_tenant and aad_issuer must also be set")
}
if hasAadIssuer && (!hasAadTenant || !hasAadAudience) {
return fmt.Errorf("if aad_issuer is set aad_tenant and aad_audience must also be set")
}

hasRadiusAddress := vpnClientConfig["radius_server_address"] != ""
hasRadiusSecret := vpnClientConfig["radius_server_secret"] != ""

Expand Down
23 changes: 21 additions & 2 deletions website/docs/d/virtual_network_gateway.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -79,18 +79,37 @@ The `vpn_client_configuration` block supports:
vpn clients will be taken. You can provide more than one address space, e.g.
in CIDR notation.

* `aad_tenant` - AzureAD Tenant URL
This setting is incompatible with the use of
`root_certificate` and `revoked_certificate`, `radius_server_address`, and `radius_server_secret`.

* `aad_audience` - The client id of the Azure VPN application.
See [Create an Active Directory (AD) tenant for P2S OpenVPN protocol connections](https://docs.microsoft.com/en-gb/azure/vpn-gateway/openvpn-azure-ad-tenant-multi-app) for values
This setting is incompatible with the use of
`root_certificate` and `revoked_certificate`, `radius_server_address`, and `radius_server_secret`.

* `aad_issuer` - The STS url for your tenant
This setting is incompatible with the use of
`root_certificate` and `revoked_certificate`, `radius_server_address`, and `radius_server_secret`.

* `root_certificate` - One or more `root_certificate` blocks which are
defined below. These root certificates are used to sign the client certificate
used by the VPN clients to connect to the gateway.
This setting is incompatible with the use of
`aad_tenant`, `aad_audience`, `aad_issuer`, `radius_server_address`, and `radius_server_secret`.

* `revoked_certificate` - One or more `revoked_certificate` blocks which
are defined below.
This setting is incompatible with the use of
`aad_tenant`, `aad_audience`, `aad_issuer`, `radius_server_address`, and `radius_server_secret`.

* `radius_server_address` - The address of the Radius server.
This setting is incompatible with the use of `root_certificate` and `revoked_certificate`.
This setting is incompatible with the use of
`aad_tenant`, `aad_audience`, `aad_issuer`, `root_certificate` and `revoked_certificate`.

* `radius_server_secret` - The secret used by the Radius server.
This setting is incompatible with the use of `root_certificate` and `revoked_certificate`.
This setting is incompatible with the use of
`aad_tenant`, `aad_audience`, `aad_issuer`, `root_certificate` and `revoked_certificate`.

* `vpn_client_protocols` - List of the protocols supported by the vpn client.
The supported values are `SSTP`, `IkeV2` and `OpenVPN`.
Expand Down
28 changes: 24 additions & 4 deletions website/docs/r/virtual_network_gateway.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -182,23 +182,43 @@ The `vpn_client_configuration` block supports:
* `address_space` - (Required) The address space out of which ip addresses for
vpn clients will be taken. You can provide more than one address space, e.g.
in CIDR notation.

* `aad_tenant` - (Optional) AzureAD Tenant URL
This setting is incompatible with the use of
`root_certificate` and `revoked_certificate`, `radius_server_address`, and `radius_server_secret`.

* `aad_audience` - (Optional) The client id of the Azure VPN application.
See [Create an Active Directory (AD) tenant for P2S OpenVPN protocol connections](https://docs.microsoft.com/en-gb/azure/vpn-gateway/openvpn-azure-ad-tenant-multi-app) for values
This setting is incompatible with the use of
`root_certificate` and `revoked_certificate`, `radius_server_address`, and `radius_server_secret`.

* `aad_issuer` - (Optional) The STS url for your tenant
jon-walton marked this conversation as resolved.
Show resolved Hide resolved
This setting is incompatible with the use of
`root_certificate` and `revoked_certificate`, `radius_server_address`, and `radius_server_secret`.

* `root_certificate` - (Optional) One or more `root_certificate` blocks which are
defined below. These root certificates are used to sign the client certificate
used by the VPN clients to connect to the gateway.
This setting is incompatible with the use of `radius_server_address` and `radius_server_secret`.
This setting is incompatible with the use of
`aad_tenant`, `aad_audience`, `aad_issuer`, `radius_server_address`, and `radius_server_secret`.

* `revoked_certificate` - (Optional) One or more `revoked_certificate` blocks which
are defined below.
This setting is incompatible with the use of `radius_server_address` and `radius_server_secret`.
This setting is incompatible with the use of
`aad_tenant`, `aad_audience`, `aad_issuer`, `radius_server_address`, and `radius_server_secret`.

* `radius_server_address` - (Optional) The address of the Radius server.
This setting is incompatible with the use of `root_certificate` and `revoked_certificate`.
This setting is incompatible with the use of
`aad_tenant`, `aad_audience`, `aad_issuer`, `root_certificate` and `revoked_certificate`.

* `radius_server_secret` - (Optional) The secret used by the Radius server.
This setting is incompatible with the use of `root_certificate` and `revoked_certificate`.
This setting is incompatible with the use of
`aad_tenant`, `aad_audience`, `aad_issuer`, `root_certificate` and `revoked_certificate`.

* `vpn_client_protocols` - (Optional) List of the protocols supported by the vpn client.
The supported values are `SSTP`, `IkeV2` and `OpenVPN`.
Values `SSTP` and `IkeV2` are incompatible with the use of
`aad_tenant`, `aad_audience` and `aad_issuer`.

The `bgp_settings` block supports:

Expand Down