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

Adding the Match parameter to the Probes to check on the response code #1446

Merged
merged 5 commits into from
Jun 28, 2018
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
55 changes: 55 additions & 0 deletions azurerm/resource_arm_application_gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,29 @@ func resourceArmApplicationGateway() *schema.Resource {
Type: schema.TypeInt,
Required: true,
},

"match": {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we also add documentation for this block?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added.

Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"body": {
Type: schema.TypeString,
Optional: true,
Default: "*",
},

"status_code": {
Type: schema.TypeList,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

given this is a status code, can we make this a TypeInt?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

People can specify status codes as ranges also like 200-300.

},
},
},
},
},
},
},
},
Expand Down Expand Up @@ -1162,6 +1185,22 @@ func expandApplicationGatewayProbes(d *schema.ResourceData) *[]network.Applicati
},
}

matchConfigs := data["match"].([]interface{})
if len(matchConfigs) > 0 {
match := matchConfigs[0].(map[string]interface{})
matchBody := match["body"].(string)

statusCodes := make([]string, 0)
for _, statusCode := range match["status_code"].([]interface{}) {
statusCodes = append(statusCodes, statusCode.(string))
}

setting.ApplicationGatewayProbePropertiesFormat.Match = &network.ApplicationGatewayProbeHealthResponseMatch{
Body: &matchBody,
StatusCodes: &statusCodes,
}
}

backendSettings = append(backendSettings, setting)
}

Expand Down Expand Up @@ -1608,6 +1647,22 @@ func flattenApplicationGatewayProbes(input *[]network.ApplicationGatewayProbe) [
if threshold := props.UnhealthyThreshold; threshold != nil {
settings["unhealthy_threshold"] = int(*threshold)
}

if match := props.Match; match != nil {
matchConfig := map[string]interface{}{}
if body := match.Body; body != nil {
matchConfig["body"] = *body
}

statusCodes := make([]interface{}, 0)
if match.StatusCodes != nil {
for _, status := range *match.StatusCodes {
statusCodes = append(statusCodes, status)
}
matchConfig["status_code"] = statusCodes
}
settings["match"] = matchConfig
}
}

result = append(result, settings)
Expand Down
254 changes: 254 additions & 0 deletions azurerm/resource_arm_application_gateway_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,32 @@ func TestAccAzureRMApplicationGateway_waf(t *testing.T) {
})
}

func TestAccAzureRMApplicationGateway_probeResponseMatch(t *testing.T) {
resourceName := "azurerm_application_gateway.test"
ri := acctest.RandInt()

subscriptionID := os.Getenv("ARM_SUBSCRIPTION_ID")
gwID := fmt.Sprintf(
"/subscriptions/%s/resourceGroups/acctestRG-%d/providers/Microsoft.Network/applicationGateways/acctestgw-%d",
subscriptionID, ri, ri)

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testCheckAzureRMApplicationGatewayDestroy,
Steps: []resource.TestStep{
{
Config: testAccAzureRMApplicationGateway_probeResponseMatch(ri, testLocation()),
Check: resource.ComposeTestCheckFunc(
testCheckAzureRMApplicationGatewayExists(resourceName),
testCheckAzureRMApplicationGatewayProbeResponseMatchAssigned(resourceName, "probe-1"),
resource.TestCheckResourceAttr(resourceName, "id", gwID),
),
},
},
})
}

func testCheckAzureRMApplicationGatewayExists(name string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[name]
Expand Down Expand Up @@ -325,6 +351,43 @@ func testCheckAzureRMApplicationGatewayAuthenticationCertificateAssigned(name st
}
}

func testCheckAzureRMApplicationGatewayProbeResponseMatchAssigned(name string, probeName string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[name]
if !ok {
return fmt.Errorf("Not found: %s", name)
}

gatewayName := rs.Primary.Attributes["name"]
resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"]
if !hasResourceGroup {
return fmt.Errorf("Bad: no resource group found in state for App Gateway: %q", gatewayName)
}

conn := testAccProvider.Meta().(*ArmClient).applicationGatewayClient
ctx := testAccProvider.Meta().(*ArmClient).StopContext

resp, err := conn.Get(ctx, resourceGroup, gatewayName)
if err != nil {
if utils.ResponseWasNotFound(resp.Response) {
return fmt.Errorf("Bad: App Gateway %q (resource group: %q) does not exist", gatewayName, resourceGroup)
}

return fmt.Errorf("Bad: Get on ApplicationGatewayClient: %+v", err)
}

for _, probe := range *resp.Probes {
if *probe.Name == probeName {
if match := probe.Match; match != nil {
return nil
}
}
}

return fmt.Errorf("Bad: Probe Response match was not found: %s", probeName)
}
}

