Azure
Terraform
ApplicationGateway

Terraform を用いて Application Gateway を構築する


reference

https://qiita.com/moaikids/items/8a7b72f51662c3cb214d


はじめに

前回の SQL Database に引き続き、Application Gateway の構築を Terraform で行ってみます。

Application Gateway も設定項目が多く、Portal から手でポチポチ作成すると大変なので、Terraform などのツール経由で作成することをおすすめします。


構築シナリオ

今回は以下を構築・設定します。


  • PublicIP / PrivateIP を割り当てた Application Gateway を構築する

  • backend address pool には予めIPがわかっているサーバー2台をぶら下げる

  • backend IP に対する Prove を設定する

  • Cookie Affinity はオフにする等、HTTP Settings の設定を行う


設定


前提

以下の環境はすでに構築済みとします。


  • resource group

  • virtual network

  • subnet

当記事では、上記構築後に、上記環境を使用して構築を行うものとします。


main.tf

provider "azurerm" {

version = "~> 1.13.0"
}

resource "azurerm_resource_group" "rg" {
name = "${var.resource_group_name}"
location = "${var.location}"
}

resource "azurerm_virtual_network" "vnet" {
name = "${var.vnet_name}"
address_space = ["${var.ip_range}"]
location = "${azurerm_resource_group.rg.location}"
resource_group_name = "${azurerm_resource_group.rg.name}"
}

resource "azurerm_subnet" "subnet" {
name = "${var.subnet_name}"
resource_group_name = "${azurerm_resource_group.rg.name}"
virtual_network_name = "${azurerm_virtual_network.vnet.name}"
address_prefix = "${var.ip_subnet}"
}



basic

基礎的な設定は以下


main.tf

resource "azurerm_application_gateway" "ag" {

name = "${var.ag_name}"
resource_group_name = "${var.resource_group_name}"
location = "${var.location}"

sku {
name = "${var.ag_sku_name}"
tier = "${var.ag_sku_tier}"
capacity = "${var.ag_sku_capacity}"
}

gateway_ip_configuration {
name = "${var.ag_name}-ip-configuration"
subnet_id = "${data.azurerm_subscription.subscription.id}/resourceGroups/${var.resource_group_name}/providers/Microsoft.Network/virtualNetworks/${var.vnet_name}/subnets/${var.subnet_name}"
}

frontend_port {
name = "${var.ag_name}-frontend-port"
port = 80
}
}


SKU については補足します。


SKU の name と tier

それぞれ以下の内容を設定します。


  • name


    • Standard_Small

    • Standard_Medium

    • Standard_Large

    • WAF_Medium

    • WAF_Large



  • tier


    • Standard

    • WAF



機能として Standard か WAF 対応版にするかを tier で選択し、そのサイズについて name にて (tier)_(size) という記法で記述します。

tier で指定している内容を name でも指定するのは冗長に見えますが、このような仕組みになってます。


frontend_ip_configuration

Application Gateway においては、Public IP と Private IP 双方を同時に割り当てることができません。

なので要件に応じて、Public IP を割り当てるのか、Private IP を割り当てるのかを、事前に決定した上で設定に反映させる必要があります。


PublicIP

事前に、Public IP アドレスを生成する必要があります。生成した IP アドレスの情報を、frontend_ip_configuration に割り当てます。


main.tf

resource "azurerm_public_ip" "publicip" {

name = "${var.ag_name}-publicip"
location = "${var.location}"
resource_group_name = "${var.resource_group_name}"
public_ip_address_allocation = "dynamic"
}


main.tf

    frontend_ip_configuration {

name = "${var.ag_name}-frontend-ip"
public_ip_address_id = "${azurerm_public_ip.publicip.id}"
}


PrivateIP

Application Gateway のインターフェースを Private IP アドレスにする際は、Private IP の割当を行う Subnet を指定します。


main.tf

    frontend_ip_configuration {

name = "${var.ag_name}-frontend-ip"
subnet_id = "${data.azurerm_subscription.subscription.id}/resourceGroups/${var.resource_group_name}/providers/Microsoft.Network/virtualNetworks/${var.vnet_name}/subnets/${var.subnet_name}"
private_ip_address_allocation = "Dynamic"
}


backend_address_pool

backend_address_pool は複数割り当てができます。

ただし、以下の設定のように、Location ごとに設定を切り替えたい際に、Map の中に配列を入れることがうまくできないようです。

そのため、ここでの例では、カンマ区切りで複数IPアドレスをつなげた文字列として表現し、main.tf での呼び出し時に Split をすることで回避をしています。


variables.tf

variable "backend_address_pools" {

type = "map"
default = {
#ほんとうはこうしたい "japaneast" = ["127.0.0.1","127.0.0.2"]
"japaneast" = "127.0.0.1,127.0.0.2"
"japanwest" = "127.0.0.3"
}
}


main.tf

    backend_address_pool {

name = "${var.ag_name}-backend-pool"
ip_address_list = "${split(",", "${lookup(var.backend_address_pools,var.location)}")}"
}


probe

backend_pool に指定した個々のアドレスに対して共通の Health Check Endpoint を指定する場合は、127.0.0.1 にすると良いようです。

たとえば、backend_address_pool に A,B,C,D の4つのアドレスが指定されていても、host = 127.0.0.1 にしておくと、A,B,C,D それぞれ同じ path を Health Check Endpoint として使用します。

この仕様は、正直直感的ではない気がしています。


main.tf

    probe {

name = "127.0.0.1"
host = "127.0.0.1"
protocol = "Http"
path = "/health"
interval = 5
timeout = 30
unhealthy_threshold = 5
}


backend_http_settings

Application Gateway についての各種振る舞いについて設定をします。たとえば Cookie Affinity の有効無効についてもこちらで設定します。以下の例では Disabled にしています。


main.tf

    backend_http_settings {

name = "${var.ag_name}-http-settings"
cookie_based_affinity = "Disabled"
port = 80
protocol = "Http"
request_timeout = 30
probe_name = "127.0.0.1"
}


Application Gateway の Portal 経由だと Connection Draining の設定なども行えるようですが、現在 2018/09/07 現在では Terraform 側での操作はできなそうです。

https://github.com/terraform-providers/terraform-provider-azurerm/blob/26705da2d7ae310939e3155e51fd3e4aec6e65e2/azurerm/resource_arm_application_gateway.go#L265-L340


http_listener

上述の設定を関連付けていきます。


main.tf

    http_listener {

name = "${var.ag_name}-http-listener"
frontend_ip_configuration_name = "${var.ag_name}-frontend-ip"
frontend_port_name = "${var.ag_name}-frontend-port"
protocol = "Http"
}


request_routing_rule

同様に、上述の設定を関連付けていきます。


main.tf

    request_routing_rule {

name = "${var.ag_name}-rule"
rule_type = "Basic"
http_listener_name = "${var.ag_name}-http-listener"
backend_address_pool_name = "${var.ag_name}-backend-pool"
backend_http_settings_name = "${var.ag_name}-http-settings"
}


まとめ

上記のような形で、Terraform で Application Gateway の構築を行う事ができます。

手で作業すると面倒なことも、多くの部分が自動化できているのではないかと思います。

これ以外にもできることがありますので、詳しく知りたい方はドキュメントなどを参照してください。

https://www.terraform.io/docs/providers/azurerm/r/application_gateway.html