【さくらのクラウド】エンハンスドロードバランサとTerraform ACMEプロバイダでHTTPS環境を作る

さくらのクラウドに「エンハンスドロードバランサ」というhttp/httpsに特化した新しいロードバランサアプライアンスが追加されました。

cloud-news.sakura.ad.jp

また、タイミングが良いことにTerraformのAMCEプロバイダーでさくらのクラウドDNSを利用できるようになるバージョン v1.1.0も先日リリースされました。

www.terraform.io

今回はTerraform+AMCEプロバイダーを利用してさくらのクラウドのエンハンスドロードバランサでHTTPS環境を作ってみます。

エンハンスドロードバランサとは

エンハンスドロードバランサについてはこちらに詳細がまとめられています。

manual.sakura.ad.jp

振り分け先にはさくらインターネットの提供するグローバルIPアドレスが指定可能ということですので、 クラウドだけでなくVPSや専用サーバもOKということになります。 (ちょっと確認できてないですが、プランによってはレンタルサーバでもOKじゃないかと思います)

また、証明書を登録しておけばSSL終端も可能です。

エンハンスドロードバランサの注意点

実サーバにはグローバルIPが必要なため、例えばVPC内へのアクセスするためのゲートウェイとして利用するといったことはできませんのでその辺は注意です。

また、現時点ではパスベースのルーティングはできません。

プレスリリースには

また今後、DDoS対策、リクエストURLパス単位のルーティング、ユーザー定義のパケットフィルタなどの機能を実装していく予定です。

とありますので今後対応予定はあるようですね。期待してます。

TerraformのACMEプロバイダのさくらのクラウド対応

先日ACMEプロバイダー v1.1.0がリリースされました。
このプロバイダーは内部でlegoというライブラリを使っており、このlegoさくらのクラウドに対応しています(させた)。
このためACMEプロバイダーで利用するlegoをバージョンアップするPullRequestを半年ほど前に送っていたのですが最近になってようやくマージされ、 この度無事にそれらを含むバージョンとしてv1.1.0がリリースされました。長かった。。。

Terraform v0.12で構築してみる

ということで早速これらを用いてエンハンスドロードバランサを構築してみます。

なお、今回は現在βテスト中であるTerraform v0.12を利用します。
Terraform for さくらのクラウドではv0.12対応を進めており、エンハンスドロードバランサはv0.12以降向けブランチでのみサポートする予定だからです。

必要なもの/準備

※Terraform v0.12ではまだOfficialプロバイダーでもTerraform v0.12対応版のリリースがされていないものがあるため、 terraform initを実行してもエラーとなるケースがあります。 このため現在は各プロバイダーのスナップショット版をダウンロードして~/.terraform.d/plugins配下などに配置しておく必要があります。

また、さくらのクラウド APIキーについては以下のように環境変数に設定しておいてください。

export SAKURACLOUD_ACCESS_TOKEN=アクセストークン
export SAKURACLOUD_ACCESS_TOKEN_SECRET=シークレット

実サーバは(さくらの)グローバルIPを持ちhttpでアクセスできるものを用意しておきます。
もしお持ちでない場合は適当にサーバを作成してdocker run -d -p 80:80 nginx:latestなどとでもして用意しておきましょう。

作成

tfファイルは以下のようになります。variablesを適当に設定してください。

# ホスト名(Let's Encryptで証明書を取得する際に利用)
variable common_name {
  default = "www"
}

# ドメイン名(さくらのクラウドDNSに登録したゾーン名)
variable target_domain {
  default = "example.com"
}

# 実サーバのIPアドレスのリスト
variable servers {
  type    = list(string)
  default = ["192.2.0.1"]
}

locals {
  fqdn = format("%s.%s", var.common_name, var.target_domain)
}


# エンハンスドロードバランサの作成
resource "sakuracloud_proxylb" "foobar" {
  name = "terraform-test-proxylb-import"
  health_check {
    protocol   = "http"
    path       = "/"
    delay_loop = 20
  }
  bind_ports {
    proxy_mode = "https"
    port       = 443
  }

  # v0.12以降で使えるdynamicを利用
  dynamic servers {
    for_each = var.servers
    content {
      ipaddress = servers.value
      port      = 80
    }
  }

  certificate {
    server_cert       = acme_certificate.cert.certificate_pem
    private_key       = acme_certificate.cert.private_key_pem
    intermediate_cert = acme_certificate.cert.issuer_pem
  }
}

# さくらのクラウド DNS(エンハンスドロードバランサに割り当てられるVIPに対しAレコード登録)
data sakuracloud_dns "zone" {
  name_selectors = [var.target_domain]
}

resource sakuracloud_dns_record "record" {
  dns_id = data.sakuracloud_dns.zone.id
  name   = var.common_name
  type   = "A"
  value  = sakuracloud_proxylb.foobar.vip
}

# ACMEプロバイダーでLet's Encrypt証明書取得
provider "acme" {
  server_url = "https://acme-staging-v02.api.letsencrypt.org/directory" # ステージング環境用
}

resource "tls_private_key" "private_key" {
  algorithm = "RSA"
}

resource "acme_registration" "reg" {
  account_key_pem = tls_private_key.private_key.private_key_pem
  email_address   = "your-mail-address@example.com"
}

resource "acme_certificate" "cert" {
  account_key_pem = acme_registration.reg.account_key_pem
  common_name     = local.fqdn

  dns_challenge {
    provider = "sakuracloud"
  }
}

AMCEプロバイダーでdns_challengeprovider="sakuracloud"を指定することで、さくらのクラウドDNSを用いてLet's Encryptで証明書を取得してくれます。
環境変数さくらのクラウドAPIキーを設定しておけばそれを利用するようになっています。
(もちろんtfファイル上で明示することも可能)

あとはterraform applyすれば証明書取得やエンハンスドロードバランサに向けたDNSレコードの登録が行われます。 その後指定したFQDN(この例だとwww.example.com)にHTTPSでアクセスできるようになるはずです。

終わりに

パスベースのルーティング待ってます!!!

以上です。