menu-icon

Elastic Beanstalkの環境プロパティから.envファイルを生成する

AWS Elastic Beanstalk を使うと、インフラの構築や管理が楽になり、アプリケーションの開発に集中できるのでありがたいです。ただ、環境依存の設定管理が不便に感じたので、一工夫してみました。

Beanstalkの環境プロパティが使いにくい

Elastic Beanstalkでは環境プロパティを使用して、アプリケーションを実行している EC2 インスタンスの環境設定を指定できます(参考)。これにより、例えば本番環境と検証環境でDBのhostを変える等が、Beanstalkだけでできるのかなと最初は思いました。しかし、これがやっかいで、以下の問題点がありました(あくまでPHPプラットフォームの話です)。

  • $_SERVER or get_cfg_var関数でしか、参照できない(環境変数として設定されるわけではない)
  • コマンド実行時には参照できない(FastCGI実行時のみ参照可能) 

特にコマンド叩く時に参照できないのは致命的です。ということで、Beanstalkの環境設定について考えました。

試した方法

1. S3に環境設定ファイルを置いておいてDL

.ebextensionsに以下を配置すれば、指定したバケットから.envをDLしてくることができます。

.ebextensions/dl-env-from-s3.config

Resources:
  AWSEBAutoScalingGroup:
    Metadata:
      AWS::CloudFormation::Authentication:
        S3Auth:
          type: "s3"
          buckets: ["elasticbeanstalk-ap-northeast-1-000000000000"]
          roleName:
            "Fn::GetOptionSetting":
              Namespace: "aws:autoscaling:launchconfiguration"
              OptionName: "IamInstanceProfile"
              DefaultValue: "aws-elasticbeanstalk-ec2-role"

files:
  "/tmp/.env":
    mode: "000644"
    owner: root
    group: root
    authentication: "S3Auth"
    source: https://elasticbeanstalk-ap-northeast-1-000000000000.s3-ap-northeast-1.amazonaws.com/.env

DLした後は適切な場所に置くだけです。ただ、これだと環境による使い分けができないです。。。

この方向で行くなら、複数のenvファイルをs3に置いておいて、環境プロパティを見てDLするファイルを変えれば、使い分けできると思います。しかし、それなら環境プロパティからenv作った方が楽かな?と思いました。

2. 環境プロパティの値から、環境設定ファイルを生成

環境プロパティに設定した値を参照して、.envを生成します。環境プロパティは環境ごとに設定できるので(当たり前)、これなら使い分けもできて管理も楽そうです。

.platform/hooks/predeploy/01_create_env.sh
#!/bin/sh

EB_META_DATA_FILE=/tmp/metadata.json
STACK_ID=`sudo cat /opt/elasticbeanstalk/config/ebenvinfo/stackid`
REGION=`sudo cat /opt/elasticbeanstalk/config/ebenvinfo/region`
sudo /opt/aws/bin/cfn-get-metadata -s ${STACK_ID} -r AWSEBBeanstalkMetadata --region ${REGION} -k "AWS::ElasticBeanstalk::Ext" > ${EB_META_DATA_FILE}
ENV_VARS=`jq -r '.Parameters.EnvironmentVariables' < ${EB_META_DATA_FILE}`
echo ${ENV_VARS} | jq -r 'to_entries[] | [.value] | join("")' > .env

rm ${EB_META_DATA_FILE}

ちょっと頑張ってますが、上記のスクリプトを配置してデプロイすればアプリケーションのルートディレクトリに.envが作成されます。

試してみる

環境プロパティの設定です。

デプロイ後、インスタンスに入って確認してみます。

$ cat /var/www/html/.env
EB_ENV=test
DB_HOST=hogehoge
SECRET=secretdayo

これで環境プロパティをLaravelやphpdotenvで便利に使うことができます。

まとめ

Elastic Beanstalkでの環境プロパティの使い方について検討しました。個人的には扱いやすくなったかと思います。ご参考までに。