はじめに
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に以下の設定を行う。
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
に以下のように設定を行ってアクセシビリティを高めている。
output "apigateway_invoke_url" {
value = aws_api_gateway_stage.prod.invoke_url
}
こうすることで、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"
};
}
});