【2022年6月】AWS Amplify CLI セットアップマニュアル

# はじめに

いままでのAmplifyCLIのセットアップは下記の記事を参考にずっと行ってきましたが、そろそろバージョンも新しくなってきたので最新版でのセットアップ方法をまとめていきたいと思います。

[AWS Amplify CLIの使い方〜インストールから初期セットアップまで〜](https://qiita.com/Junpei_Takagi/items/f2bc567761880471fd54)

こちらの記事は、2018年に書かれており、Amplifyの始まりたての頃の記事ですが、初期の頃から本当にお世話になりました。ありがとうございます！！

# 環境
Amplify CLI 8.3.1
Node.js 14.19.2
npm 6.14.17

# セットアップ方法
## インストール
今回は、`8.3.1`のバージョンで設定を行っていきます。

```console
$ npm install -g @aws-amplify/cli@8.3.1
```

## AWSアカウントの紐付け

まずは以下のコマンドを実行します。

```console
$ amplify configure
```

そうするとAWSのログインフォームに飛ばされるので、紐付けをしたいAWSアカウントにログインしてください。

※この時にすでにログインしている状態のときは、自動でそのAWSアカウントでの紐付け設定に進みますので、紐付けたいAWSアカウント以外でログインしているときは注意が必要です。


コンソールに戻ってくると以下の表示がされていますので、Enterを押してください。

```console
Follow these steps to set up access to your AWS account:

Sign in to your AWS administrator account:
https://console.aws.amazon.com/
Press Enter to continue
```

### リージョン指定
自分の使いたいリージョンを指定してください。

```console
Specify the AWS Region
? region:  
  eu-west-2 
  eu-west-3 
  eu-central-1 
❯ ap-northeast-1 
  ap-northeast-2 
  ap-southeast-1 
  ap-southeast-2 
(Move up and down to reveal more choices)
```

私は、東京リージョンを使いたいので、`ap-northeast-1 `を選択します。

### IAMユーザーの作成
AmplifyCLI用のIAMユーザーを作成していきます。

```console
Specify the username of the new IAM user:
? user name:  (amplify-HsBk0) 
```

登録されるIAMユーザー名なので、表示されたusernameそのままでもいいですし、管理しやすいようにプロジェクト名の名前をつけるのもいいと思います。

名前を入力して、Enterを押すとAWSのGUI画面へ遷移しますので、IAMユーザーの作成を進めます。

![スクリーンショット 2022-06-02 19.13.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252427/36bc75ba-e037-b295-4924-33cf82af3d96.png)


必ず`アクセスキー - プログラムによるアクセス`にチェックが入っていることを確認して、次へ進みます。

![スクリーンショット 2022-06-02 19.15.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252427/81238292-1f3d-1f6b-ce2d-d97015efd348.png)


次に進むと`AdministratorAccess-Amplify`にチェックが入っていますが、こちらのポリシーは正確には、AmpliyConsole用のポリシー(2022.2に公式サポート確認)だそうでAmplifyCLIのドキュメントにあるポリシー内容よりも権限がたくさんある状態になります。(多いだけなので、確か問題なくAmplifyCLIは動いたはず、、、。)

[AmplifyCLIの公式ドキュメント](https://docs.amplify.aws/cli/reference/iam/)に、AmplifyCLI専用のIAMポリシー例が記載されていますので、AmplifyCLIの権限を絞っておきたい方は、予めこちらのポリシーをコピペしてAmplifyCLI専用のポリシーを作っておいてから、そのポリシーを紐付けるといいかと思います。

ただし、上記のIAMポリシーをそのままコピペすると以下のトラブルが起きましたので、参考までに記載しておきます。(2022.6.2時点)

1. そのままコピペだとファイルサイズが大きすぎると起こられるため2分割してポリシーを作成する必要がある
2. セキュリティ1とエラー1が出る(そのままでも保存できるし、動作に支障はないが、、、。)
3. `"lambda:ListTags",`など手動で追加しないとエラーが発生する

2022.6.2時点では、以下のポリシーを2分割(個人的には使うものと使わないものを分けてます。)して、その2つのポリシーをAmplify用IAMユーザーに付与しています。

2022.10.20時点、ドキュメントにはまだ記載されていませんが、`"lambda:TagResource",`の権限を追加しないとfuntionの作成ができなくなったため、追加しています。

```json:AmplifyCLI-Main
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "amplify:CreateApp",
                "amplify:CreateBackendEnvironment",
                "amplify:CreateBranch",
                "amplify:DeleteApp",
                "amplify:DeleteBackendEnvironment",
                "amplify:DeleteBranch",
                "amplify:GetApp",
                "amplify:GetBackendEnvironment",
                "amplify:GetBranch",
                "amplify:ListApps",
                "amplify:ListBackendEnvironments",
                "amplify:ListBranches",
                "amplify:ListDomainAssociations",
                "amplify:UpdateApp",
                "apigateway:DELETE",
                "apigateway:GET",
                "apigateway:PATCH",
                "apigateway:POST",
                "apigateway:PUT",
                "appsync:CreateApiKey",
                "appsync:CreateDataSource",
                "appsync:CreateFunction",
                "appsync:CreateGraphqlApi",
                "appsync:CreateResolver",
                "appsync:CreateType",
                "appsync:DeleteApiKey",
                "appsync:DeleteDataSource",
                "appsync:DeleteFunction",
                "appsync:DeleteGraphqlApi",
                "appsync:DeleteResolver",
                "appsync:DeleteType",
                "appsync:GetDataSource",
                "appsync:GetFunction",
                "appsync:GetGraphqlApi",
                "appsync:GetIntrospectionSchema",
                "appsync:GetResolver",
                "appsync:GetSchemaCreationStatus",
                "appsync:GetType",
                "appsync:GraphQL",
                "appsync:ListApiKeys",
                "appsync:ListDataSources",
                "appsync:ListFunctions",
                "appsync:ListGraphqlApis",
                "appsync:ListResolvers",
                "appsync:ListResolversByFunction",
                "appsync:ListTagsForResource",
                "appsync:ListTypes",
                "appsync:StartSchemaCreation",
                "appsync:TagResource",
                "appsync:UpdateApiKey",
                "appsync:UpdateDataSource",
                "appsync:UpdateFunction",
                "appsync:UpdateGraphqlApi",
                "appsync:UpdateResolver",
                "appsync:UpdateType",
                "cloudformation:CreateChangeSet",
                "cloudformation:CreateStack",
                "cloudformation:CreateStackSet",
                "cloudformation:DeleteStack",
                "cloudformation:DeleteStackSet",
                "cloudformation:DescribeChangeSet",
                "cloudformation:DescribeStackEvents",
                "cloudformation:DescribeStackResource",
                "cloudformation:DescribeStackResources",
                "cloudformation:DescribeStacks",
                "cloudformation:DescribeStackSet",
                "cloudformation:DescribeStackSetOperation",
                "cloudformation:ExecuteChangeSet",
                "cloudformation:GetTemplate",
                "cloudformation:GetTemplateSummary",
                "cloudformation:ListStackResources",
                "cloudformation:UpdateStack",
                "cloudformation:UpdateStackSet",
                "cloudfront:CreateCloudFrontOriginAccessIdentity",
                "cloudfront:CreateDistribution",
                "cloudfront:DeleteCloudFrontOriginAccessIdentity",
                "cloudfront:DeleteDistribution",
                "cloudfront:GetCloudFrontOriginAccessIdentity",
                "cloudfront:GetCloudFrontOriginAccessIdentityConfig",
                "cloudfront:GetDistribution",
                "cloudfront:GetDistributionConfig",
                "cloudfront:TagResource",
                "cloudfront:UntagResource",
                "cloudfront:UpdateCloudFrontOriginAccessIdentity",
                "cloudfront:UpdateDistribution",
                "cognito-identity:CreateIdentityPool",
                "cognito-identity:DeleteIdentityPool",
                "cognito-identity:DescribeIdentity",
                "cognito-identity:DescribeIdentityPool",
                "cognito-identity:GetIdentityPoolRoles",
                "cognito-identity:ListIdentityPools",
                "cognito-identity:SetIdentityPoolRoles",
                "cognito-identity:TagResource",
                "cognito-identity:UpdateIdentityPool",
                "cognito-idp:AdminAddUserToGroup",
                "cognito-idp:AdminCreateUser",
                "cognito-idp:CreateGroup",
                "cognito-idp:CreateUserPool",
                "cognito-idp:CreateUserPoolClient",
                "cognito-idp:DeleteGroup",
                "cognito-idp:DeleteUser",
                "cognito-idp:DeleteUserPool",
                "cognito-idp:DeleteUserPoolClient",
                "cognito-idp:DescribeIdentityProvider",
                "cognito-idp:DescribeUserPool",
                "cognito-idp:DescribeUserPoolClient",
                "cognito-idp:GetUserPoolMfaConfig",
                "cognito-idp:ListIdentityProviders",
                "cognito-idp:ListTagsForResource",
                "cognito-idp:ListUserPoolClients",
                "cognito-idp:ListUserPools",
                "cognito-idp:UpdateGroup",
                "cognito-idp:UpdateUserPool",
                "cognito-idp:UpdateUserPoolClient",
                "dynamodb:CreateTable",
                "dynamodb:DeleteItem",
                "dynamodb:DeleteTable",
                "dynamodb:DescribeContinuousBackups",
                "dynamodb:DescribeTable",
                "dynamodb:DescribeTimeToLive",
                "dynamodb:ListStreams",
                "dynamodb:ListTables",
                "dynamodb:PutItem",
                "dynamodb:TagResource",
                "dynamodb:UpdateContinuousBackups",
                "dynamodb:UpdateItem",
                "dynamodb:UpdateTable",
                "dynamodb:UpdateTimeToLive",
                "es:AddTags",
                "es:CreateElasticsearchDomain",
                "es:DeleteElasticsearchDomain",
                "es:DescribeElasticsearchDomain",
                "events:DeleteRule",
                "events:DescribeRule",
                "events:ListRuleNamesByTarget",
                "events:PutRule",
                "events:PutTargets",
                "events:RemoveTargets",
                "iam:AttachRolePolicy",
                "iam:CreatePolicy",
                "iam:CreatePolicyVersion",
                "iam:CreateRole",
                "iam:CreateServiceLinkedRole",
                "iam:DeletePolicy",
                "iam:DeletePolicyVersion",
                "iam:DeleteRole",
                "iam:DeleteRolePermissionsBoundary",
                "iam:DeleteRolePolicy",
                "iam:DetachRolePolicy",
                "iam:GetPolicy",
                "iam:GetRole",
                "iam:GetRolePolicy",
                "iam:GetUser",
                "iam:ListAttachedRolePolicies",
                "iam:ListPolicyVersions",
                "iam:PassRole",
                "iam:PutRolePermissionsBoundary",
                "iam:PutRolePolicy",
                "iam:TagRole",
                "iam:UpdateRole",        
                "iam:UpdateAssumeRolePolicy",
                "kinesis:AddTagsToStream",
                "kinesis:CreateStream",
                "kinesis:DeleteStream",
                "kinesis:DescribeStream",
                "kinesis:DescribeStreamSummary",
                "kinesis:ListTagsForStream",
                "kinesis:PutRecords",
                "lambda:AddLayerVersionPermission",
                "lambda:AddPermission",
                "lambda:CreateEventSourceMapping",
                "lambda:CreateFunction",
                "lambda:DeleteEventSourceMapping",
                "lambda:DeleteFunction",
                "lambda:DeleteLayerVersion",
                "lambda:GetEventSourceMapping",
                "lambda:GetFunction",
                "lambda:GetFunctionConfiguration",
                "lambda:GetLayerVersion",
                "lambda:InvokeAsync",
                "lambda:InvokeFunction",
                "lambda:ListTags",
                "lambda:ListEventSourceMappings",
                "lambda:ListLayerVersions",
                "lambda:PublishLayerVersion",
                "lambda:RemoveLayerVersionPermission",
                "lambda:RemovePermission",
                "lambda:TagResource",
                "lambda:UpdateFunctionCode",
                "lambda:UpdateFunctionConfiguration",
                "logs:DescribeLogStreams",
                "logs:GetLogEvents",
                "s3:CreateBucket",
                "s3:DeleteBucket",
                "s3:DeleteBucketPolicy",
                "s3:DeleteBucketWebsite",
                "s3:DeleteObject",
                "s3:DeleteObjectVersion",
                "s3:GetBucketLocation",
                "s3:GetObject",
                "s3:HeadBucket",
                "s3:ListAllMyBuckets",
                "s3:ListBucket",
                "s3:ListBucketVersions",
                "s3:PutBucketAcl",
                "s3:PutBucketCORS",
                "s3:PutBucketNotification",
                "s3:PutBucketPolicy",
                "s3:PutBucketWebsite",
                "s3:PutEncryptionConfiguration",
                "s3:PutObject",
                "s3:PutObjectAcl",
                "cognito-idp:SetUserPoolMfaConfig"
            ],
            "Resource": "*"
        }
    ]
}
```

```json:AmplifyCLI-Others
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "lex:GetBot",
                "lex:GetBuiltinIntent",
                "lex:GetBuiltinIntents",
                "lex:GetBuiltinSlotTypes",
                "mobiletargeting:CreateApp",
                "mobiletargeting:DeleteApnsChannel",
                "mobiletargeting:DeleteApnsSandboxChannel",
                "mobiletargeting:DeleteApp",
                "mobiletargeting:DeleteEmailChannel",
                "mobiletargeting:DeleteGcmChannel",
                "mobiletargeting:DeleteSmsChannel",
                "mobiletargeting:GetApnsChannel",
                "mobiletargeting:GetApnsSandboxChannel",
                "mobiletargeting:GetApp",
                "mobiletargeting:GetEmailChannel",
                "mobiletargeting:GetGcmChannel",
                "mobiletargeting:GetSmsChannel",
                "mobiletargeting:UpdateApnsChannel",
                "mobiletargeting:UpdateApnsSandboxChannel",
                "mobiletargeting:UpdateEmailChannel",
                "mobiletargeting:UpdateGcmChannel",
                "mobiletargeting:UpdateSmsChannel",
                "rekognition:DescribeCollection"
            ],
            "Resource": "*"
        }
    ]
}
```

あとはタグの追加したい人だけ追加して、ユーザーを作成します。

作成完了すると以下の画面になります。

![スクリーンショット 2022-06-03 22.44.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252427/a67b4f23-30ea-87a5-a9f3-df9411b380ed.png)

次にアクセスキーIDとシークレットアクセスキーを使うのでコピーしておきます。


### IAMユーザーの紐付け
コンソールに戻ってくると以下のメッセージが出ているので、Enterを押します。

```
? user name:  amplify-xxxxxxx
Complete the user creation using the AWS console
https://console.aws.amazon.com/iam/home?{-- 省略 --}
Press Enter to continue
```

先程コピーしたアクセスキーIDとシークレットアクセスキーを貼り付けます。

```console
Enter the access key of the newly created user:
? accessKeyId:  ********************
? secretAccessKey:  ****************************************

```

### ローカルのプロフィール作成

プロフィール名は、複数のプロジェクトのAmplifyCLIを設定しない人はdefaultのままでいいかと思いますが、これから同じPCで複数プロジェクトを触る可能性がある場合は、プロジェクトごとの名前(amplify-project_name)とかが管理しやすくていいかと思います。

```console
This would update/create the AWS Profile in your local machine
? Profile Name:  (default)  
```

これで紐付け作業は終了です。

## Amplifyプロジェクトの初期設定

紐付けが終わったので、早速AmplifyCLIを使ったプロジェクトの作成を進めていきます。

```console
$ amplify init
```

プロジェクト名を決めます。

```console
? Enter a name for the project <project_name>
```

以前は以下の設定がすべて聞かれましたが、デフォルトでこれでいいですか？と聞かれます。変更をしたい場合は、noを選択して、各項目を変更します。

``

```console
Project information
| Name: <project_name>
| Environment: dev // 環境名
| Default editor: Visual Studio Code // 使用するエディタ
| App type: javascript // js/ios/android/flutter
| Javascript framework: none // フロントエンドのフレームワーク指定
| Source Directory Path: src // プロジェクト内のソースディレクトリパス
| Distribution Directory Path: dist  // 配布用ディレクトリパス
| Build Command: npm run-script build  // ビルドコマンド(使ったこと無い)
| Start Command: npm run-script start // スタートコマンド(使ったこと無い)
? Initialize the project with the above configuration? (Y/n) 
```

上記の設定が終わると今回のAmplifyプロジェクトにどの権限を使うか聞かれますので、先ほど作成したローカルのプロフィールと紐付けます。

まずは、`AWS profile`を選択してください。

```console
? Select the authentication method you want to use: (Use arrow keys)
❯ AWS profile 
  AWS access keys 
```

先程作成したプロフィール名を選択します。

```console
  default 
❯ amplify-project_name
```

すると自動的に初期化作業が始まります。

```console
Adding backend environment dev to AWS Amplify app: xxxxxxxxxxxxx
⠇ Initializing project in the cloud...

CREATE_IN_PROGRESS amplify-officeapp-dev-213646 AWS::CloudFormation::Stack Fri Jun 03 2022 21:36:47 GMT+0900 (GMT+09:00) User Initiated
CREATE_IN_PROGRESS AuthRole                     AWS::IAM::Role             Fri Jun 03 2022 21:36:51 GMT+0900 (GMT+09:00)               
CREATE_IN_PROGRESS DeploymentBucket             AWS::S3::Bucket            Fri Jun 03 2022 21:36:51 GMT+0900 (GMT+09:00)               
CREATE_IN_PROGRESS UnauthRole                   AWS::IAM::Role             Fri Jun 03 2022 21:36:51 GMT+0900 (GMT+09:00)               
⠋ Initializing project in the cloud...

CREATE_IN_PROGRESS AuthRole         AWS::IAM::Role  Fri Jun 03 2022 21:36:53 GMT+0900 (GMT+09:00) Resource creation Initiated
CREATE_IN_PROGRESS UnauthRole       AWS::IAM::Role  Fri Jun 03 2022 21:36:53 GMT+0900 (GMT+09:00) Resource creation Initiated
CREATE_IN_PROGRESS DeploymentBucket AWS::S3::Bucket Fri Jun 03 2022 21:36:53 GMT+0900 (GMT+09:00) Resource creation Initiated
⠦ Initializing project in the cloud...

CREATE_COMPLETE DeploymentBucket AWS::S3::Bucket Fri Jun 03 2022 21:37:15 GMT+0900 (GMT+09:00) 
⠇ Initializing project in the cloud...

CREATE_COMPLETE AuthRole AWS::IAM::Role Fri Jun 03 2022 21:37:21 GMT+0900 (GMT+09:00) 
⠏ Initializing project in the cloud...

CREATE_COMPLETE UnauthRole AWS::IAM::Role Fri Jun 03 2022 21:37:22 GMT+0900 (GMT+09:00) 
⠏ Initializing project in the cloud...

CREATE_COMPLETE amplify-officeapp-dev-213646 AWS::CloudFormation::Stack Fri Jun 03 2022 21:37:25 GMT+0900 (GMT+09:00) 
✔ Successfully created initial AWS cloud resources for deployments.
✔ Initialized provider successfully.
✅ Initialized your environment successfully.

Your project has been successfully initialized and connected to the cloud!

Some next steps:
"amplify status" will show you what you've added already and if it's locally configured or deployed
"amplify add <category>" will allow you to add features like user login or a backend API
"amplify push" will build all your local backend resources and provision it in the cloud
"amplify console" to open the Amplify Console and view your project status
"amplify publish" will build all your local backend and frontend resources (if you have hosting category added) and provision it in the cloud

Pro tip:
Try "amplify add api" to create a backend API and then "amplify push" to deploy everything
```

たったこれだけでAmplifyのプロジェクトが作成されました。
セットアップ完了です。


# リソース/参考記事
セットアップ後にためになる記事をご紹介。色々記事書いてますので、ご参考までに。

## api (AppSync)

https://qiita.com/too/items/c0ce14d16772b9f71223

https://qiita.com/too/items/f9078803ea394c35df7d

https://qiita.com/too/items/ab6b313da9f9e34be4a7

https://qiita.com/too/items/fae2879ea36f00c3ae10

https://qiita.com/too/items/0e9f5ca5227a090594b4

https://qiita.com/too/items/37ea2a2b87268fbba4e8

https://qiita.com/too/items/982dff46f9e70d5226d4


## auth (Cognito)
https://qiita.com/too/items/fc961283dcbef3aafdeb

https://qiita.com/too/items/54992bb871fc1a2ab101

https://qiita.com/too/items/52f35860bcb5bdf5e667

## function (Lambda)
https://qiita.com/too/items/d2732b3ec625011f4567

https://qiita.com/too/items/b34cbfd7e96a01e33f23

https://qiita.com/too/items/54de781085bd9a3a66d0


## storage (S3)
https://qiita.com/too/items/361bc10b6d27f133e9f8


## env (amplifyの複数環境の構築)
https://qiita.com/too/items/5c1e28cf95fc6229547e


## SSR設定
https://qiita.com/too/items/08937252b9352507fa39

## 全般
https://qiita.com/too/items/e6f56297d1066d6affe6

https://qiita.com/too/items/8a3c75d094bc9441f4bf

## その他/豆知識
https://qiita.com/too/items/b423fee28fd210bacd71

https://qiita.com/too/items/f11957064ba9c1053674

# 公式ドキュメント
https://docs.amplify.aws/cli/

# おわりに

皆様、よきAmplifyライフを！