はじめに
Herokuで実際にアプリケーションを運用していると機能の追加に伴って環境変数を追加したり、アドオンを追加したりすることがあると思います。
そして、これらは手作業で行うことが多いです。ごく少人数で開発しているときはそれでもなんとかなるのですが、開発者が増えたり、開発者のレベルにばらつきが出てくるとコードで管理してリリースする前にレビューを行いたいと思うようになってきました。
現在developer previewで公開されているheroku.ymlというマニフェストファイル的な機能がゆくゆくはそういうものになっていってほしいなあと個人的に考えているのですが、現状はどちらかというとアプリケーションのbuildをシンプルに記述できるようにするのが目的のようなので、本番環境で参照する環境変数を管理したり、アドオンを管理したりする機能はありません。となると、現状で私のニーズを満たしてくれる最有力候補はTerraformになりそうです。
前置きが長くなりましたが、Terraformを試してみたいと思います。
今回のゴール
- Terraformを利用して新規にHerokuアプリケーションをセットアップしてみる。
実際にやってみる
前提
- 開発環境はMacです。
- すでにHerokuのアカウントは開設済みで
heroku login
済みとします。
Terraformのインストール
- Homebrewを利用します。
brew install terraform
tfファイルを書く
- アプリケーションとheroku-postgresqを用意するだけのシンプルなものです。
variable "heroku_api_key" {}
provider "heroku" {
email = "your.email@example.com"
api_key = "${var.heroku_api_key}"
}
resource "heroku_app" "default" {
name = "sugai-tf-test"
region = "us"
}
resource "heroku_addon" "database" {
app = "${heroku_app.default.name}"
plan = "heroku-postgresql:hobby-dev"
}
初期化
- いろいろ調べていると
terraform plan
がdry run(試しに実行してリソースへの変更は加えない)でterraform apply
が実際に変更を適用する、ということを知りました。 - というわけで上記のファイルを用意した段階で
terraform plan
してみたところ下記のようなメッセージが。
$ terraform plan
Plugin reinitialization required. Please run "terraform init".
Reason: Could not satisfy plugin requirements.
Plugins are external binaries that Terraform uses to access and manipulate
resources. The configuration provided requires plugins which can't be located,
don't satisfy the version constraints, or are otherwise incompatible.
1 error(s) occurred:
* provider.heroku: no suitable version installed
version requirements: "(any version)"
versions installed: none
Terraform automatically discovers provider requirements from your
configuration, including providers used in child modules. To see the
requirements and constraints from each module, run "terraform providers".
Error: error satisfying plugin requirements
- どうやら
terraform init
で初期化する必要があるようです。 - ドキュメントにも書いてありました。
- というわけで
terraform init
してみます。
$ terraform init
Initializing provider plugins...
- Checking for available provider plugins on https://releases.hashicorp.com...
- Downloading plugin for provider "heroku" (0.1.2)...
The following providers do not have any version constraints in configuration,
so the latest version was installed.
To prevent automatic upgrades to new major versions that may contain breaking
changes, it is recommended to add version = "..." constraints to the
corresponding provider blocks in configuration, with the constraint strings
suggested below.
* provider.heroku: version = "~> 0.1"
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
- 問題なさそうですね。
次にterraform planしてみる
- 初期化ができたので続いて
terraform plan
してみます。
$ terraform plan
var.heroku_api_key
Enter a value: xxxxxxxxxxxxxxx
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.
------------------------------------------------------------------------
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
+ heroku_addon.database
id: <computed>
app: "sugai-tf-test"
config_vars.#: <computed>
name: <computed>
plan: "heroku-postgresql:hobby-dev"
provider_id: <computed>
+ heroku_app.default
id: <computed>
all_config_vars.%: <computed>
config_vars.#: <computed>
git_url: <computed>
heroku_hostname: <computed>
name: "sugai-tf-test"
region: "us"
stack: <computed>
web_url: <computed>
Plan: 2 to add, 0 to change, 0 to destroy.
------------------------------------------------------------------------
Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.
- なお、HerokuのAPIキーは下記のコマンドで取得できます。
heroku auth:token
最後にterraform applyする
- 特に問題なさそうなのでいよいよ
terraform apply
を実行します。
$ terraform apply
var.heroku_api_key
Enter a value: xxxxxxxxxxx
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
+ heroku_addon.database
id: <computed>
app: "sugai-tf-test"
config_vars.#: <computed>
name: <computed>
plan: "heroku-postgresql:hobby-dev"
provider_id: <computed>
+ heroku_app.default
id: <computed>
all_config_vars.%: <computed>
config_vars.#: <computed>
git_url: <computed>
heroku_hostname: <computed>
name: "sugai-tf-test"
region: "us"
stack: <computed>
web_url: <computed>
Plan: 2 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
heroku_app.default: Creating...
all_config_vars.%: "" => "<computed>"
config_vars.#: "" => "<computed>"
git_url: "" => "<computed>"
heroku_hostname: "" => "<computed>"
name: "" => "sugai-tf-test"
region: "" => "us"
stack: "" => "<computed>"
web_url: "" => "<computed>"
heroku_app.default: Creation complete after 2s (ID: sugai-tf-test)
heroku_addon.database: Creating...
app: "" => "sugai-tf-test"
config_vars.#: "" => "<computed>"
name: "" => "<computed>"
plan: "" => "heroku-postgresql:hobby-dev"
provider_id: "" => "<computed>"
heroku_addon.database: Creation complete after 2s (ID: 88eaebdb-4b52-4b0e-853a-6fef33b70012)
Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
- 途中で「ほんとに実行して良い?」と聞かれるのでyesと入力すると変更が適用されます。
- Herokuの管理画面で見てみると、たしかに新規のアプリケーションが作成されています。簡単。
おわりに
驚くほど簡単にTerraformを使って新たにHerokuアプリケーションを立ち上げることができました。
ごくシンプルなアプリケーションの雛形だということもあるとは思いますが、それでも拍子抜けするくらい簡単でした。
ただこういうツールって既存の稼働中のプロジェクトに導入して実際に運用してみる中で得られる知見に価値があるのかなと思うので、近いうちに個人で運用しているHerokuアプリケーションで試してみたいと思います。
参考
- Provider: Heroku - Terraform by HashiCorp
- TerraformでHerokuアプリのセットアップ | SOTA