0
0

More than 1 year has passed since last update.

Terraformで作ったAWSリソースの情報をWebpackで動的にJavascriptに埋め込む方法

Posted at

はじめに

Javascriptで開発をしていると困るのが、Terraformで作ったAWSリソースのURIが動的に払い出されてしまうため、開発環境とプロダクション環境で冪等にスクリプトを作れないということがあるのではなかろうか。

今回は、Webpackを使ってどんな環境でも同じコードベースで動作するように定義することをチャレンジしてみたい。

なお、今回の例ではフロントエンドのフレームワークにはVue.jsを使用している。
Vue.jsの基本的な文法や環境構築は別途前提知識として備えていることを前提としているのでご留意いただきたい。

Javascriptの設定

さて、URIはどこに埋め込んでも良いが、main.jsなりapp.jsなりのメインに、Vue.mixinを使って埋め込むのがシンプルで良いのではなかろうか。
定数なので、グローバルとして保持しても特に問題ないだろう。
今回は、Javascriptの環境変数として保持しておきつつ、バンドル版にパックするときに置換する仕組みとする。
これにより、ローカルテスト時は環境変数をlocalhostにしてあげればモックに向けて通信することも可能になり、コードベースの冪等性も高まるはずだ。

Vue.mixin({
  data: function () {
    return {
      APIGATEWAY_INVOKE_URL: process.env.APIGATEWAY_INVOKE_URL,
    }
  }
})

Webpackの設定

Wepackでは、webpack.config.jsに以下の設定を行う。

webpack.config.js
module.exports = {
  plugins: [
    // Vueを読み込めるようにする
    new VueLoaderPlugin(),
    // 環境変数を置換
    new webpack.DefinePlugin( (() => {
      // tfstateをJSONObjectにロードして必要な情報にアクセス可能にする
      //   ※tfstateへのパスは適宜変更する
      const jsonObject = JSON.parse(fs.readFileSync('../terraform/terraform.tfstate', 'utf8'))
      return {
        "process.env.APIGATEWAY_INVOKE_URL": JSON.stringify(jsonObject['outputs']['apigateway_invoke_url']['value'] + '/hogehoge')
      }
    })() )
  ]
};

補足: tfstateの中身

tfstateはJSON形式なので、Javascriptで読み込んで実装していくには相性が良い。
ただし、直接リソースにアクセスするのはハードルが高いため、今回はoutputsに以下のように設定を行ってアクセシビリティを高めている。

outputs.tf
output "apigateway_invoke_url" {
  value = aws_api_gateway_stage.prod.invoke_url
}

こうすることで、tfstate上では以下のように定義されるようになる。

terraform.tfstate
{
  "version": 4,
  "terraform_version": "0.14.5",
  "serial": 559,
  "lineage": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "outputs": {
    "apigateway_invoke_url": {
      "value": "https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/prod",
      "type": "string"
    }
  },
  (以下略)
}

リモートステートを使用している場合は、terraform output -jsonすることで同様の出力を得ることができる。

$ terraform output -json
{
  "apigateway_invoke_url": {
    "sensitive": false,
    "type": "string",
    "value": "https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/prod"
  }
}

WebpackによりバンドルされたJavascript

これで、npm run webpackすれば、以下のように変換される。
どんな環境でも同じコードベースからバンドル版のJavascriptを生成できるようになった!

vue__WEBPACK_IMPORTED_MODULE_1__["default"].mixin({
  data: function data() {
    return {
      APIGATEWAY_INVOKE_URL: "https://urhgcdv4mi.execute-api.ap-northeast-1.amazonaws.com/prod/hogehoge"
    };
  }
});
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0