AWS 設計ガイドライン_CTO監修

AWS 設計ガイドライン_CTO監修

本記事は、Ragate 株式会社の AWS 開発業務で使用される AWS の設計ガイドラインです。

本記事はAWSのWell-ArchitectedのServerless Applications Lensに則り定義されており、当社の AWS 開発業務に関わる各位が閲覧する事を前提とした開発ドキュメントとなります。

本書のユースケース

  • AWS 開発プロジェクトの初期段階に、お客様含めプロジェクトメンバー各位が参照
  • AWS の設計業務で行き詰まった時に設計の原則として見返す

※ 但しお客様がすでに同様のガイドラインを所有している場合はそちらに従います

※ お客様の所有するガイドラインに懸念がある場合はプロジェクト初期段階に設計ガイドラインを慎重にすり合わせます(当社の AWS 開発プロジェクトは開発内製化を前提としているため)

コンピュートレイヤーの設計戦略

Things to Consider When You Build a GraphQL API with AWS AppSync | AWS  Architecture Blog

コンピュートレイヤーには極力、従来の AWS EC2 のようなホットスタンバイする製品ではなく、サーバーレス製品の提案を目指します。ビジネス要件を要件定義フェーズで慎重にヒアリングし、サーバーレス製品が要件にフィットすると判断した場合は、サーバーレス製品による各メリット(従量課金制によるコスト最適化、保守運用の簡素化等々)の説明と提案に努めてください。

ただし、注意したいのはサーバーレスの製品は銀の弾丸ではないということです。例えば以下のような、サーバーレス製品の弱みを理解しお客様への説明に努め、適切に提案することが重要です。

  • 瞬時に大量の需要(スケール)を伴うワークロードの場合はスロットリングのリスクを抱える
  • API は常にコールドスタートによるレイテンシーの可能性を持つ
  • AWSの利用費用試算の誤りによる意図しないコストの消費
  • チームメンバーの教育コスト、モノリスと比較して習熟したエンジニアがまだ少ない
  • アプリケーションレイヤーの自主的な管理
  • AWS へのベンダーロックイン

要件がサーバーレス製品にフィットしそうなら、コンピュートレイヤーの設計は以下戦略をベースとしてお客様へ提案を行います。

AWS コンピュート製品製品説明戦略 (主なユースケース)
LambdaLambdaの概要– NodeJS の実行 ( TypeScript のデプロイ)
– APIGateway との統合
– AppSync との統合
– DynamoDB Stream との統合
– その他 AWS 上でのイベント駆動実行
API GatewayAPI Gatewayとは– サーバーレスな RestAPI サーバ―の構築
AppSyncAppSyncの概要– サーバーレスな Graphql サーバ―の構築
Step FunctionsStep Functionsとは?– ビジネスクリティカルな処理の実行
– 複雑なワークロードの管理

サーバーレスアーキテクチャーにメリットはいずれのビジネスでも重宝されるものばかりですが、デメリットも理解の上、提案・導入するように努めてください。

データレイヤーの設計戦略

Fast NoSQL Key-Value Database – Amazon DynamoDB – Amazon Web Services

データレイヤーはシステム内の永続ストレージを扱い、ビジネスロジックが必要とする状態を保存するための安全なメカニズムの提供を目指します。尚、データ変更に応じたイベントトリガーのメカニズムも含め提供します。

データレイヤーの設計者は、設計の原則として以下を確認してください。

  • RDBMS は銀の弾丸ではない、悩んだ時にとりあえず RDBMS に逃げるのはやめしょう
  • 一つの DBMS 製品での完結は極力避ける、ユースケース毎に適切な NoSQL を使い分ける
  • クエリーニーズとデータボリュームを主軸にして DBMS を検討する
  • 要件にフィットするなら積極的に DynamoDB を提案
  • バックアップは手動ではなく RPO に合わせて AWS backup 等のマネージド製品を活用

以下は主に提案するデータレイヤーの製品です。

