【2020年度冬季】第一回 AWS Amplify 認定試験

こんにちは！
本エントリは[AWS Amplify Advent Calendar 2020](https://qiita.com/advent-calendar/2020/amplify)の８日目の記事です。

みなさんAmplify 使ってますか！？
最近はAmplifyもどんどん機能が増えてきてキャッチアップが追いついていない・・という方も多いのではないでしょうか。
今回は「Amplify認定試験」というものを作ってみました。後半に解説も掲載しているので、Amplifyの力試し、Amplifyのキャッチアップにお役立てください！

### 試験概要

※ この試験は、AWS認定試験とは無関係です。筆者が勝手にやっているものです。
※ この記事は 2020/12/02 時点での情報に基づいた内容となります。
※ 配点は1問5点、問題数20問の計100点満点とします。
※ 合格点は **65点以上** とします。

--- 

### 問1: プロジェクトにAmplifyを導入する際に、アプリケーションのrootディレクトリにて発行すべきコマンドは次のうちどれか？

**【A】** amplify configure
**【B】** amplify init
**【C】** amplify add auth
**【D】** amplify project



### 問2: Amplify CLIで構築されたバックエンドの情報をクラウドから取得するコマンドは次のうちどれか？

**【A】** amplify configure
**【B】** amplify init
**【C】** amplify load
**【D】** amplify pull

### 問3. Amplify CLIから指定可能なCognito UserPoolのソーシャルプロバイダを全て選べ

- [ ] **【A】** Amazon
- [ ] **【B】** Apple
- [ ] **【C】** Facebook
- [ ] **【D】** Google
- [ ] **【E】** Twitter

### 問4. あなたはAmplifyを用いて従業員の人事情報を管理するWebアプリケーションを構築しています。このアプリケーションは会社に所属する従業員のみ認証できる必要があり、社外ユーザのサインアップ、サインインを防ぐ必要があります。また、人事部に所属するユーザとそれ以外のユーザで操作できる機能を分ける必要があります。このWebアプリケーションはAmplify Consoleにホスティングされています。Amplify CLIからこれらの要件を設定するために適切な選択肢を2つ選べ

- [ ] **【A】** `amplify add auth`コマンドからAWS WAFによるIP制限を追加し、社内ネットワークからのみアクセスできるよう設定する
- [ ] **【B】** `amplify add auth`コマンドからSing Upの必須属性にEmailを指定し、Sing UpできるEmailのドメインを社内ドメインに限定する
- [ ] **【C】** `amplify add auth`コマンドからCognito Groupに人事部用グループを作成し、対象のユーザを人事用グループに参加させる
- [ ] **【D】** `amplify add auth`コマンドからOAuthフローを追加し、Facebook認証の設定を追加する



### 5. graphql.schema のスキーマ定義について正しい記述を2つ選べ

```graphql

type Item @model
  @key(fields: ["orderId", "status", "createdAt"])
  @key(name: "itemsByStatus", fields: ["status", "createdAt"], queryField: "itemsByStatus") {
  orderId: ID!
  status: Status!
  createdAt: AWSDateTime!
  name: String!
}
enum Status {
  DELIVERED
  IN_TRANSIT
  PENDING
  UNKNOWN
}
```

- [ ] **【A】** このスキーマ定義から作成されるDynamoDBのテーブルにはorderId、statusをそれぞれパーティションキーとした2つGSIが作成される
- [ ] **【B】** orderIdを指定することで一意にレコードを指定できる
- [ ] **【C】** statusを指定して、createdAtでソートしたリストの結果を取得することができる
- [ ] **【D】** orderId、statusに値を指定して、createdAtでソートしたリストの結果を取得することができる
- [ ] **【E】** ItemテーブルにはcreatedAtの属性が定義されていないため、スキーマの作成に失敗する



### 6. graphql.schema のスキーマ定義に対して、_発行することができないクエリ_を1つ選べ

```graphql
type Project @model {
  id: ID!
  name: String
  teamID: ID!
  team: Team @connection(fields: ["teamID"])
}

type Team @model {
  id: ID!
  name: String!
}

```

**【A】**

```graphql

query GetProject($id: ID!) {
        getProject(id: $id) {
          id
          name
          teamID
          team {
            id
            name
            createdAt
            updatedAt
          }
          createdAt
          updatedAt
        }
      }
```

**【B】** 

```graphql
query GetTeam($id: ID!) {
        getTeam(id: $id) {
          id
          name
          createdAt
          updatedAt
        }
      }
```
**【C】** 

```graphql
query ListTeams {
      listTeams(filter:{
        name: {
          eq: "Team1"
        }
      }) {
        items {
          id
          name
          createdAt
          updatedAt
        }
        nextToken
      }
    }
```

**【D】** 

```graphql
query GetTeam($id: ID!) {
        getTeam(id: $id) {
          id
          name
          project: {
            id
            name
            teamID
            createdAt
            updatedAt
          }
          createdAt
          updatedAt
        }
      }
```

### 7. graphql.schema のスキーマ定義について正しい説明を2つ選べ

```graphql
type Device
  @model
  @auth(
    rules: [
      { allow: owner, ownerField: "owner", operations: [create,update,read, delete] }
      { allow: groups, groups: ["Admin"] }
    ]
  )
  @key(
    name: "deviceByStatus"
    fields: ["status", "createdAt"]
    queryField: "deviceByStatus"
  ) {
  id: ID!
  owner: String!
  name: String!
  status: Status
}

enum Status {
  ACTIVE
  INACTIVE
  UNKNOWN
}
```

- [ ] **【A】** このスキーマ定義から作成されるDynamoDBテーブルにはownerフィールドにGSIが付与される
- [ ] **【B】** Adminグループに所属しないユーザは、他のユーザが作成したレコードを削除できない
- [ ] **【C】** Adminグループに所属しないユーザの場合、全てのレコードに対して、読み込み、更新、新規レコードの作成を行うことができる
- [ ] **【D】** Adminグループには許可されたoperationsが定義されていないため全ての操作を行うことができない
- [ ] **【E】** Adminグループに所属しないユーザは自分が作成したレコードに対してのみ読み込み、更新、新規レコードの作成を行うことができる

### 8. スキーマ定義のディレクティブの説明について_誤ったもの_を1つ選べ

**【A】** @connection : @modelタイプ間の1：1、1：M、およびN：Mの関係を定義する
**【B】** @function : API GatewayのバックエンドとなるLambda関数を定義する
**【C】** @searchable :  Elasticsearchにストリーミングすることで、データ検索を可能にする
**【D】** @predictions : Amazon Rekognition、Amazon Translate、AmazonPollyなどのAI / MLサービスのオーケストレーションを照会する

### 9. Amplify UI Componenents がサポートするフレームワーク

- [ ] **【A】** React
- [ ] **【B】** React Native
- [ ] **【C】** Vue
- [ ] **【D】** Angular
- [ ] **【E】** Web Components
- [ ] **【F】** Flutter

### 10.  Amplify DataStore の記述に関して正しいものを全て選べ

- [ ] **【A】** Amplify DataStpreはネットワーク接続が利用可能であれば、データをAWS AppSyncと透過的に同期し、オフラインの場合はローカルストレージにデータを書き込むことができる
- [ ] **【B】** AWSアカウントがなくてもDataStoreを使用してデバイスのローカルストレージにデータの永続化できる
- [ ] **【C】** Amplify DataStoreを使用するには、Amplify CLI の `amplify add api` もしくは`amplify update api`からDataStoreの設定を有効にする必要がある
- [ ] **【D】** Amplify DataStoreはバックエンドの書き込みにGraphQL、REST APIをサポートする
- [ ] **【E】** 複数のクライアントが同時にデータを更新した場合、Amplify DataStoreはデータの競合検知と、その解消を試みる


### 11.  Amplify DataStore がサポートしていないディレクティブを一つ選べ

**【A】** @model
**【B】** @auth
**【C】** @connection
**【D】** @searchable


### 12.  Amplify Consoleへのソース連携方法の組み合わせで正しいものを一つ選べ

**【A】** Github、GitLab、AWS CodeCommit
**【B】** Github、BitBucket、AWS CodeCommit
**【C】** Github、GitLab、AWS CodeCommit、zipファイルによる手動アップロード
**【D】** Github、GitLab、BitBucket、AWS CodeCommit、zipファイルによる手動アップロード

### 13.  Amplify Consoleが提供する機能を全て選べ

- [ ] **【A】** Gitリソースに新たなブランチを検知した際に自動で新たなパイプラインを構築する機能
- [ ] **【B】** パイプライン実行結果のメール通知
- [ ] **【C】** Basic 認証によるサイトの保護
- [ ] **【D】** AWS WAF と統合されたサイトの保護
- [ ] **【E】** Cypressを用いたE2Eテスト
- [ ] **【F】** Server Side Rendering アプリケーションのデプロイ機能

### 14.  Amplify Consoleに関する記述について誤ったものを一つ選べ

**【A】** デプロイの設定はamplify.ymlに記述することができる
**【B】** Githubのパブリックリポジトリにプルリクエストが発行されたことをトリガーに、自動でパイプラインを構築することができる
**【C】** Amplify ConsoleでホスティングされたURLに、Route53やサードパーティプロバイダーに登録された任意のドメインを接続することができる
**【D】** Webhookからホスティングのパイプラインの起動することができる
**【E】** ホスティングされたアプリケーションのアクセスログを取得することができる

### 15.  Amplify Consoleでデプロイできるアプリケーションの種類について適切なものを2つ選べ

- [ ] **【A】** ReactやVue、Angularなどで構築されたSingle Page Application(SPA)のWebアプリケーション
- [ ] **【B】** iOSやAndroid、React Native、Flutterで構築されたMobileアプリケーション
- [ ] **【C】** Server Side Rendering(SSR)で構築されたWebアプリケーション
- [ ] **【D】** Amplify CLIやAmplify Libraryを用いないシンプルな静的Webアプリケーション

### 16.  Amplify CLIで複数のバックエンド環境を構築するにあたり正しい記述を2つ選べ

- [ ] **【A】** バックエンドの環境の複製にはコマンドラインから `amplify add env ${環境名}` のコマンドを発行する
- [ ] **【B】** Amplify CLIは複数のアカウントにまたがって環境を構築することができない
- [ ] **【C】** ホスティングされたアプリケーションがどのバックエンドの環境を参照するかは、Amplify Consoleから手動で設定を行う
- [ ] **【D】** 使用するバックエンドの環境を切り替えるにはコマンドラインから `amplify env checkout ${環境名}`のコマンドを発行し、aws-export.js (Javascriptの場合)の内容を手動で切り替える

### 17.  Amplify CLI からAmazon Auroraのインスタンスを構築する場合の操作について適切な記述を1つ選べ

**【A】** Amplify CLIではAmazon Auroraを構築するためのカテゴリをサポートしていないため、CloudFormationなどのAmplify CLI以外のプロビジョニングツールを用いる
**【B】** コマンドラインから`amplify add storage`コマンドを発行し、データベースタイプにauroraを選択する
**【C】** `amplify/backend/backend-config.json`に独自のカテゴリ定義を記述し、amplify/backend/${カテゴリ名}/${リソース名}/フォルダ配下にAmazon Auroraのインスタンスを構築するCloudFormationファイルを配置する
**【D】** `amplify add function`コマンドでAmazon Auroraインスタンスをプロビジョニングするカスタムカテゴリ用Lambdaファンクションを追加する

### 18.  Amplify Mockに関する記述で誤ったものを一つ選べ

**【A】** Amplify MockはAWS AppSync、Amazon DynamoDB 、Amazon S3、AWS Lambdaのローカルモックをサポートする
**【B】** Amplify MockはウェブブラウザからアクセスできるAmplify GraphiQL Explorerを用いて、Query/Mutation/Subscriptionのテストを行うことができる
**【C】** Amplify Mockを使用する場合は、aws-exports.jsに記載されているAppSyncやAPI Gateway のエンドポイントを全てlocalhost:20002に置き換える必要がある
**【D】** Amplify Mockの機能を使用するにはローカル端末にJavaがインストールされている必要がある
**【E】** AWSアカウントがなくてもAmplify Mockを使用することができる

### 19.  Amplify Mockがサポートするschema.graphqlのディレクティブを全て選べ

- [ ] **【A】** @auth
- [ ] **【B】** @key
- [ ] **【C】** @connection
- [ ] **【D】** @searchable
- [ ] **【E】** @versioned
- [ ] **【F】** @function

### 20.  あなたは既存のアプリケーションに、Amazon Cognito UserPoolを認証プロバイダとするAWS AppSyncの構築を検討しています。バックエンドの構築にはAmplify CLI、クライアントからバックエンドの接続にはAmplify Libraryを用いる予定です。既存のアプリケーションはすでにCognito UserPoolを用いた認証認可が実装されており、既に多くのユーザがこのアプリケーションを利用しています。既存のリソースを最大限活用しつつ、認証付きAppSyncの構築を行うのに最も適切な方法を一つ選べ。

**【A】** `amplify add auth`でCognito、`amplify add api`でAppSyncを構築し、認証プロバイダには新規に作成したCognito UserPoolを指定する。旧Cognito UserPoolからユーザ情報のバックアップを取得し、新規に作成したCognito UserPoolにユーザをimportする。ユーザのimportが完了した後に旧Cognitoを削除する。
**【B】** `amplify add auth`でCognito、`amplify add api`でAppSyncを構築し、認証プロバイダには新規に作成したCognito UserPoolを指定する。Cognito Lambda Triggersを用いて、Sign Inをトリガーに旧Cognito UserPoolから新Cognito UserPoolにデータを移行するLambdaを構築する。移行完了後に旧Cognitoを削除する。
**【C】** `amplify add api`でAppSyncを構築し、認証プロバイダの指定には、既存のCognito UserPool IdとIdentity Provider Idを指定する。
**【D】** `amplify import auth`コマンドで既存のCognitoをインポートする。`amplify add api`でAppSyncを構築し、認証プロバイダにはimportしたCognito UserPoolを指定する。


--- 
 
お疲れ様でした!!
長くなってしまったので、解答、解説は[【2020年度冬季版】第一回 AWS Amplify 認定試験 （解答編）](https://qiita.com/tamizuma/items/5436b0bc6fce6e769a62)の記事で掲載しています！