VPS は DigitalOcean の Droplets が安いのでたまに利用しています。
Terraform は DigitalOcean に対応していて専用のプラグインが HashiCorp から提供されています。
Terraform 用の GitHub Actions も公開されていました。
GitHub - hashicorp/terraform-github-actions: Terraform GitHub Actions
Droplet は Web 画面をポチポチして作るのも簡単ですが、Terraform の勉強を兼ねて Actions で CI/CD することにしました。
Droplet を作る tf ファイル。5$ / mo のマシンを指定しています。DigitalOcean プロバイダーを定義しておくと、terraform init
実行時に必要なプラグインをダウンロードしてくれます。API トークンは環境変数 DIGITALOCEAN_TOKEN
に展開しておきます。
provider "digitalocean" { # export DIGITALOCEAN_TOKEN="Your API TOKEN" } data "digitalocean_ssh_key" "ssh_key" { name = "blink" } resource "digitalocean_droplet" "dev" { image = "${var.ubuntu}" name = "dev-01" region = "${var.do_sgp1}" size = "s-1vcpu-1gb" ssh_keys = [data.digitalocean_ssh_key.ssh_key.id] }
リージョンや OS は変数用の tf ファイルに書いて参照しています。
# Datacenter regions variable "do_sgp1" { description = "Digital Ocean Singapore Data Center 1" default = "sgp1" } # OS variable "ubuntu" { description = "Eoan Ermine" default = "ubuntu-19-10-x64" }
GitHub Actions のワークフロー定義。PR 作成時に tf ファイルを検証して plan を出力、レビューできるようにします。
各 step で terraform のサブコマンド、init
/ validate
/ plan
を実行しています。PR を編集するための GitHub アクセストークンと、DigitalOcean の API トークンは Secrets に格納して環境変数に渡しています。
name: Terraform Plan for droplet on: pull_request: types: [opened] jobs: terraform: name: 'Terraform' runs-on: ubuntu-latest steps: - name: 'Checkout' uses: actions/checkout@master - name: 'Terraform Init' uses: hashicorp/terraform-github-actions@master with: tf_actions_version: 0.12.15 tf_actions_subcommand: 'init' tf_actions_working_dir: 'droplet' tf_actions_comment: true env: GITHUB_TOKEN: ${{ secrets.GITHUB_TF_TOKEN }} DIGITALOCEAN_TOKEN: ${{ secrets.DIGITALOCEAN_TOKEN }} - name: 'Terraform Validate' uses: hashicorp/terraform-github-actions@master with: tf_actions_version: 0.12.15 tf_actions_subcommand: 'validate' tf_actions_working_dir: 'droplet' tf_actions_comment: true env: GITHUB_TOKEN: ${{ secrets.GITHUB_TF_TOKEN }} DIGITALOCEAN_TOKEN: ${{ secrets.DIGITALOCEAN_TOKEN }} - name: 'Terraform Plan' uses: hashicorp/terraform-github-actions@master with: tf_actions_version: 0.12.15 tf_actions_subcommand: 'plan' tf_actions_working_dir: 'droplet' tf_actions_comment: true env: GITHUB_TOKEN: ${{ secrets.GITHUB_TF_TOKEN }} DIGITALOCEAN_TOKEN: ${{ secrets.DIGITALOCEAN_TOKEN }}
この状態で branch を作成し tf ファイルを更新して PR を作成すると、ワークフローが実行され PR の画面で実行結果をレビューすることができます。
plan の結果も表示できます。
PR がマージされる時に実行するワークフローです。init
の後続でサブコマンド apply
を指定しているのと、PR がマージされたかどうか (github.event.pull_request.merged == true
) を判定する if を入れています。
name: Terraform Apply droplet on: pull_request: types: [closed] jobs: terraform: name: 'Terraform' runs-on: ubuntu-latest steps: - name: 'Checkout' uses: actions/checkout@master - name: 'Terraform Init' uses: hashicorp/terraform-github-actions@master with: tf_actions_version: 0.12.15 tf_actions_subcommand: 'init' tf_actions_working_dir: 'droplet' tf_actions_comment: true env: GITHUB_TOKEN: ${{ secrets.GITHUB_TF_TOKEN }} DIGITALOCEAN_TOKEN: ${{ secrets.DIGITALOCEAN_TOKEN }} - name: 'Terraform Apply' if: github.event.pull_request.merged == true uses: hashicorp/terraform-github-actions@master with: tf_actions_version: 0.12.15 tf_actions_subcommand: 'apply' tf_actions_working_dir: 'droplet' tf_actions_comment: true env: GITHUB_TOKEN: ${{ secrets.GITHUB_TF_TOKEN }} DIGITALOCEAN_TOKEN: ${{ secrets.DIGITALOCEAN_TOKEN }}
PR をマージするとワークフローが実行されました。
そして無事 Droplet が作成されました。
Infrastructure as Code に GitHub flow が融合したワークフローですね。
単体の Droplet 作成には羊頭狗肉感は否めませんが、業務で AWS の複雑な依存関係を持つリソースを Terraform で作っているような場合にはかなり役立ちそうです。
2020.06.10 追記)
この terraform-github-actions はかなり冗長な記述が必要でしたが、setup-terraform action がリリースされて簡潔に書けるようになりました。