本記事は AWS AmplifyとAWS×フロントエンド #AWSAmplifyJP Advent Calendar 2023の19日目の記事です。
はじめに
最近発表のあったAmplifyのGen2についてまだ詳しく情報収集はできていませんが、開発方法が大きく変わり、Gen1では手が届かなかった痒いところにも手が届きやすくなって開発体験はより良くなりそうな印象です。
近い将来にはAmplifyのGen2がベターな方法になって行くかとは思いますが、まだプレビューのお試し状態ですので、本番運用で使うAmplifyについてはまだしばらくGen1が続きそうです。
そんなGen1をまだまだ現役として少しでも快適に使うために今回は、AmplicyCLIのオーバーライド機能について簡単に書いていきたいと思います。
Amplifyのオーバライド機能
AmplifyCLIの対話方式では設定ができない細かいバックエンドの設定をAmplify管理の中で行うことができる機能です。
初期の頃は、Amplifyによって自動生成されるCloudFormationのファイルを直接触って設定を行うなんてこともしていましたが、色々大変でしたので、こうやって1つ1つ改善されて言っていることを改めて感じます。
現状オーバーライドに関してはproject/api/auth/storageの4つが用意されています。
プロジェクトレベルのオーバライド
Amplifyが生成したプロジェクトレベルのIAMリソースの設定が行えます。
$ amplify override project
参考
Override Amplify-generated project-level IAM resources
AWS::IAM::Role
authRoleポリシーに特定の権限を追加
import { AmplifyRootStackTemplate } from "@aws-amplify/cli-extensibility-helper";
export function override(resources: AmplifyRootStackTemplate) {
const authRole = resources.authRole;
const basePolicies = Array.isArray(authRole.policies)
? authRole.policies
: [authRole.policies];
authRole.policies = [
...basePolicies,
{
policyName: "amplify-permissions-custom-resources",
policyDocument: {
Version: "2012-10-17",
Statement: [
// 追加したいリソースの権限を追加
{
Resource: "<ARN of Geo>",
Action: ["geo:CalculateRoute*"],
Effect: "Allow",
},
],
},
},
];
}
参考
GraphQL override not working
APIのオーバーライド設定
Amplifyで作成したAppSyncやDynaamoDBの設定の上書きができます。
$ amplify override api
参考
Modify Amplify-generated resources
AWS AppSync resource type reference
本番環境だけポイントインタイムリカバリを有効化
import { AmplifyApiGraphQlResourceStackTemplate } from '@aws-amplify/cli-extensibility-helper'
import { ModelDirectiveStack } from '@aws-amplify/cli-extensibility-helper/lib/types/api/amplify-api-resource-stack-types'
type Models =
| 'TargetTable1'
| 'TargetTable2'
| 'TargetTable3'
export function override({ models }: AmplifyApiGraphQlResourceStackTemplate) {
const modelNames: Models[] = ['TargetTable1', 'TargetTable2', 'TargetTable3']
const modelsMap = models as Partial<Record<Models, ModelDirectiveStack>>
// 環境名の取得 // https://qiita.com/naniwadari/items/7944b31ce52f85646e2c
const amplifyMetaJson = require('../../../amplify-meta.json')
const prodEnv = amplifyMetaJson.providers.awscloudformation.StackName
.split('-')
.find((part) => part === 'prod')
if (prodEnv) {
modelNames.forEach((modelName) => {
const model = modelsMap[modelName]
if (model) {
prepareForExport(model)
}
})
}
}
function prepareForExport(model: ModelDirectiveStack) {
model.modelDDBTable.pointInTimeRecoverySpecification = {
pointInTimeRecoveryEnabled: true,
}
}
参考
GraphQL override not working
Amplifyのoverride.tsで環境名を取得する
X-Rayのトレースを有効化
import { AmplifyApiGraphQlResourceStackTemplate } from '@aws-amplify/cli-extensibility-helper';
export function override(resources: AmplifyApiGraphQlResourceStackTemplate) {
resources.api.GraphQLAPI.xrayEnabled = true
}
TTLを有効化
import { AmplifyApiGraphQlResourceStackTemplate } from '@aws-amplify/cli-extensibility-helper'
import { ModelDirectiveStack } from '@aws-amplify/cli-extensibility-helper/lib/types/api/amplify-api-resource-stack-types'
type Models =
| 'TargetTable1'
| 'TargetTable2'
| 'TargetTable3'
export function override({ models }: AmplifyApiGraphQlResourceStackTemplate) {
const modelNames: Models[] = ['TargetTable1', 'TargetTable2', 'TargetTable3']
const modelsMap = models as Partial<Record<Models, ModelDirectiveStack>>
modelNames.forEach((modelName) => {
const model = modelsMap[modelName]
if (model) {
prepareForExport(model)
}
})
}
function prepareForExport(model: ModelDirectiveStack) {
model.modelDDBTable.timeToLiveSpecification = {
attributeName: "ttl",
enabled: true
}
}
参考
AWS::DynamoDB::Table TimeToLive
Authのオーバーライド設定
Amplifyで作成したCognitoの設定の上書きができます。
$ amplify override auth
参考
Amazon Cognito resource type reference
デバイス情報を常に記憶する
import { AmplifyAuthCognitoStackTemplate } from '@aws-amplify/cli-extensibility-helper'
export function override(resources: AmplifyAuthCognitoStackTemplate) {
resources.userPool.deviceConfiguration = {
challengeRequiredOnNewDevice: true,
}
}
参考
AWS::Cognito::UserPool DeviceConfiguration
SESを使ったメール送信設定
import { AmplifyAuthCognitoStackTemplate } from '@aws-amplify/cli-extensibility-helper'
export function override(resources: AmplifyAuthCognitoStackTemplate) {
resources.userPool.emailConfiguration = {
replyToEmailAddress: 'test@example.com', // 返信の宛先メールアドレス
emailSendingAccount: 'DEVELOPER', // SES使用を指定
from: 'example.com <support@example.com>', // Fromの表示設定
sourceArn: 'arn:aws:ses:xxxx:000:identity/yyy', // SESで検証済みドメインのarn
}
}
参考
AWS::Cognito::UserPool EmailConfiguration
ユーザー名の小文字大文字判定
import { AmplifyAuthCognitoStackTemplate } from '@aws-amplify/cli-extensibility-helper'
export function override(resources: AmplifyAuthCognitoStackTemplate) {
resources.userPool.usernameConfiguration = {
caseSensitive: true,
}
}
参考
AWS::Cognito::UserPool UsernameConfiguration
パスワード設定の上書き
import { AmplifyAuthCognitoStackTemplate } from '@aws-amplify/cli-extensibility-helper';
export function override(resources: AmplifyAuthCognitoStackTemplate) {
resources.userPool.policies = {
passwordPolicy: {
...resources.userPool.policies["passwordPolicy"], // 現在の設定を展開
// 上書きしたい設定
minimumLength: 12, // 最小数
requireLowercase: true, // 小文字必須
requireNumbers: true, // 数字必須
requireSymbols: true, // 記号必須
requireUppercase: true, // 大文字必須
temporaryPasswordValidityDays: 2 // 一時的なパスワードの有効日数
}
}
}
参考
AWS::Cognito::UserPool PasswordPolicy
管理者のみにユーザーの作成を許可
import { AmplifyAuthCognitoStackTemplate } from '@aws-amplify/cli-extensibility-helper'
export function override(resources: AmplifyAuthCognitoStackTemplate) {
resources.userPool.adminCreateUserConfig = {
allowAdminCreateUserOnly: true
}
}
参考
AWS::Cognito::UserPool AdminCreateUserConfig
トークンの設定
import { AmplifyAuthCognitoStackTemplate } from '@aws-amplify/cli-extensibility-helper'
export function override(resources: AmplifyAuthCognitoStackTemplate) {
// 各トークンの有効期限
resources.userPoolClientWeb.accessTokenValidity = 30;
resources.userPoolClientWeb.idTokenValidity = 30;
resources.userPoolClientWeb.refreshTokenValidity = 30;
// 各トークンの有効期限の単位
resources.userPoolClientWeb.tokenValidityUnits = {
accessToken: 'hours',
idToken: 'hours',
refreshToken: 'hours'
};
}
参考
AWS::Cognito::UserPoolClient
Storageのオーバーライド設定
Amplifyで作成したS3などの設定の上書きができます。
$ amplify override storage
参考
Modify Amplify-generated resources
Amazon Simple Storage Service (Amazon S3) resource type reference
バージョニングの設定
import { AmplifyS3ResourceTemplate } from '@aws-amplify/cli-extensibility-helper';
export function override(resources: AmplifyS3ResourceTemplate) {
resources.s3Bucket.versioningConfiguration = {
status: 'Enabled',
};
}
参考
AWS::S3::Bucket VersioningConfiguration
ライフサイクルポリシーの設定
import { AmplifyS3ResourceTemplate } from '@aws-amplify/cli-extensibility-helper';
export function override(resource: AmplifyS3ResourceTemplate): void {
resource.s3Bucket.lifecycleConfiguration = {
rules: [
{
status: 'Enabled',
noncurrentVersionExpiration: {
noncurrentDays: 30, // 30日で削除
newerNoncurrentVersions: 10, // 最新のオブジェクト10個は保持
},
},
],
};
}
参考
AWS::S3::Bucket LifecycleConfiguration
AmplifyのOverride機能を使って、S3にバージョニングとライフサイクルポリシーを設定する方法
おわりに
オーバーライド機能によって、Amplify管理の中でより細かい設定も行えるようになったので、開発規模が大きくなっても対応しやすくなってきました。
ただ、そもそも各AWSサービスの基礎知識がなければ設定のしようもないので、より踏み込んだ開発を行うためには、各AWSサービスの学習をもっとしなければ、と感じている今日このごろです。
引き続きAmplifyの今後の動向にもチェックしながら、今後のさらなる発展に期待です。
良きAmplifyライフを!