AWS データレイヤー製品製品説明戦略 (主なユースケース)
DynamoDBDynamoDB の概要– メインの DBMS
– KVS によるデータ格納
– 検索要件に合わせたインデックス設計
– 低コストで高速な可用性高い DBMS
– スタートアップから大規模まで対応可能
OpenSearch ServerlessOpenSearch の概要– 全文検索(形態素解析付き)
– Nグラム検索
– コンシューマー向けの複雑な検索要件
DynamoDB で対応できない検索ニーズに応える
– DynamoDBStream との組み合わせ
– ログの検索
DocumentDBDocumentDB の概要– MongoDB の要件は DocumentDB で満たす
– ドキュメント型のデータ管理
Neptune ServerlessNeptune Serverless の概要– グラフ型のワークロードを実行
– 縦軸の大規模な演算
Aurora ServerlessAurora Serverless 概要– RDBMS 型の保持
S3S3の概要– バイナリー型データの保持
– 非常に高い可用性でバイナリーデータを管理

ここで大きな注意点としては、Aurora Serverless のコールドスタート(レイテンシー)問題です。事前に PoC 検証の段階を挟むなどしてワークロードに確実にフィットするかを慎重に検証してください。もし許容出来ないレイテンシーが発生するなら、通常のホットスタンバイするデータストアー(RDS)を使用するのも悪い選択肢ではありません。

メッセージング・ストリーミングレイヤーの設計戦略

Push Notification Service - Amazon Simple Notification Service (SNS) - AWS

メッセージングレイヤーは、コンポーネント間の通信を扱います。ストリーミングレイヤーは、ストリーミングデータのリアルタイム分析と処理を扱います。

AWS データレイヤー製品製品説明戦略 (主なユースケース)
SNSSNS の概要– マイクロサービスの非同期イベント通知
– サーバーレスアプリケーション非同期イベント通知
– モバイルプッシュ通知
– pub/sub パターンのためのフルマネージドメッセージングサービス
Kinesis ファミリーKinesis の概要– リアルタイムのストリーミング・データの収集
リアルタイムのストリーミング・データの処理・分析

特に Kinesis はサーバーレス製品でありながら、 秒あたりにギガバイト単位のデータをストリーミング可能です。大量のインサイトの収集要件が上がれば、ぜひ積極的に提案しましょう。

ユーザー管理 / IDレイヤーの設計戦略

Authentication Service - Customer IAM (CIAM) - Amazon Cognito - AWS

ユーザー管理 / IDレイヤーは、ワークロードにおける外部・内部顧客の両方に ID、認証、および認可を定義します。

要件にフィットするなら、基本的には CognitoUserPool を提案・導入しましょう。

Amazon Cognito を使用すると、サーバーレスアプリケーションにユーザーサインアップ、サインイン、データ同期を簡単に追加できます。Amazon Cognito User Pools は、組み込みのサインイン画面と Facebook、Google、Amazon、および Security Assertion Markup Language (SAML) とのフェデレーションを提供します。更に、Amazon CognitoFederated Identities を使用すると、他の AWS リソースへのスコープ付きアクセスを安全に提供できます。

補足として、高い確率でお客様が独自に認証サーバー(IDP)を保有しているケースが多数見られますので、もし既存のIDPとの認証が必要なら、まずは Cognito と連携可能かを調査するのも一つです。Cognito と既存の IDP が連携できると、セッションタグを使用した安全な AWS リソースへのアクセスが可能となります。

  1. CognitoUserPool と既存の IDP を連携
  2. 認証ユーサーへ Cognito ユーザーグループを付与
  3. CognitoIDPool を使用し Cognito ユーザーグループに合った IAM ロールの STS トークンを発行

またよくあるユースケースとして、ユーザー自身がプロフィール画像のアップロードをS3へ行う際に、ユーザーに対して、ユーザーIDを Prefix とした IAM ポリシーを動的に生成しユーザーにS3へのアップロードを許可するケースがあります。これらの一連の処理をフロントエンドで完結できるようにすると、API の実装コストが削減できます。

