Amplifyのデプロイで「Ops...」だったことーアプリケーションの構築とデプロイー

ご挨拶

みなさん、こんにちは ぎりぎり1年目エンジニアの佐々木です。

 

さて、今回はAmplifyのデプロイで…という題を銘打ちましたが、若干特殊です。 というのも、「開発環境のAWS環境」にはデプロイしているアプリケーションを、本番環境として用意している「別のAWS環境」にデプロイ(移行?)する、というものだからです。

 

よくあるような(?)同じAWS環境内で環境名だけ変えてデプロイとは若干趣が違います。

 

しかし、今回私が当たった問題の数々は、通常デプロイする方にも起こることだと思いますので、 本記事がそういった方々の一助になればと思います。

 

環境構築手順(超簡易版)

  1. GitHub上にソースコード(amplifyの環境情報~cloudformation~含む)があり、これをgit clone してくる
  2. aws cli(amlify cli)を用いてamplify initする
  3. amplify push
  4. マネジメントコンソール側からGitHubのブランチと連携 ※はじめからamplify init せずに、コンソール側からGitHubと連携していた方が簡単にできたかもしれない…
  5. Cognitoの初期ユーザーを作成
  6. ドメインの割り当て

 

エラーの数々

[CASE1]:: aws profileの設定ミス

これは「amplify init」をした時に、発生したエラーです。 途中までは下記の手順で進めますが、そこからはエラー続きになります。
 
$ amplify init
Note: It is recommended to run this command from the root of your app directory
? Do you want to use an existing environment? (Y/n) n
? Enter a name for the environment production
? Choose your default editor: (Use arrow keys)
  Visual Studio Code 
  Atom Editor 
  Sublime Text 
  IntelliJ IDEA 
  Vim (via Terminal, Mac OS only) 
  Emacs (via Terminal, Mac OS only) 
> None 
Using default provider  awscloudformation

For more information on AWS Profiles, see:
https://docs.aws.amazon.com/cli/latest/userguide/cli-multiple-profiles.html

? Do you want to use an AWS profile? (Y/n) Y
? Please choose the profile you want to use 
> hogehoge
  default

《エラー内容》

\ Initializing your environment: production(node:9280) UnhandledPromiseRejectionWarning: AccessDenied: Access Denied
    at Request.extractError (C:\Users\hogehogeman\AppData\Roaming\npm\node_modules\@aws-amplify\cli\node_modules\aws-sdk\lib\services\s3.js:816:35)
    at Request.callListeners (C:\Users\hogehogeman\AppData\Roaming\npm\node_modules\@aws-amplify\cli\node_modules\aws-sdk\lib\sequential_executor.js:106:20)
    at Request.emit (C:\Users\hogehogeman\AppData\Roaming\npm\node_modules\@aws-amplify\cli\node_modules\aws-sdk\lib\sequential_executor.js:78:10)
    ...(中略)
(node:9280) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:9280) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
 

《原因》

これは「amplify init」の際に、下記の通り選択してしまったために起きた悲劇です。 【環境】:production ※これは元の環境で使っていた名称 【AWS Profile】:デプロイ先のAWS環境に属するIAMユーザーのもの
 
「新規に作成する」際にも環境の情報が記載されているファイルである、「amplify\team-provider-info.json」を参照するようです。 その結果、これからデプロイする先のAWS環境のIAMユーザーで、以前デプロイした先のAWS環境を参照するような形になってしまい、 Access Deniedのエラーが発生した模様です。
 
《おまけ》
AWSprofileは下記の通り指定しましょう。 Access Deniedのときは、勿論認証情報も確認すべきです。
 
【~/.aws/credentials】
 
[default]
aws_access_key_id=~~~
aws_secret_access_key=~~~

[hogehoge]
aws_access_key_id=~~~
aws_secret_access_key=~~~
また、デプロイ先のregionは下記のファイルに設定する。
 
【~/.aws/config】
 
[profile supportdoc]
region=ap-northeast-1
output=json

[default]
region=ap-northeast-1
output=json


[CASE2]:: arnのべた書き

基本的にAWSの環境情報(arn)は、「amplify\team-provider-info.json」くらいにしか書いていませんが、
 
今回は他にも下記のようなファイルにべた書きされていました。 1. 「amplify\backend\auth(アプリID)(アプリID)-cloudformation-template.yml」 2. 「amplify\backend\function..(某jsファイル)」
 
