AmplifyGen2でのリソース名の付け方と変数の管理方法について
概要
Amplify Gen2 を使用していてリソース名の付け方や環境ごとの変数のもたせ方について困ったが、そういった記事がどこにもなかったので質問も兼ねて書いてみます。
初めて書く記事なのでご容赦を。
リソース名の付け方について
CDKでAWSの構築をする時、リソース名ってどのようにつけますか?
AWS CDKのベストプラクティスでは「自動で生成されるリソース名を使用し、物理的な名前を使用しない
」と記載があります。
趣旨としては理解ができますが、以下のような問題があると考えています。
- 何がどのリソースなのかがぱっと見でわからない
- 循環参照おきがち( これは私の書き方が悪いだけかも )
なので私は基本的にリソース名のPrefixにプロジェクト名・環境名を入れるようにしています。
Amplify Gen1では?
Amplify Gen1のときにはCloudFormationの各Stackにenvというパラメータがあり、ここでAmplify の環境名を取得することができました。
そのため CustomResourceで独自のリソースを作るときには以下のようにして環境ごとの名称の衝突を避けていました。
"Name": {
"Fn::Sub": "amplify-poc-${env}-reosurceName"
}
Amplify Gen2では?
Amplify Gen2ではenvというパラメータがなくなってしまいました。なぜ…
先述の理由でリソース名を自動でつける選択肢はないと思っているので、なんとかamplifyから環境を識別できる文字列を取得しなければなりません。
案1 スタック名を使う
1個目はスタック名を使用する案です。
defineBackendのパラメータから親スタックの名前が取れます。
const backend = defineBackend({...})
const parentStackName = backend.stack.stackName // 親のスタックの名称
new iam.Policy(this, 'policy', {
policyName: `${parentStackName}-henoheno-policy`,
statements: [new iam.PolicyStatement({
actions: ['s3:GetObject'],
resources: ["*"],
})],
})
こうすれば、環境ごとに名前が変わるので衝突の問題はなさそうです。
ただ、1つ懸念があります。Stack名の長さです。
Amplify Gen2のStack名は以下のようなルールで決まります
本環境: amplify-${APP_ID(14桁)}-${ブランチ名}-branch-${ランダム文字列(10桁)}
Sandbox環境: amplify-${APP_ID(14桁)}-${identifier}-sandbox-${ランダム文字列(10桁)}
identifierは独自で設定ができますが基本はPCのユーザー名になります
ブランチ名・identifierを無視しても、40文字以上あります。
あまり長いと読みづらくなるのと、リソースによっては文字数の上限に引っかかりそうな気がします。
案2 環境変数で環境名を指定する
2個目は環境名を環境変数で指定してしまう方法です。
.env.localに環境名を記載しておいて、amplify側でその値を読み取らせます。
Sandboxでの実行には@dotenvx/dotenvx が必要になります
env=sandbox1
const backend = defineBackend({...})
const PROJECT_NAME = "amplify-poc"
const ENV = process.env.ENV as string
new iam.Policy(this, 'policy', {
policyName: `${PROJECT_NAME}-${ENV}-henoheno-policy`,
statements: [new iam.PolicyStatement({
actions: ['s3:GetObject'],
resources: ["*"],
})],
})
npx dotenvx run -f .env.local -- npx ampx sandbox
これであれば、プロジェクト名も環境名も好きに決められるので可読性が良く、比較的短い名称にできると思います。
注意点は以下の通りです。
- 複数人で同じAWSアカウント上で開発を行っている場合、誰がどの環境名を使用しているか管理しておかないと名前が衝突する可能性がある。
- 環境構築時に環境名の指定を忘れないようにする
環境変数の持ち方について
AWSで複数の環境を構築する場合、環境ごとに値を変えたいものがあると思います。
Amplifyの場合、Console上で設定することができますが、個人的にはあまりこの方法は好きではありません。
- コンソール上での手での設定はどうやってもミスが起きる。(タイポ・入力忘れ等)
- バージョン管理ができない
- 文字列しか使用できない
基本的にはコードの中で完結するように管理をしたいです。
CDKでは
CDKでは複数環境を作る場合、環境ごとの変数の管理の方法はいくつかありますが、個人的に推奨したいのは「TypeScriptのファイルとして記載する方法」です。
いくつか理由を上げると
- 補完が聞くこと
- 型定義ができること
- 文字列以外の型を使用できること (例えば、ec2.InstanceType 等CDKで定義された型が使用できる)
等が挙げられます。
詳細は割愛しますが、以下のような感じです。
Amplify Gen2では
順当にやるのであれば、Amplifyの環境変数を利用する方法ですが、先述の通りあまりこの方法は使いたくありません。
以下の方法を提案してみます。
TypeScriptで環境名毎に 変数を管理する
TypeScriptで値を管理したうえで、前半で提案した環境名を利用して、変数を切り替えられるようにします。
コードは以下においておきます
/amplify/config 内で
- 各パラメータの定義
- 各環境の変数管理
- 環境名による値の出し分け
をしています。
/amplify/backend.ts で環境変数から環境名を取り出して、対象の環境のconfigを取得、各コンストラクタに引き渡しています。
環境ごとに変数を記載したファイルが1個ずつあります。
今回はCustomResourceでIamPolicyを作成し、環境ごとに与える権限を変えています。(権限に関してはこういう使い方をすることは少ないとは思いますが)
この方法の良いところは、先述のCDKの変数をTypeScript内で持つ方法で触れた点に加えて、Amplifyの環境変数よりも差し替えが容易なことが挙げられます。
dotenvxで環境変数を利用する場合、環境変数を追加・変更しようとした場合、sandboxコマンドを一度終了させて、変更後に再実行する必要があります。
そんなに手間な作業ではないですが、環境構築中などで頻度が多くなると煩わしくなってきます。
最後に:本当にこれでよいのか?
本当にこの方法で良いのか謎。🤔🤔🤔
– 環境名をamplify gen2で簡単に取得できる方法は本当に無いのか?
- AmplifyGen2のCustomResourceを利用している記事がほとんど無い。
- 更にリソース名の付け方や変数の持ち方を問題にしているものは、自分が見た限り無い
- そういった記事が無いのは、利用者が少ないからなのか、自分のAmplifyの使い方が悪いからなのか…
AmplifyGen2を利用されている方、コメントお待ちしています。
Discussion