Elastic Beanstalk 環境を Terraform で構築する

Elastic Beanstalk 環境を Terraform で構築する

AWS Elastic Beanstalk (以下 EB)は、スケール可能なウェブアプリの環境を簡単に構築・運用できるサービスです。

AWS コンソールからポチポチクリックしたりするくらいで、ELB・EC2・セキュリティグループ・CloudFormation stackなどなど、ウェブアプリ実行に必要なリソースが作成されます。

ただ、今回は、AWS コンソールからではなく Terraform を使って、Elastic Beanstalk 上での Rails 環境を構築してみます。

背景

環境構築の際の設定内容を記録しておきたいというのが一番の動機です。

  • AWS コンソールでの設定画面をスクリーンショットで保存する
  • AWS コンソールを使わずに、EB CLI を使ったシェルスクリプトで環境構築する

というのも選択肢としてはあり得ますが、他のプロジェクトで Terraform を使う事が多いため、今回は Terraform を使って設定ファイルをソース管理することにしました。

全体の流れ

前述の通り、EB を使って環境構築をすると、色んなリソースを勝手に作ってくれます。従って、

  1. Terraform で、EB が作ってくれる以外のリソース(VPC など)を作成
  2. その後に、EB の application と environment を Terraform で作成

という流れになります。

具体的な手順

(EB によって作成されない)各種リソース作成

以下のリソースを Terraform で作成しました。特に難しいところも無いと思いますし、ネット上にも色々と情報がありますので、詳細は省略します。

  • ネットワーク関連
    • VPC
    • サブネット
    • インターネットGW
    • NAT GW 、及びそれに割り当てる Elastic IP
    • ルーティングテーブル、及びサブネットとの関連付け
  • アプリで使用するもの、その他
    • S3 バケット
    • RDS
    • セキュリティグループ

その他、以下は手動で作成しました。

  • SSL 証明書(AWS Certificate Manager で作成)

EB の service role を作成

EB が他のサービスを呼び出す時などに、service role というロールが使われます。AWS コンソールなどから EB の application を作成する際に、特に指定しない場合は aws-elasticbeanstalk-service-role という名前のロールが自動生成されます。詳細は以下のページを参照して下さい。

Elastic Beanstalk service role – AWS Elastic Beanstalk

ただ、後述の Terraform の application を作成する手順では、service role が必須項目のため、事前に作成する必要があります。

一番簡単なのは、適当に EB のアプリケーションを作成(して後から削除)する方法です。

EB の application と environment を作成

次に、EB の application と environment も Terraform で作成するのですが、若干分かりにくいところがあったので、いくつか補足します。

application は以下の通り作成します。

resource "aws_elastic_beanstalk_application" "great-app" {
  name        = "GreatApp"
  description = "The Great App"

  appversion_lifecycle {
    delete_source_from_s3 = true
    max_age_in_days       = 0
    max_count             = 200
    # 事前に作成した service role を指定します。
    # nnnn のところは、AWS のアカウント ID を入れて下さい。
    service_role          = "arn:aws:iam::nnnnnnnnnnnn:role/aws-elasticbeanstalk-service-role"
  }
}

次に environment を作成します。注意すべき点などは、設定ファイル中のコメントに記載するか、後ほど説明します。

resource "aws_elastic_beanstalk_environment" "eb-env-great-app" {
  # Terraform の workspace 機能を使って、production, staging といった環境を作成します。
  name                = "GreatApp-${terraform.workspace}"
  application         = aws_elastic_beanstalk_application.great-app.name
  # 後ほど説明します。
  solution_stack_name = "64bit Amazon Linux 2018.03 v2.11.1 running Ruby 2.6 (Puma)"

  cname_prefix = "great-app-${terraform.workspace}"

  # 以下、"setting" で必要な値を設定します
  setting {
    namespace = "aws:ec2:vpc"
    name      = "VPCId"
    # "(EB によって作成されない)各種リソース作成" の項で作成したリソースを指定します。
    value     = aws_vpc.vpc-great-app.id
  }

  # 以下、"setting" のブロックが並ぶ
}

solution_stack_name に何を指定すれば良いかは、多分 AWS のサイトを見ないと分からないと思います。Ruby on Rails の場合は、以下のページにある表の一番左の列の太字じゃ無い方が solution stack name です。

Ruby Platform History – AWS Elastic Beanstalk

また、setting のブロックに、environment の設定項目を記載していくのですが、namespacename に何を指定すれば良いかは、以下のページに記載があります。

General options for all environments – AWS Elastic Beanstalk

大量の設定項目があるので、デフォルト値で良いものは指定しない方が楽です。

まとめ

Elastic Beanstalk を使うと web アプリの環境が簡単に構築できますが、Terraform と併用することで、さらに簡単に構築でき、Infrastructure as Code も実現できます。

人によっては、 EB によって自動的に作成されるリソースなどが沢山あるのが気持ち悪いと思うかもしれませんが、個人的には PaaS ってそんなものだと割り切っているので特に気になりませんでした。

we are hiring

優秀な技術者と一緒に、好きな場所で働きませんか

株式会社もばらぶでは、優秀で意欲に溢れる方を常に求めています。働く場所は自由、働く時間も柔軟に選択可能です。

現在、以下の職種を募集中です。ご興味のある方は、リンク先をご参照下さい。