基本的にはAWSアカウントIDで検索すればヒットするので、そこのみ修正すれば問題ないはずですね。
 

[CASE3]:: SESがサンドボックスから出ていない

SESサービスを用いて、アプリケーションからメールを送ろうとするとき、 そのリージョンのアカウントがサンドボックスを出ていないと正常にデプロイすることが出来ません。 エラー文にもsandboxから出ていないのでは?という趣旨の文句が出るので自明です。
 

《対処方法》

docs.aws.amazon.com
ちなみにですが、一か所5000文字以内の記述が求められる箇所がありましたが、「アプリケーション内利用のため」くらいで許可が下りました。 しかも、「24時間当たりのメッセージを200に(そのまま)してください。」でリクエストを出したのですが、おまけで結構制限を解放してくださったので太っ腹です。
 
AWSからのお返事】
 
このたびは、送信制限の引き上げ申請をご送信いただき、ありがとうございます。新たな送信クォータは、1 日あたり 50,000 メッセージとなります。新たな最大送信レートは、毎秒 14 メッセージです。また、お客様のアカウントを Amazon SES サンドボックスから移動いたしました。
 

[CASE4]:: Cognitoで作成したユーザーでログインできない

マネジメントコンソールで新規作成したCognitoユーザーは、アカウントステータスが「FORCE_CHANGE_PASSWORD」となります。 この状態ではユーザーとして使うことができないので、CognitoCLIからパスワードを変更してやります。
 
こちらのサイトが非常に参考になりました。
docs.aws.amazon.com
 

1. 認証用のクライアントの権限を変更

(Cognito)マネジメントコンソール → 全般設定/アプリクライアントにて、一時的にアプリクライアントの下記項目にチェックを入れる。 「認証用の管理 API のユーザー名パスワード認証を有効にする (ALLOW_ADMIN_USER_PASSWORD_AUTH)」
 

2. AWS CognitoCLIを用いてセッション情報を取得する。

下記のコマンドでセッション情報を取得するが、usernameとpasswordはCognitoにプールされているユーザーのものを用いること。
 
aws cognito-idp admin-initiate-auth \
--user-pool-id (下記参照) \
--client-id (下記参照) \
--auth-flow ADMIN_NO_SRP_AUTH \
--auth-parameters \
USERNAME=(下記参照),PASSWORD=(下記参照) \
--profile (あればaws credentialのprofile名を入力)
※オプションのuser-pool-idとclient-idを下記の通り変更する。 [user-pool-id] (Cognito)マネジメントコンソール → 全般設定/アプリクライアントから「アプリクライアントID」を取得 [client-id] (Cognito)マネジメントコンソール → 全般設定から「プールID」を取得 [auth-aprameters/USERNAME] 作成したCognitoユーザーのusername [auth-aprameters/PASSWORD] 作成したCognitoユーザーのpassword
 

3. セッション情報を用いて、パスワードを変更する。

2で取得したセッション情報を用いて、パスワードを変更するコマンドを実行する。
 
aws cognito-idp admin-respond-to-auth-challenge \
--user-pool-id (前述) \
--client-id (前述) \
--challenge-name NEW_PASSWORD_REQUIRED \
--challenge-responses NEW_PASSWORD='ZAQ!2wsx',USERNAME=test@test.com \
--session "先程取得したセッションを入力" \
--profile (あればaws credentialのprofile名を入力)

[CASE5]:: ドメインにアクセスすると403が返ってくる

実に簡素な画面に以下のようなエラーメッセージが出た場合。
 
[shell]
403
The request could not be satisfied. Bad Request  
generated by cloudfront (cloudfront)
[/shell]
(キャプチャーし忘れてしまい、若干あやふやですが…)
 
このエラーはAmplifyのカスタムドメインの割り当てに則らずに、DNS
 
(ドメイン) CNAME (ブランチ名).(アプリID).amplifyapp.com
というCNAMEレコードのみを作成したために起こったようです。
 
下記の通り正しい手順に則って設定したら問題ありませんでした。 1. Amplifyコンソールのドメイン管理から、「カスタムドメインの追加」で追加したいドメインを設定する。 2. ドメイン管理画面から、「アクション/DNSレコードの表示」で表示されるCNAMEをDNSに登録する。 3. 少しばかり待つ。
 
こちらは下記のサイトを参考にいたしました。 カスタムドメインをセットアップする
    docs.aws.amazon.com
 

 

 

 

ブログ著者

 

 

アプリケーション開発バナー

AWS相談会