以下は、上記ユースケースの IAM ロールの一例です。

AuthenticatedRole:
  Type: AWS::IAM::Role
  Properties:
    RoleName: 'authenticated-role'
    AssumeRolePolicyDocument:
      Version: '2012-10-17'
      Statement:
        - Effect: Allow
          Principal:
            Federated: cognito-identity.amazonaws.com
          Action:
            - sts:AssumeRoleWithWebIdentity
            - sts:TagSession
          Condition:
            StringEquals:
              cognito-identity.amazonaws.com:aud: !Ref CognitoIdentityPool
            ForAnyValue:StringLike:
              cognito-identity.amazonaws.com:amr: authenticated
    Path: '/'
    Policies:
      - PolicyName: authenticated-role-policy
        PolicyDocument:
          Version: '2012-10-17'
          Statement:
            - Effect: Allow
              Action:
                - 's3:ListBucket'
              Resource:
                - !GetAtt UserAssetBucket.Arn
              Condition:
                StringLike:
                  s3:prefix:
                    - !Join
                      - ''
                      - - '$'
                        - '{aws:PrincipalTag/username}'
                        - '/*' # 要件に合わせて権限を絞る
            - Effect: Allow
              Action:
                - 's3:PutObject'
              Resource:
                - !Join
                  - ''
                  - - !GetAtt UserAssetBucket.Arn
                    - '/'
                    - '$'
                    - '{aws:PrincipalTag/username}'
                    - '/*' # 要件に合わせて権限を絞る

エッジレイヤーの設計戦略

Low-Latency Content Delivery Network (CDN) - Amazon CloudFront - Amazon Web  Services

エッジレイヤーは、プレゼンテーションレイヤーと外部顧客との接続を管理します。エッジレイヤーは、地理的に異なる場所にいる外部顧客に効率的な配信方法を定義します。

特段、お客様から希望がなければCloudFront導入を提案してください。

ただし、Edge ロケーションでの高度なコンピュート処理(画像の圧縮等々、通信情報変換等々)が求められる要件が存在する場合は、CloudFlare 等々の外部サービスとの連携も視野に入れてください。結果として運用コスト及び開発工数が小さく抑えられる方法をきちんと検討・提案した上で、最終的なアーキテクチャーを決定してください。

システム監視レイヤーの設計戦略

Amazon CloudWatch(リソースとアプリケーションの監視と管理)| AWS

システム監視レイヤーは、メトリクスを通じてシステムの可視性を管理し、ワークロードが時間とともにどのように動作し、どのように振る舞うかについて定義します。

AWS 開発におけるシステム監視は、お客様の構想されている運用体制と、ビジネス的にどのような運用監視が必要化を慎重にヒアリングした上で設計を行います。

AWS システム監視製品製品説明戦略 (主なユースケース)
Amazon CloudWatchAmazon CloudWatch とは– 使用中の全 AWS サービスのメトリクスにアクセス
– システムとアプリケーションレベルのログを統合
– 特定のニーズに合わせてカスタムメトリクスを定義
– ビジネス要件に合わせた KPI 作成
– ダッシュボードによる運用中の監視
– アラートを設定しプラットフォーム上で自動化されたアクションをトリガー
AWS X-RayAWS X-Ray とは– リクエストのエンドツーエンドを可視化
– パフォーマンスのボトルネックを特定
– サーバーレスアプリケーションの分析とデバッグ

尚、上記のような監視ツールでの監視が行えない要件の場合は、独自に運用監視用のワークロードを Step Functionsや EventBridge を用いて構築することも視野に入れてください。

ログ収集アカウントを検討してください

アプリケーション用の AWS アカウントとは別に、ログ収集用の AWS アカウントの構築及び設定を検討してください。

AWS ContorolTowerでは、ランディングゾーンセットアップすると、共有アカウントの 1 つとしてログアーカイブアカウントが作成されます。これは、すべてのログ (他のすべてのアカウントのログを含む) を一元的に収集する専用のアカウントです。これらのログファイルを参照することで、管理者と監査人は発生したアクションとイベントを確認できます。

