reference
はじめに
前回の 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
当記事では、上記構築後に、上記環境を使用して構築を行うものとします。
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
基礎的な設定は以下
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 に割り当てます。
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"
}
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 を指定します。
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 をすることで回避をしています。
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"
}
}
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 として使用します。
この仕様は、正直直感的ではない気がしています。
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 にしています。
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 側での操作はできなそうです。
http_listener
上述の設定を関連付けていきます。
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
同様に、上述の設定を関連付けていきます。
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