func testCheckAzureRMApplicationGatewayDestroy(s *terraform.State) error {
conn := testAccProvider.Meta().(*ArmClient).applicationGatewayClient
ctx := testAccProvider.Meta().(*ArmClient).StopContext
Expand Down Expand Up @@ -1310,3 +1373,194 @@ resource "azurerm_application_gateway" "test" {
}
`, rInt, location, rInt, rInt, rInt, rInt)
}

func testAccAzureRMApplicationGateway_probeResponseMatch(rInt int, location string) string {
return fmt.Sprintf(`
resource "azurerm_resource_group" "test" {
name = "acctestRG-%d"
location = "%s"
}

resource "azurerm_virtual_network" "test" {
name = "acctest-vnet-%d"
resource_group_name = "${azurerm_resource_group.test.name}"
address_space = ["10.254.0.0/16"]
location = "${azurerm_resource_group.test.location}"
}

resource "azurerm_subnet" "test" {
name = "subnet-%d"
resource_group_name = "${azurerm_resource_group.test.name}"
virtual_network_name = "${azurerm_virtual_network.test.name}"
address_prefix = "10.254.0.0/24"
}

resource "azurerm_public_ip" "test" {
name = "acctest-pubip-%d"
location = "${azurerm_resource_group.test.location}"
resource_group_name = "${azurerm_resource_group.test.name}"
public_ip_address_allocation = "dynamic"
}

resource "azurerm_application_gateway" "test" {
name = "acctestgw-%d"
location = "${azurerm_resource_group.test.location}"
resource_group_name = "${azurerm_resource_group.test.name}"

sku {
name = "Standard_Medium"
tier = "Standard"
capacity = 1
}

disabled_ssl_protocols = [
"TLSv1_0",
]

gateway_ip_configuration {
# id = computed
name = "gw-ip-config1"
subnet_id = "${azurerm_subnet.test.id}"
}

frontend_ip_configuration {
# id = computed
name = "ip-config-public"
public_ip_address_id = "${azurerm_public_ip.test.id}"
}

frontend_ip_configuration {
# id = computed
name = "ip-config-private"
subnet_id = "${azurerm_subnet.test.id}"

# private_ip_address = computed
private_ip_address_allocation = "Dynamic"
}

frontend_port {
# id = computed
name = "port-8080"
port = 8080
}

backend_address_pool {
# id = computed
name = "pool-1"

fqdn_list = [
"terraform.io",
]
}

backend_http_settings {
# id = computed
name = "backend-http-1"
port = 8010
protocol = "Https"
cookie_based_affinity = "Enabled"
request_timeout = 30

# probe_id = computed
probe_name = "probe-1"
}

http_listener {
# id = computed
name = "listener-1"

# frontend_ip_configuration_id = computed
frontend_ip_configuration_name = "ip-config-public"

# frontend_ip_port_id = computed
frontend_port_name = "port-8080"
protocol = "Http"
}

http_listener {
name = "listener-2"
frontend_ip_configuration_name = "ip-config-public"
frontend_port_name = "port-8080"
protocol = "Https"

# ssl_certificate_id = computed
ssl_certificate_name = "ssl-1"
host_name = "terraform.io"
require_sni = true
}

probe {
# id = computed
name = "probe-1"
protocol = "Https"
path = "/test"
host = "azure.com"
timeout = 120
interval = 300
unhealthy_threshold = 8
match = {
body = "*"
status_code = [
"200",
"201",
"205-210",
]
}
}

url_path_map {
# id = computed
name = "path-map-1"
default_backend_address_pool_name = "pool-1"
default_backend_http_settings_name = "backend-http-1"

path_rule {
# id = computed
name = "path-rule-1"
backend_address_pool_name = "pool-1"
backend_http_settings_name = "backend-http-1"

paths = [
"/test",
]
}
}

request_routing_rule {
# id = computed
name = "rule-basic-1"
rule_type = "Basic"

# http_listener_id = computed
http_listener_name = "listener-1"

# backend_address_pool_id = computed
backend_address_pool_name = "pool-1"

# backend_http_settings_id = computed
backend_http_settings_name = "backend-http-1"
}

request_routing_rule {
# id = computed
name = "rule-path-1"
rule_type = "PathBasedRouting"
url_path_map_name = "path-map-1"

# http_listener_id = computed
http_listener_name = "listener-2"
}

ssl_certificate {
# id = computed
name = "ssl-1"
data = "${file("testdata/application_gateway_test.pfx")}"
password = "terraform"
}

tags {
environment = "tf01"
}
}
`, rInt, location, rInt, rInt, rInt, rInt)
}
5 changes: 5 additions & 0 deletions website/docs/r/application_gateway.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,11 @@ The `probe` block supports:

* `unhealthy_threshold` - (Required) Probe retry count. Backend server is marked down after consecutive probe failure count reaches UnhealthyThreshold. Minimum 1 second and Maximum 20.

* `match` - (Optional) Probe health response match.

* `body` - (Optional) Body that must be contained in the health response. Defaults to "*"
* `status_code` - (Optional) Allowed health response status codes.

The `request_routing_rule` block supports:

* `name` - (Required) User defined name for a request routing rule.
Expand Down