AWS アカウントの初期設定段階では、AWS ContorolTowerの利用を検討してください。

サードパーティ製品の利用

データドッグの技術的な企業分析

基本的な運用要件は AWS の製品で満たすことが可能ですが、ダッシュボード GUI の洗練さを求める場合や、お客様の運用チームの持つ運用に対する経験・知見次第では、データドッグ等のツールの使用も検討してください。

尚、サードパーティ製品については、エンタープライズ割引等も受けれることもがありますので、お客様と共に価格交渉を極力行ってください。

Serverless CI.CD

CI/CD with Serverless Framework - YouTube

当社は ServerlessFramework で開発を行うことが非常に多いです。そのため、CICD については ServerlessFramework社の製品でもある Serverless CI.CD の導入を検討してみてください。以下は CodePipeLine との比較です。

製品メリットデメリット
AWS Code シリーズ– AWS の内部に閉じてデプロイできるのでセキュア
– AWS の通知系サービスと統合可能
– AWS CloudFormation で管理可能
– ServerlessFramework のデプロイを独自設定必要
– CodeBuild のビルドプロセス等でログを確認しなければ行けない
– リポジトリ変更検知が少し遅い印象
Serverless CI.CD– ServerlessFramework のデプロイ設定が基本的に不要
ServerlessFramework のデプロイ進捗を見やすく可視化
ServerlessFramework 社のサポートを一部受けることが可能
– デプロイ失敗の原因をダッシュボードで可視化
– 高速なリポジトリの変更検知
– AWS の外部に強い IAM 権限を渡さなければいけない
– 外資系サービスの為コンプライアンスと相談必須
– ServerlessFramework で開発していない場合は使用するメリットは無い

デプロイの設計戦略

マイクロサービスアーキテクチャにおけるデプロイのベストプラクティスは、変更がコンシューマのサービス契約を壊さないようにすることです。もし API オーナーがサービス契約を壊すような変更を行い、コンシューマーがそれに備えていない場合、障害が発生する可能性があります。

どのコンシューマが API を使用しているかを把握することは、デプロイメントを安全に行うための第一歩です。コンシューマとその使用状況に関するメタデータを収集することで、変更の影響についてデータ駆動型の意思決定を行うことができます。データの収集方法については、前述のシステム監視レイヤーをご覧ください。 

デプロイ戦略については、特段お客様の方で案がない場合、サーバーレス構成なら以下のような戦略の提案してください。

環境デプロイ方法詳細
開発環境オール・アット・ワンス・デプロイメントオール・アット・ワンスのデプロイメントでは、既存の構成の上に一括で変更を加えます。このタイプのデプロイメントスタイルは開発者の労力が少なく、デプロイの疎通が容易に行なえます。

しかし、ロールバックに関してはリスクが増し、通常はダウンタイムが発生します。このデプロイメント・モデルは、開発などの非クリティカルな環境で、顧客への影響がリスクにならない場合に使用するようにしてください。
ステージング環境オール・アット・ワンス・デプロイメント同上
本番環境ブルー/グリーンの配備API を別のサブドメインにクローンし、そしてRoute53 等々でルーティングすることで、既存のコンシューマーに影響が及ばないようにします。フェイルオーバールーティング等が検討できます。

このアプローチは、ブルーグリーンのデプロイメントをシンプルにそして容易にしますが、二重の API(及びそれに伴うバックエンドインフラストラクチャ)を維持するためのオーバーヘッドが追加で必要になります。

コストの試算を行った上で、適切なデプロイ戦略を検討してください。

セキュリティ戦略

サーバーレスアーキテクチャーでは、OS・システムのパッチ適用やバイナリ更新といったインフラ管理タスクを AWS が行うため、従来の多くのセキュリティリスクに自動で対処してくれます。しかし、 非サーバーレスアーキテクチャと比較していくつかの攻撃から自動で守ってくれるものの、OWASP を始めとしたアプリケーション層のセキュリティ対策のベストプラクティスは、依然として開発者に求められます。

