【2020年度冬季】第一回 AWS Amplify 認定試験 〜解答・解説編〜


本エントリは[AWS Amplify Advent Calendar 2020](https://qiita.com/advent-calendar/2020/amplify) の８日目の記事である[【2020年度冬季版】第一回 AWS Amplify 認定試験](https://qiita.com/tamizuma/items/b4597240049829781749)の解答・解説編です。

まだAWS Amplify認定試験認定試験にチャレンジできていない方はこちらから問題を確認してみましょう！

## 第一回 AWS Amplify 認定試験 〜回答・解説編〜

### 問1.  B
それぞれのコマンドの意味は以下の通りです。

`amplify configure`: ローカルマシンでAmplify CLIを設定するためにAWSアカウントに接続するように設定することができます
`amplify init`: プロジェクトのrootフォルダにてこのコマンドを発行すると、amplifyプロジェクトを初期化することができます。このコマンドが正しく発行されたのちに`amplify add ${category}`でカテゴリを追加することができます。
`amplify add ${category}`: はAmplify のカテゴリを追加するコマンドです
amplify projectというコマンドは存在しません。

（参考）
https://docs.amplify.aws/cli/start/install#option-2-follow-the-instructions

### 問2.  D
amplify pull コマンドで既存のAmplfiy プロジェクトのバックエンド情報をクラウドから取得することができます。amplify loadというコマンドは存在しません。

（参考）
https://docs.amplify.aws/cli/start/workflows#amplify-category-add

### 問3.  A,B,C,D
amplify cliでは、Cognito UserPoolで利用可能なソーシャルプロバイダとしてAmazon、Apple、Facebook、Googleを選択できます。

（参考）
https://docs.amplify.aws/lib/auth/social/q/platform/js#setup-your-auth-provider

### 問4.  B,C
Amplify ConsoleはWAFとのインテグレーションがサポートされておらず、AuthカテゴリからWAFによるIP制限を設定することはできません。社外ユーザによるサインアップを防ぐにはサインアップ時に必要なEmailのドメインを社内ドメインに限定する方法が考えられます。ドメイン設定は`amplify add auth`もしくは`amplify update auth`から設定を行うことができます。

（参考）
https://docs.amplify.aws/cli/usage/lambda-triggers#email-domain-filtering-deny-list-and-email-domain-filtering-allow-list

対象のユーザを人事用グループに参加させることで、人事用グループに所属するかどうかに応じてアプリケーションの実装を切り替えることができます。また、Amplify から AWS AppSyncを用いる場合、@auth ディレクティブを用いることで、特定のグループに所属したユーザのみAPIの実行権限を与えることが可能です。例えば、以下のスキーマでは、HRグループに所属するユーザのみ、Payment情報のCreate/Update/Read/Deleteの操作を行うことができます。

```graphql
Payment @model @auth(
    rules: [{ allow: groups, groups: ["Admin"] }]
  )
  {
  employeeId: ID!
  employeeName: String!
  paymentAmount: Int!
}
```

（参考）
https://docs.amplify.aws/cli/graphql-transformer/auth#auth

OAuthフローによるログインを許可するのは今回の要件では適切ではないため、選択肢Dは誤りです。

### 問5. C,D

@keyディテクティブ の`fields`パラメータに2つの値を設定した場合、1つ目のパラメータがPartition Key、2つ目のパラメータにSort Keyが指定されます。`itemsByStatus`は第1パラメータに`status`フィールド、第2パラメータに`createdAt`フィールドが指定されているため、Partition Keyに`status`を指定して`createdAt`でソートした一覧結果を取得することができます。よって、Cは正しい選択肢です。
@keyディテクティブの`fields`に3つ以上の値を指定した場合、1つ目のパラメータがPartition Key、2番目以降に指定した項目を「#」で結合した文字列がSort Keyとして設定されます。

`@key(fields: ["orderId", "status", "createdAt"])` の場合、Partition Key、Sort Keyがそれぞれ以下のようになります。
* **Partition Key** : orderId
* **Sort Key** : status#createdAt

Sort Keyは前方一致による検索が可能なため、`orderId`、`status`に値を指定して、`createdAt`でソートした一覧結果を得ることができます。例として、`orderId`に”order1”と`status` に“IN_TRANSIT”を指定する場合、以下のようなクエリが発行可能です。

```graphql
query ListInTransitItemsForOrder {
  listItems(orderId:"order1", statusCreatedAt: { beginsWith: { status: IN_TRANSIT}}) {
    items {
      orderId
      status
      createdAt
      name
    }
  }
}
```

`@key(fields: ["orderId", "status", "createdAt"])` はテーブル自体のPartition Key、Sort Keyを指定する設定のため、選択肢Aは誤りです。
Sort Keyが指定されている場合、Partition Keyだけで一意にレコードを特定することはできないため、選択肢Bは誤りです。
`createdAt`の属性はスキーマ作成時に自動的に付与されるため、選択肢Eも誤りです。

（参考）
https://docs.amplify.aws/cli/graphql-transformer/key#designing-data-models-using-key

### 問6. D
@connectionディレクティブの has-one パターンの場合、子テーブルであるTeamから親テーブルであるProjectの要素を参照することはできません。よって、Dが誤ったクエリになります。

（参考）
https://docs.amplify.aws/cli/graphql-transformer/connection#has-one

### 問7.  B,E
@auth ディレクティブでは`rules`に設定を追加することで、きめ細やかなデータアクセス制限を実装することができます。
`ownerField`では、データのオーナー(データを作成したユーザ)のみが指定された操作を行うことができるよう制御することができます。(`ownerField`の設定を用いるには認証プロバイダーにCognito UserPoolを指定している必要があります)
今回の例では`ownerField`に`owner`フィールドが指定されており、このフィールドにはCognito UserPoolのusernameが書き込まれます。データ操作を試みるCognito Userのusernameとownerフィールドの値が一致する場合にのみ[create,update,read,delete]の操作が許可されます。よって、Eは正しい選択肢です。また、`operations`を省略した場合は、[create,update,read,delete]全ての操作が許可されます。Adminグループに所属するユーザは[create,update,read,delete]の権限を持つ設定となり、Bが正しい選択肢です。

明示的に指定しない限り、`ownerfield`にはGSIは付与されません。よって選択肢Aは誤りです。
Adminグループに所属しないユーザの場合、データのオーナーのみが[create,update,read]処理を実行できるため、選択肢Cは誤りです。
`operations`列は省略可能なため、選択肢Dも誤りです。

（参考）
https://docs.amplify.aws/cli/graphql-transformer/auth

### 問8. B
@functionディレクティブはAppSyncから呼び出すLambda(Lambdaリゾルバ)の追加を可能にします。
API GatewayのバックエンドにLambda処理を記述する場合は、`amplify add api` コマンドでAPIの種類にREST APIを選択肢ましす。

### 問9. A,B,C,D,E
（参考）
https://docs.amplify.aws/ui/q/framework/react

### 問10.  A,B,C,E

Amplify DataStoreは、開発者がデータへの変更を書き込み、読み取り、監視するための永続的なオンデバイスストレージリポジトリです。AWS アカウントを必要とせずに、ウェブおよびモバイルアプリケーションでスタンドアロンのローカルデータストアとして使用できます。ただし、クラウドバックエンドで使用する場合、Amplify DataStore は、ネットワーク接続が利用可能であれば、データを AWS AppSync (https://aws.amazon.com/appsync/) API と透過的に同期します。Amplify DataStore はデータを自動的にバージョン管理し、AppSync (https://aws.amazon.com/appsync/) を使用してクラウドで競合の検出と解決を実装します。

（参考）
https://aws.amazon.com/jp/blogs/news/amplify-datastore-simplify-development-of-offline-apps-with-graphql/
https://docs.amplify.aws/lib/datastore/getting-started/q/platform/js

### 問11.  D
Amplify DataStoreは@searchableディレクティブをサポートしていません。
https://docs.amplify.aws/cli/graphql-transformer/searchable#known-limitations

### 問12.  D
Amplify ConsoleはGithub、GitLab、BitBucket、AWS CodeCommit、zipファイルによる手動アップロードをサポートしています。

（参考）
https://docs.aws.amazon.com/ja_jp/amplify/latest/userguide/getting-started.html

### 問13.  A,B,C,E
A. App settings > General > Edit. のautodetectionをONにすると正規表現を用いたパターンベースのブランチデプロイの機能を利用することができます。
https://docs.aws.amazon.com/ja_jp/amplify/latest/userguide/pattern-based-feature-branch-deployments.html
B. パイプライン実行結果をEmailで通知することができます。
https://docs.aws.amazon.com/amplify/latest/userguide/notifications.html
C.ブランチごとにBasic 認証によるサイトの保護を設定することができます。
https://docs.aws.amazon.com/amplify/latest/userguide/access-control.html
D.Amplify ConsoleはAWS WAFと統合することはできません。
E.Cypressを用いたE2Eテストをパイプラインに簡単に組み込むことができます
https://docs.aws.amazon.com/amplify/latest/userguide/running-tests.html
F.Amplify Consoleでは静的サイトのホスティングをを想定しており、Server Side Renderingで構築されたアプリケーションのデプロイ機能はサポートしていません

### 問14.  B
Amplify ConsoleにはPreviews機能と呼ばれる機能があります。この機能はプルリクエストによる変更のプレビューを提供します。選択されたブランチに対しプルリクエストが発行されると、プレビュー用のウェブサイトをホストしてURLが払い出されます。Githubのプルリクエスト画面からプレビュー画面に遷移することが可能になります。
この機能はセキュリティ上の理由から、プレビューは、AmplifyCLIを使用するフルスタックアプリのプライベートリポジトリでのみ機能します。
https://docs.aws.amazon.com/amplify/latest/userguide/pr-previews.html

パブリックリポジトリではPreviews機能を設定することはできないため、選択肢Bが誤った選択肢になります。

### 問15.  A,D
Amplify ConsoleはSingle Page Application(SPA)や静的なHTMLサイトのホスティングを想定しています。また、Amplicy Consoleの利用にAmplify CLIやAmplify Libraryの利用は必須ではありません。
選択肢B,Cのようにモバイルアプリケーションや、サーバサイドのデプロイはサポートしていません。

### 問16.  A,C
Amplify CLI で新たに環境を複製するには、 `amplify add env ${環境名}` のコマンドを発行します。環境ごとに、AWS Profileを指定でき、環境ごとにAWSアカウントを分けることが可能です。
ホスティングされたアプリケーションがどのバックエンドの環境を参照するかは、Amplify Consoleから手動で設定を行う必要があります。
使用するバックエンドの環境を切り替えるにはコマンドラインから `amplify env checkout ${環境名}`のコマンドを発行します。その際に、aws-export.js (Javascriptの場合)の内容はAmplify CLIが自動的に更新を行います。

（参考）
https://www.slideshare.net/AmazonWebServicesJapan/20200520-aws-black-belt-online-seminar-aws-amplify-234663231/60

### 問17.  C
Amplify CLIのカテゴリがサポートしないAWSリソースを構築する場合は、任意のCloudFormationテンプレートファイルをカスタムカテゴリとして定義することができます。amplifyフォルダ配下にカテゴリを管理する「backend-config.json」というファイルがあり、このファイルを修正します。`amplify/backend/${カテゴリ名}/${リソース名}/`フォルダ配下に任意のCloudFormationテンプレートファイルを配置することで、Amplify CLIがサポートしていないリソースを定義することができます。

（参考）
https://www.slideshare.net/AmazonWebServicesJapan/20200520-aws-black-belt-online-seminar-aws-amplify-234663231/69 (https://www.slideshare.net/AmazonWebServicesJapan/20200520-aws-black-belt-online-seminar-aws-amplify-234663231/68)

### 問18.  C
Amplify Mockを用いることで、クラウド上にバックエンドを構築することなく、ローカル環境でモック、テストを行うことができます。Amplify MockはAWS AppSync、Amazon DynamoDB 、Amazon S3、AWS Lambdaのローカルモックをサポートしています。また、Amplify GraphQL ExplorerにブラウザからアクセスすることでGraphQLのテストを容易に行うことが可能です。利用にはクライアント端末にJavaがセットアップされている必要があります。
Amplify Mockを起動中は、aws-exports.js (Javascriptの場合)が自動的にMock環境の設定に置き換わるため、手動で設定を変更する必要はありません。

### 問19.  A,B,C,E,F
Amplify Mockは@searchableディレクティブをサポートしていません
https://docs.amplify.aws/cli/usage/mock#api-mocking-setup

### 問20.  D
`amplify import auth`コマンドで既存のCognito UserPool、Identity Providerの設定をインポートすることができます。importしたCognito UserPoolを認証プロバイダとしてAppSyncのエンドポイントを構築することも可能です。

A, Cognito UserPoolはユーザ情報のバックアップを取得することはできません。
B, 選択肢Bは既存のCognito UserPoolから別のUserPoolに移行を行う際に有効な方法です。`amplify import auth`を用いることで既存のUserPoolをそのまま使用できるため、もっとも適切な方法とは言えません。
C, `amplify add api` で既存のCognito UserPoolId、Identity Provider Idを指定することはできません。

よって、Dが正しい選択肢となります。

（参考）
https://docs.amplify.aws/cli/auth/import
https://aws.amazon.com/jp/blogs/mobile/use-existing-cognito-resources-for-your-amplify-api-storage-and-more/


---

### [復習のために] Amplifyの学習お役立ちリンク集

https://github.com/aws-amplify-jp/awesome-aws-amplify-ja

### お疲れ様でした！

試験は以上になります！
みなさん何点取れたでしょうか？初見で合格点取れた人はかなりすごいと思います
年末年始のAmplifyキャッチアップにお役立てください！


※ 問題・回答の不備などについてはコメント欄で受け付けます🙇‍♂🙇‍♂🙇‍♂