ociのロードバランサーのサーバ証明書を定期的に手作業で更新するのが面倒になってきたので、自動的に更新する方法を考えてみましたので備忘録としてメモします。certbotとterraformを使用しています。certbotを動かすサーバは、LBとは別のIPアドレスとなっています。ざっくりとした流れは以下となります。
- DNSのAレコードで設定しているIPアドレスをLBのものからcertbotが動作するサーバに切り替える
- certbotにより事前に取得済みの証明書を更新する
- DNSのAレコードのIPアドレスをLBのIPに戻す
- terraform destroyにより、ociに登録しているLBのリスナー、証明書を削除する
- 証明書のtfファイルに埋め込む証明書を更新した証明書に差し替え
- terraform applyにより、証明書、LBのリスナーを作成する
2についてはこちらが参考になりました。1,3はレコードの管理にCloudFlareを使用していますので、こちらを参考にAPIをたたいて実行しました。
terraformの証明書のリソースは以下のように作成しました。
resource "oci_load_balancer_certificate" "lb_certificate" {
#Required
certificate_name = var.certificate_certificate_name
load_balancer_id = var.load_balancer_id
#Optional
ca_certificate = "${file("./certs/chain.pem")}"
public_certificate = "${file("./certs/cert.pem")}"
private_key = "${file("./certs/privkey.pem")}"
lifecycle {
create_before_destroy = true
}
}
LBのリスナーは以下のように作成しました。
resource "oci_load_balancer_listener" "mylistener" {
default_backend_set_name = "mybackendset"
load_balancer_id = var.load_balancer_id
name = "mylistener"
port = 443
protocol = "HTTP"
hostname_names = [
"myserver",
]
ssl_configuration {
certificate_name = var.certificate_certificate_name
verify_depth = 1
verify_peer_certificate = false
}
}
terraformでdestroy, applyすると1回目は必ず失敗するので、スクリプトで実行する際にはリトライするようにしました。ociに登録した証明書をアップデートするやり方がわからなかったので、一回削除して作り直しているのですが、リスナーが証明書を参照しているのでリスナーも作り直すようにしています。そのため、結構更新に時間がかかってます。ociのCLIを使えばもっと無駄なくスマートにできるのかもしれませんが、terraformだとCLIの使い方を知らなくても使えるので楽でした。
ちなみに、リスナーのリソースを記述するtfファイルは、以下のコマンドで取り込んだものをtfファイルにそのままコピーして不要なものを削除する、という手順で作成しました。
terraform import oci_load_balancer_listener.mylistener "loadBalancers/ロードバランサーのID/listeners/mylistener"