本セクションを確認し、サーバーレスアーキテクチャーで意識すべきセキュリティ事項を把握してください。

サーバーレス API へのアクセス制御

本記事では APIGateway を題材として API のアクセス制御について解説します。まず、APIGateway には現在5つの認証タイプがあります。

  • AWS_IAM authorization
  • Amazon Cognito user pools
  • API Gateway Lambda authorizer
  • Resource policies
  • Mutual TLS authentication

上記を必要に応じて API サーバーへ設定してください。

AWS_IAM authorizationのユースケース


                Diagram showing AWS_IAM authorization

IAM 認証は、事前に API の利用者が確定している場合に有効です。(リクエスターがより厳格にきまっている場合は後述の Resource policies のユースケースセクションもご覧ください)

例えばお客様のパートナー企業が APIGateway へリクエストするケースを想定した場合、アクセスの都度CognitoUserPool による認証を実行してもらうのではなく、必要な権限をセットした IAM ロールを AssumeRole してもらい、トークンを使用し API Gateway へリクエストしてもらうようなアプローチが検討できます。IAM ロールの Pricipal と IAM ポリシーは常に最小範囲であることが求められますので注意してください。Principal の設定方法は、こちらをご覧ください。

Amazon Cognito user poolsのユースケース


                Diagram showing  Amazon Cognito user pools

コンシューマーを始めとした利用者が認証要求を行うユースケースに最適です。ユーザーは CognitoUserPool で認証後に、認証トークンを Auhtorization ヘッダーに設定することで、APIGateway へリクエストすることが可能です。尚、APIGateway 以外の AWS リソースへのアクセスは、ユーザーに CognitoUserPool 認証で得た認証トークンをCognitoID プールへリクエストしSTSトークンを取得させることで可能となります。

補足として、CognitoID プールで実現可能な認可(動的な IAM ポリシー生成)は、セッションタグまでとなります。より高度な認可設定を行う場合は、別途 API を用意し、セッションポリシーを生成し、ユーザーへ認可トークンを提供してください。セッションポリシーのユースケースとして、例えばユーザーが複数の組織に属しており、複数組織に対応する認可トークンを生成する必要があるなどが挙げられます。(1回のセッションポリシー生成処理におけるJSON オブジェクトのサイズには制限があるため注意してください)

API Gateway Lambda authorizerのユースケース


                Diagram showing API Gateway Lambda authorizer

お客様が独自に認証サーバーを運用している場合に有効な方法です。LambdaAuthorizer 上で、お客様の認証サーバーと連携しトークンの検証などを行う事が可能です。尚、LambdaAuthorizer の認可はデフォルトで300秒のキャッシュが有効化されているため、1回目のリクエストが疎通しても、実装方法次第では2回目のリクエストが疎通しなくなります。詳しくは以下の LambdaAuthorizer のソースコードを参考にしてください。

import middy from 'utils/middy';
import { APIGatewayAuthorizerResult, APIGatewayTokenAuthorizerEvent } from 'aws-lambda';
import logger from 'utils/logger';

export const handler = middy.handler(async (event: APIGatewayTokenAuthorizerEvent): Promise<APIGatewayAuthorizerResult> => {
  const region = process.env.REGION as string;
  const accountId = process.env.ACCOUNT_ID as string;
  const apiId = process.env.API_GATEWAY_ID as string;
  const stage = process.env.STAGE as string;
  const methodArn = `arn:aws:execute-api:${region}:${accountId}:${apiId}/${stage}/*`;
  // 以下のように実装するとキャッシュの有効期間(TTL)中は、同一APIにしかリクエストできなくなります
  // const methodArn = event.methodArn;
  try {
    return generatePolicy('user', 'Allow', methodArn);
  } catch (error) {
    logger.error({
      ...(error as UnauthorizedError),
    });
    return generatePolicy('user', 'Deny', methodArn);
  }
});
export const generatePolicy = (principalId: string, effect: string, resource: string): APIGatewayAuthorizerResult => {
  const authResponse: APIGatewayAuthorizerResult = {
    principalId: principalId,
    policyDocument: {
      Version: '2012-10-17',
      Statement: [
        {
          Action: 'execute-api:Invoke',
          Effect: effect,
          Resource: resource,
        },
      ],
    },
  };
  return authResponse;
};

Resource policiesのユースケース


                Diagram showing  Amazon API Gateway Resource Policy based on IP CIDR

リクエスターが事前に特定されている場合に有効な方法です。リクエストクライアントの IP アドレスなどをもとに、アクセスを制限することが可能です。

リクエスターは特定の企業だけど、不特定多数が使用する可能性がある…場合は IAM 認証の使用を検討してください。

Mutual TLS authenticationのユースケース


                Diagram showing  API Gateway cross-account authorizers

IoT デバイスやアプリケーション間認証のようなケースでは、相互 TLS(mTLS)認証を設定することができます。API Gateway のエンドポイントにアクセスする際に、クライアントは証明書を提示して身元を確認する必要があります。また、mTLS を Lambda オーソライザーと組み合わせることで、よりきめ細かな認証メカニズムを実現することも可能です。証明書を事前に発行し提供できるユースケースにおいては有効です。

Lambdaへの権限設定は可能な限り最小に設定

Lambda 関数では、最小特権アクセスに従い、与えられた操作の実行に必要なアクセスのみを許可するようにしてください。必要以上の権限を持つロールを付けると、システムが悪用される可能性があります。

ただし、開発運用が大変になり工数に大きく影響のでる場合は、例えば AppSync のデータソースアクセスに対して以下のような IAM ロールを提供します。

${self:custom.awsResourcePrefix}には AWS リソースの Prefix が設定されます

# データソース=DynamoDB
AppSyncDynamoDBServiceRole:
  Type: 'AWS::IAM::Role'
  Properties:
    RoleName: '${self:custom.awsResourcePrefix}AppSyncDynamoRole'
    AssumeRolePolicyDocument:
      Version: '2012-10-17'
      Statement:
        - Effect: 'Allow'
          Principal:
            Service:
              - 'appsync.amazonaws.com'
          Action:
            - 'sts:AssumeRole'
    Policies:
      - PolicyName: '${self:custom.awsResourcePrefix}AppSyncDynamoPolicy'
        PolicyDocument:
          Version: '2012-10-17'
          Statement:
            - Effect: 'Allow'
              Action:
                - 'dynamodb:PutItem'
                - 'dynamodb:ConditionCheckItem'
              Resource: !Sub 'arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${self:custom.awsResourcePrefix}*'

# データソース=Lambda
AppSyncLambdaServiceRole:
  Type: 'AWS::IAM::Role'
  Properties:
    RoleName: '${self:custom.awsResourcePrefix}AppSyncLambdaRole'
    AssumeRolePolicyDocument:
      Version: '2012-10-17'
      Statement:
        - Effect: 'Allow'
          Principal:
            Service:
              - 'appsync.amazonaws.com'
          Action:
            - 'sts:AssumeRole'
    Policies:
      - PolicyName: '${self:custom.awsResourcePrefix}AppSyncLambdaPolicy'
        PolicyDocument:
          Version: '2012-10-17'
          Statement:
            - Effect: 'Allow'
              Action:
                - 'lambda:invokeFunction'
              Resource: !Sub 'arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:${env:AWS_RESOURCE_PRIFIX}*'

VPC Lambdaには常に最小のルートテーブル&セキュリティグループを設定

万が一オープンソースのモジュールに対し悪意のあるスクリプトが含まれていた場合に情報漏洩やクラッキングの恐れがあります。VPC 内の Lambda はセンシティブなデータと通信する可能性が高いため、常に最小の設定になるように努めてください。また、Lambda は基本的には PrivateSubnet に配置し、インターネットや AWS リソースとの通信は、NAT または VPC エンドポイントを使用し行ってください。(VPC エンドポイントの方が NAT よりもコストが安い為、要件にフィットするなら VPC エンドポイントを推奨)

機密情報は常に暗号化して保持

サードパーティの API_KEY や SECRET_KEY 等々は、クラッキングは勿論の事、開発者自身にも見えないような工夫が必要です。プレーンテキストを SecretManager に暗号化して保持するか、あるいは KMS を使用して暗号化することを検討してください。

RDSへの接続はRDS Proxyを経由で行う&パスワードローテーション実行

RDS Proxy の SecretManager との連携機能を使用して、RDS への問い合わせを行うように設計します。アンチパターンは、RDS のマスターパスワードをプレーンテキストで例えば Lambda の環境変数等々に保持することです。RDS Proxy は Lambda と RDS で直接通信した場合のコネクションプールリミットを防止してくれますので、Lambda×RDS環境で使わない手はありません。

尚、RDS のパスワードは確実にローテーションさせてください。データベースのパスワードの漏洩は死活問題と心得てください。

設計で意識すべきこと総括

AWS Well-Architected Framework – Updated White Papers, Tools, and Best  Practices | AWS News Blog

AWS の Well-Architected フレームワークに則り、以下の事項を意識の上設計を行ってください。

スピーディ、シンプル、単一

ファンクションは簡潔で、短く・単一目的に実装し、リクエストのライフサイクルに沿うものである。一つのLambda 関数に全ての処理をデプロイする行為は、マイクロアーキテクチャ―の原則からも外れ推奨されません。

また、トランザクションは効率的にコストを考慮するため、より速い開始が推奨されます。

総リクエスト数ではなく、同時リクエストを考える

サーバーレス構成はスロットリングのリスクを抱えます。そのため、サーバーレス・アプリケーションは同時実行モデルを活用し、設計段階で確実に同時実行数を試算してください。

AWSリソース間を疎結合に構築

実行環境と基盤となる Lambda 等のコンピュートリソースは短命であるため、一時ストレージなどのローカルリソース(例えば Lambda の/tmp 領域)は保証されません。

ハードウェアに依存したコードは実装しない

基盤となるインフラは AWS が運用しています。そのため、例えば Lambda の OS などは更新される可能性があります。ハードウェアに依存しないコードを実装してください。

単一の関数ではなく、ステートマシンでアプリケーションをオーケストレーションする

アプリケーションのワークフローをオーケストレーションするために、コード内で Lambda 実行を Invoke すると、モノリシックで密結合なアプリケーションになってしまいます。 その代わりに、StepFunctions 等を活用し、ステートマシンを使ってトランザクションと通信フローをオーケストレーションしてください。

イベント駆動型の設計

Amazon S3 へのオブジェクト書き込みや DynamoDB のアイテム変更イベントは、ビジネス機能に応じてトランザクションな実行を可能にします。この非同期イベントによる設計アプローチは、多くの場合コンシューマに依存せず、無駄のないサービス設計を実現できます。

失敗と重複を考慮した設計

リクエストやイベントからトリガーされるオペレーションは、失敗する可能性があり、与えられたリクエストやイベントが複数回配信される可能性があるため、冪等でなければなりません。

例えば SQS からメッセージをポーリングする Lambda 関数は、非同期実行においては冪等性を考慮した実装を行わなければいけません。

セキュリティは常に最小を心がける

コンピュートリソースに不要なアクセス権限を与えないでください。常に必要最低限の権限を付与してください。

まとめ

本記事では、AWS の設計〜セキュリティ考慮に関する実践的な内容をまとめました。AWS の開発プロジェクトに関わるヒトは以下の点も意識し日々業務に取り組んでみてください!

  • AWS Well-Architected を常に Watch する、設計思想を常にアップデートする
  • 設計に銀の弾丸はない、ベストプラクティスは要件次第で常に変わる
  • 技術ファーストではなく、ビジネス要件ファーストで検討する、無理やり型にはめようとしない

サーバーレスの開発はお気軽にお問い合わせください。