CDK for Terraform で Azure StaticSiteApps のアプリをデプロイした際のハマりどころメモ
純正 Provider の有無は CDKTF のプロバイダーから検索
https://github.com/orgs/cdktf/repositories?q=cdktf-provider-
下記ページのまんま(リンク抜粋してるだけだし)
Providers - CDK for Terraform | Terraform | HashiCorp Developer
各プロバイダーの API は HCL と同じ
どんな設定ができるか?だとか、HCLと VSCode の「定義へ移動」(F12) を使って調べればわかる。
Input Variables の使い方が謎
cdktf cli では、現時点では環境変数でしか指定できない。 というのは良いのだが、cdktf synth なり cdktf deploy なりする際に HCL 生成時にランダムで発行される XXXX が付いてしまう。 回避方法が不明なため、1 回はコケさせて XXXX を確認しないとダメそう。(それってどうなの?という感じがするのだが。。。)
サービスプリンシパルは Azure AD アプリ
そのまんま。アプリの登録から登録する。
サービスプリンシパル (アプリ) に ロールを割り当てる
これをしないと、
Cannnot register providers: Microsoft.TimeSeriesInsights. Errors were: Cannot register provider Microsoft.TimeSeriesInsights with Azure Resource Manager: resources.ProvidersClient#Register: Failure responding to request: StatusCode=403
やら
Unable to list provider registration status, it is possible that this is due to invalid credentials or the service principal does not have permission to use the Resource Manager API, Azure error: resources.ProvidersClient#List: Failure sending request: StatusCode=0
やら、ログ取り忘れたけど ResourceGroup 作成や ResourceManager API のアクセス権限が無いと怒られる。(与えてないから当然なのだが)
GitHub Actions から OIDC を使うための Azure の設定
単純に、どこだっけ?となるのでメモ。
stdin が無いと怒られたりするので CDKTF Action を使いましょう
https://github.com/hashicorp/terraform-cdk-action
こんなエラーが出る。
Raw mode is not supported on the current process.stdin, which Ink uses as input stream by default. Read about how to prevent this error on https://github.com/vadimdemedes/ink/#israwmodesupported
tfstate の管理
Terraform Cloud を使うなり、AWS S3 なり外部に保存しておいて、毎回、落としてきて使う。変更があったら更新する。をしないとダメそう。(Terraform の宿命だろうけど)
作ったもの
Ubuntu (ARM64) on Intel Mac
参考記事
手順
- qemu のインストール
- Ubuntu Server のイメージファイルのダウンロード
- qemu を使って Kernel (vmlinuz)、initram (initrd.img) を取り出す
- qemu を使って起動
qemu-system-aarch64 -m 1024 -cpu cortex-a57 -nographic -machine virt \ -kernel vmlinuz-5.4.0-91-generic \ -append 'root=/dev/vda1 rw rootwait mem=1024M console=ttyS0 \ console=ttyAMA0,38400n8 init=/usr/lib/cloud-init/uncloud-init \ ds=nocloud ubuntu-user=ubuntu ubuntu-pass=upass' \ -drive if=none,id=image,file=focal-server-cloudimg-arm64.img \ -initrd initrd.img-5.4.0-91-generic \ -device virtio-blk-device,drive=image \ -netdev user,id=net0,hostfwd=tcp::2222-:22 \ -device virtio-net-pci,netdev=net0
ArchLinux で error: required key missing from keyring が出た場合の keyring の更新方法
ArchLinux を長い間起動せずにおくと、pacman
で使用する証明書が失効してしまって、 pacman -Syu
で
:: Import PGP key 3B94A80E50A477C7, "Jan Alexander Steffens (heftig) <heftig@archlinux.org>"? [Y/n] error: key "3B94A80E50A477C7" could not be looked up remotely error: required key missing from keyring error: failed to commit transaction (unexpected error) Errors occurred, no packages were upgraded.
といったエラーで pacman -Syu
が失敗する。
archlinux-keyring
パッケージを更新して、 pacman -Syu
が期待通りに動作するようにする対策手順を記載する。
sudo -s pacman-key --init pacman-key --populate pacman-key --refresh-keys pacman -Sy archlinux-keyring
pacman-key --refresh-keys
でエラーが出ても、 pacman -Sy archlinux-keyring
が成功すれば、その後は pacman -Syu
が期待通りに動作するようになる。
bash 風 zsh (prezto) prompt
それらしく動くようになったので残しておく。
# VCSの情報を取得するzshの便利関数 vcs_infoを使う autoload -Uz vcs_info # 表示フォーマットの指定 # %b ブランチ情報 # %a アクション名(mergeなど) zstyle ':vcs_info:*' formats '[%b]' zstyle ':vcs_info:*' actionformats '[%b|%a]' precmd () { psvar=() LANG=en_US.UTF-8 vcs_info [[ -n "$vcs_info_msg_0_" ]] && psvar[1]="$vcs_info_msg_0_" } local demi='$' test "${USER}" = "root" && demi='#' # バージョン管理されているディレクトリにいれば表示,そうでなければ非表示 #RPROMPT="%1(v|%F{green}%1v%f|)" PROMPT="%F{green}%B%n@%m%b%f:%~%1(v|%F{blue}%1v%f|)${demi} "
参考
Docker のコンテナーランタイムを Kata containers と Firecracker に切り替える
blog.inductor.me この記事に触発されて、www.pearllinux.com に入れてみました。 上記では、GitHubのリリースからダウンロードされているが、今回はkata-containers のインストールを docker から kata-deploy を使用するようにしてみた。
手順
kata-deploy
の install 手順通りにdocker run -v /opt/kata:/opt/kata -v /var/run/dbus:/var/run/dbus -v /run/systemd:/run/systemd -v /etc/docker:/etc/docker -it katadocker/kata-deploy kata-deploy-docker install
を行う。
$ docker run -v /opt/kata:/opt/kata -v /var/run/dbus:/var/run/dbus -v /run/systemd:/run/systemd -v /etc/docker:/etc/docker -it katadocker/kata-deploy kata-deploy-docker install Unable to find image 'katadocker/kata-deploy:latest' locally latest: Pulling from katadocker/kata-deploy a02a4930cb5d: Pull complete c702ea4a22bc: Pull complete 97ec70278314: Pull complete 56283ea9568d: Pull complete 3be7ca42e1f8: Pull complete ece4a4e81262: Pull complete 7051f8fda3fc: Pull complete Digest: sha256:3c3a0307572a0903e1f0877ac01e782c5f366fe2b0b0a62eb87da579020929e2 Status: Downloaded newer image for katadocker/kata-deploy:latest copying kata artifacts onto host configuring docker { "runtimes": { "kata-qemu": { "path": "/opt/kata/bin/kata-runtime", "runtimeArgs": [ "--kata-config", "/opt/kata/share/defaults/kata-containers/configuration-qemu.toml" ] }, "kata-qemu-virtiofs": { "path": "/opt/kata/bin/kata-runtime", "runtimeArgs": [ "--kata-config", "/opt/kata/share/defaults/kata-containers/configuration-qemu-virtiofs.toml" ] }, "kata-fc": { "path": "/opt/kata/bin/kata-runtime", "runtimeArgs": [ "--kata-config", "/opt/kata/share/defaults/kata-containers/configuration-fc.toml" ] }, "kata-clh": { "path": "/opt/kata/bin/kata-runtime", "runtimeArgs": [ "--kata-config", "/opt/kata/share/defaults/kata-containers/configuration-clh.toml" ] } } }
- コンソールログ出力された内容を
/etc/docker/daemon.json
として保存する。 - system に反映
sudo systemctl daemon-reload sudo systemctl restart docker
- 動作確認
$ docker run --rm --runtime=kata-fc -itd --name alpine alpine ash cc5556f76661f4b3ab58dba7c64a1f70c21b53ed85a1d7889a98863f37c06612 docker: Error response from daemon: OCI runtime create failed: rpc error: code = Unknown desc = rootfs (/run/kata-containers/shared/containers/cc5556f76661f4b3ab58dba7c64a1f70c21b53ed85a1d7889a98863f37c06612/rootfs) does not exist: unknown.
コケた…理由は簡単
5. /etc/docker/daemon.json
を修正
"storage-driver": "devicemapper"
の設定を追加する。
6. ふたたび動作確認
$ docker run --rm --runtime=kata-fc -itd --name alpine alpine ash Unable to find image 'alpine:latest' locally latest: Pulling from library/alpine df20fa9351a1: Pull complete Digest: sha256:185518070891758909c9f839cf4ca393ee977ac378609f700f60a771a2dfe321 Status: Downloaded newer image for alpine:latest 4642bdf55730e00b14c76e7295ff147a1c835bda4a2ac060eeadbbc25d1461c4 vagrant@vagrant-virtualbox:~$ ps -ae | grep -E "kata|fire" 6608 ? 00:00:07 firecracker 6616 pts/1 00:00:00 kata-shim
はい!通りました。
結果
docker run -v /opt/kata:/opt/kata -v /var/run/dbus:/var/run/dbus -v /run/systemd:/run/systemd -v /etc/docker:/etc/docker -it katadocker/kata-deploy kata-deploy-docker install && ¥ sudo modprobe vhost_vsock && ¥ cat <<EOF | sudo tee /etc/docker/daemon.json { "default-runtime": "kata-fc", "runtimes": { "kata-qemu": { "path": "/opt/kata/bin/kata-runtime", "runtimeArgs": [ "--kata-config", "/opt/kata/share/defaults/kata-containers/configuration-qemu.toml" ] }, "kata-qemu-virtiofs": { "path": "/opt/kata/bin/kata-runtime", "runtimeArgs": [ "--kata-config", "/opt/kata/share/defaults/kata-containers/configuration-qemu-virtiofs.toml" ] }, "kata-fc": { "path": "/opt/kata/bin/kata-runtime", "runtimeArgs": [ "--kata-config", "/opt/kata/share/defaults/kata-containers/configuration-fc.toml" ] }, "kata-clh": { "path": "/opt/kata/bin/kata-runtime", "runtimeArgs": [ "--kata-config", "/opt/kata/share/defaults/kata-containers/configuration-clh.toml" ] } }, "storage-driver": "devicemapper" } EOF sudo systemctl daemon-reload && ¥ sudo systemctl restart docker && ¥ docker run --rm -itd --name alpine alpine ash && ¥ ps -ae | grep -E "kata|fire" && ¥ docker stop alpine
ちなみに Nested Virtualization が有効でないと動きません。
AWS Cloud 9 上だと、おそらくそれが原因で動かない…
SpringBoot 2.3.x の 「OCI images using Cloud Native Buildpacks」を試してみた
背景
TwitterでSpringBoot2.3.xでは Cloud Native Buildpacks によって jib プラグインを使わずに DockerfileレスでDockerイメージをビルド出来ると教えていただきました。
ご存知かもしれませんが、Spring Boot 2.3からはCloud Native Buildpackを使ってデフォルトのままコマンド一発でDockerイメージが作れるようになったので、ぜひお試しください。(そして詳しい部分を僕に教えてほしいですw
— Ryo Shindo (@shindo_ryo) 2020年6月21日
な、なんだってーー!!
ということで、試さないかもと言っておきながら、早速試してみました。
環境
Java
- Librca JDK 11.0.7
- Spring Boot 2.3.1.RELEASE
- Gradle 6.5
- Jib Gradle Plugin 2.4.0 (比較用)
- Docker Desktop for Mac 2.3.0.3 (45519)
- docker-ce 19.03.8
ざっくりとしたまとめ
評価項目 | Cloud Native Buildpacks | Jib Gradle Plugin |
---|---|---|
手軽さ | ○ | △ |
スピード | × | ○ |
機能性 | |
|
イメージサイズ | △ | ○ |
シンプルさ | × | ○ |
詳細
手軽さ
jib と比べた場合、spring-boot-gradle-plugin(Maven の場合は spring-boot-maven-plugin)のみで完結するため、わざわざjib pluginのようなサードパーティ製プラグインを導入せずに使える。 とはいえ、jib plugin の導入自体も難しいものではないため、Dockerfileを書かずにコンテナー化するための敷居が下がった程度と言えよう。
スピード
きちんと時間計測はしていないが、jib pluginでビルドした方がビルド時間は短い。
機能性
Twitterでご指摘いただきました。とても有益な情報をありがとうございます!
こんにちは。確かにjibの方がビルドは速いしあとはDocker Daemonなしでビルドできるってメリットがありますね。
— Toshiaki Maki (@making) 2020年6月22日
CNBもjibにはないメリットがあるのでよかったら↓の資料か動画をチェックしてみてもらいたいです。資料から省きましたがベースイメージの差し替えもできます。https://t.co/xBfF5WpXpC
Memory Calculator、Link-Local DNS、JVMKill Agent (個人的には特に前者2つ)はとても魅力的。 jib でやるには、事前にベースイメージとして、これらをインストールしたものを使うほか無いだろう。
生成するDockerイメージ名を変更出来る程度で、Dockerfileの
ベースイメージの変更は、おそらくbuilderのrun imageを差し替えることになる。
ただ、そうすると自前でbuilderを用意しないとならなさそう(Dockerfile3つとTOMLでいけるだろうけど)なので、jibよりはハードルが高そう。
(何となくだが、AWS CodeBuildのbuildspec.ymlとビルド環境として指定するイメージがひとまとめになったものがbuilderというイメージ。高機能故に少し複雑)FROM
で指定するような内容は設定できそうに無い。(jibなら出来る)
イメージのタイムスタンプをDockerの形式(?)に合わせることができなさそう(jibなら出来る)
Spring Boot Gradle Plugin Reference Guide
イメージサイズ
同じアプリをビルドして docker images
で表示されるサイズを比較してみた。
Cloud Native Buildpacks でビルドした場合417MB。 jibでビルドした場合(jib.from.imageをデフォルトから変更しない場合です)366MB。
→ Memory Calculator、Link-Local DNS、JVMKill Agent が入っていること、layer数が多いことを考えると、左程の差ではなさそう。(ベースイメージのサイズが支配的になるお話。jibで mcr.microsoft.com/java/jdk:11-zulu-alpine
を指定したら600MB超えたから充分、許容範囲内だろう。それでもデカいというならGraalVM使うしかない気がする)
シンプルさ
Cloud Native Buildpacks はとても高機能だが、その反面、jibほどシンプルでは無い(Builder/Stack/Run Imageが存在するので、それを理解しないとどのようにすればベースイメージを変えられるのか?がわからないなど)。 ということで、シンプルさはjibにあると思う。(シンプルが必ずしも良いとは言わないし、高機能も同じく。この辺はGo言語とRustのどちらの方がいいのか?という不毛な議論と同じようなお話だろう。手軽さ・使い勝手が大事なのだと思うんだけど…)
結論
現状では jib plugin を使用した方が ベースイメージ(DockerfileのFROMに指定するイメージ)を指定できたり、 タイムスタンプ形式の変更、外部ファイルの追加、 ビルドスピードといった面で優位である。
しかしながら、Memory Calculator、Link-Local DNS、JVMKill Agent といったミドルウェアの存在を考えると、Cloud Native Buildpacks の方が運用していく上で欲しいものが最初から付いてくるので良い。
また、毎回、[start.spring.io:title] で作ったプロジェクトに jib plugin を導入する手間を考えると、自動生成されたプロジェクトに設定済みのプラグインだけで完結するというのは嬉しい限り。
run image (ベースイメージ) を build.gradle で指定出来るようになってくれると嬉しいかも。(今はjibと比べるとちょっと敷居高い)
検証コード
jib
Cloud Native Buildpacks
Remove jib by poad · Pull Request #34 · poad/examples · GitHub
おまけ
ビルドコマンド (Gradle)
jib
./gradlew jibDockerBuild
Cloud Native Buildpacks
./gradlew bootBuildImage
AWS Amplify と AWS Cognito と TypeScript で作る ユーザー認証機能付き Next.js アプリ
AWS Amplify とは?
モバイルアプリケーションやウェブアプリケーションを構築するための JavaScript フレームワークです。 これを使うことで、後述する AWS Cognito を簡単に使用できます。
AWS Cognito とは?
ユーザー管理を一括で行ってくれるユーザー認証サービスです。 Auth0 の AWS版といったところでしょうか。
この様に色々と設定できます。
Next.js とは?
React.js でサーバーサイドレンダリングするためのフレームワークです。 Vue.js の Nuxt.js のようなものですね。
やってみよう!
1. Next.js with TypeScript な環境を作る
https://nextjs.org のサイトの手順を参考に、TypeScript に対応した Next.js アプリが実行できる環境を構築します。
ちなみに、筆者はyarn
を使うことが多いですが、公式ドキュメントは npm ベースです。npm を使われる方は適宜、置き換えてお読みください。
$ mkdir next-amplify-example [ken-yo@MacBook-Pro-2019-15inch ~]$ cd next-amplify-example [ken-yo@MacBook-Pro-2019-15inch next-amplify-example]$ yarn init -y yarn init v1.22.0 warning The yes flag has been set. This will automatically answer yes to all questions, which may have security implications. success Saved package.json ✨ Done in 0.02s. [ken-yo@MacBook-Pro-2019-15inch next-amplify-example]$ yarn add --save react react-dom next yarn add v1.22.0 info No lockfile found. [1/4] 🔍 Resolving packages... warning next > @babel/runtime-corejs2 > core-js@2.6.11: core-js@<3 is no longer maintained and not recommended for usage due to the number of issues. Please, upgrade your dependencies to the actual version of core-js@3. warning next > styled-jsx > babel-types > babel-runtime > core-js@2.6.11: core-js@<3 is no longer maintained and not recommended for usage due to the number of issues. Please, upgrade your dependencies to the actual version of core-js@3. [2/4] 🚚 Fetching packages... [3/4] 🔗 Linking dependencies... warning "next > styled-jsx@3.2.4" has unmet peer dependency "react@15.x.x || 16.x.x". warning "next > use-subscription@1.1.1" has unmet peer dependency "react@^16.8.0". warning " > react-dom@16.12.0" has unmet peer dependency "react@^16.0.0". warning " > next@9.2.2" has unmet peer dependency "react@^16.6.0". [4/4] 🔨 Building fresh packages... success Saved lockfile. success Saved 578 new dependencies. info Direct dependencies ├─ next@9.2.2 └─ react-dom@16.12.0 info All dependencies ├─ @ampproject/toolbox-optimizer@2.0.0 ├─ @ampproject/toolbox-runtime-version@2.0.0 ├─ @ampproject/toolbox-script-csp@2.0.0 ├─ @ampproject/toolbox-validator-rules@2.0.0 ├─ @babel/core@7.7.2 ├─ @babel/generator@7.8.4 ├─ @babel/helper-builder-binary-assignment-operator-visitor@7.8.3 ├─ @babel/helper-builder-react-jsx@7.8.3 ├─ @babel/helper-call-delegate@7.8.3 ├─ @babel/helper-create-class-features-plugin@7.8.3 ├─ @babel/helper-define-map@7.8.3 ├─ @babel/helper-explode-assignable-expression@7.8.3 ├─ @babel/helper-wrap-function@7.8.3 ├─ @babel/helpers@7.8.4 ├─ @babel/highlight@7.8.3 ├─ @babel/parser@7.8.4 ├─ @babel/plugin-proposal-async-generator-functions@7.8.3 ├─ @babel/plugin-proposal-class-properties@7.7.0 ├─ @babel/plugin-proposal-dynamic-import@7.8.3 ├─ @babel/plugin-proposal-json-strings@7.8.3 ├─ @babel/plugin-proposal-nullish-coalescing-operator@7.7.4 ├─ @babel/plugin-proposal-object-rest-spread@7.6.2 ├─ @babel/plugin-proposal-optional-catch-binding@7.8.3 ├─ @babel/plugin-proposal-optional-chaining@7.7.4 ├─ @babel/plugin-proposal-unicode-property-regex@7.8.3 ├─ @babel/plugin-syntax-async-generators@7.8.4 ├─ @babel/plugin-syntax-bigint@7.8.3 ├─ @babel/plugin-syntax-dynamic-import@7.8.3 ├─ @babel/plugin-syntax-json-strings@7.8.3 ├─ @babel/plugin-syntax-nullish-coalescing-operator@7.8.3 ├─ @babel/plugin-syntax-object-rest-spread@7.8.3 ├─ @babel/plugin-syntax-optional-catch-binding@7.8.3 ├─ @babel/plugin-syntax-optional-chaining@7.8.3 ├─ @babel/plugin-syntax-top-level-await@7.8.3 ├─ @babel/plugin-syntax-typescript@7.8.3 ├─ @babel/plugin-transform-arrow-functions@7.8.3 ├─ @babel/plugin-transform-async-to-generator@7.8.3 ├─ @babel/plugin-transform-block-scoped-functions@7.8.3 ├─ @babel/plugin-transform-block-scoping@7.8.3 ├─ @babel/plugin-transform-classes@7.8.3 ├─ @babel/plugin-transform-computed-properties@7.8.3 ├─ @babel/plugin-transform-destructuring@7.8.3 ├─ @babel/plugin-transform-dotall-regex@7.8.3 ├─ @babel/plugin-transform-duplicate-keys@7.8.3 ├─ @babel/plugin-transform-exponentiation-operator@7.8.3 ├─ @babel/plugin-transform-for-of@7.8.4 ├─ @babel/plugin-transform-function-name@7.8.3 ├─ @babel/plugin-transform-literals@7.8.3 ├─ @babel/plugin-transform-member-expression-literals@7.8.3 ├─ @babel/plugin-transform-modules-amd@7.8.3 ├─ @babel/plugin-transform-modules-commonjs@7.7.0 ├─ @babel/plugin-transform-modules-systemjs@7.8.3 ├─ @babel/plugin-transform-modules-umd@7.8.3 ├─ @babel/plugin-transform-named-capturing-groups-regex@7.8.3 ├─ @babel/plugin-transform-new-target@7.8.3 ├─ @babel/plugin-transform-object-super@7.8.3 ├─ @babel/plugin-transform-parameters@7.8.4 ├─ @babel/plugin-transform-property-literals@7.8.3 ├─ @babel/plugin-transform-react-display-name@7.8.3 ├─ @babel/plugin-transform-react-jsx-self@7.8.3 ├─ @babel/plugin-transform-react-jsx-source@7.8.3 ├─ @babel/plugin-transform-react-jsx@7.8.3 ├─ @babel/plugin-transform-regenerator@7.8.3 ├─ @babel/plugin-transform-reserved-words@7.8.3 ├─ @babel/plugin-transform-runtime@7.6.2 ├─ @babel/plugin-transform-shorthand-properties@7.8.3 ├─ @babel/plugin-transform-spread@7.8.3 ├─ @babel/plugin-transform-sticky-regex@7.8.3 ├─ @babel/plugin-transform-template-literals@7.8.3 ├─ @babel/plugin-transform-typeof-symbol@7.8.4 ├─ @babel/plugin-transform-typescript@7.8.3 ├─ @babel/plugin-transform-unicode-regex@7.8.3 ├─ @babel/preset-env@7.7.1 ├─ @babel/preset-modules@0.1.1 ├─ @babel/preset-react@7.7.0 ├─ @babel/preset-typescript@7.7.2 ├─ @babel/runtime-corejs2@7.7.2 ├─ @babel/runtime@7.7.2 ├─ @next/polyfill-nomodule@9.2.2 ├─ @webassemblyjs/floating-point-hex-parser@1.8.5 ├─ @webassemblyjs/helper-code-frame@1.8.5 ├─ @webassemblyjs/helper-fsm@1.8.5 ├─ @webassemblyjs/helper-wasm-section@1.8.5 ├─ @webassemblyjs/wasm-edit@1.8.5 ├─ @webassemblyjs/wasm-opt@1.8.5 ├─ @xtuc/ieee754@1.2.0 ├─ abbrev@1.1.1 ├─ accepts@1.3.7 ├─ acorn@6.4.0 ├─ adjust-sourcemap-loader@2.0.0 ├─ ajv-errors@1.0.1 ├─ ajv-keywords@3.4.1 ├─ ajv@6.11.0 ├─ amphtml-validator@1.0.23 ├─ ansi-colors@3.2.4 ├─ ansi-html@0.0.7 ├─ ansi-styles@3.2.1 ├─ anymatch@3.1.1 ├─ aproba@1.2.0 ├─ are-we-there-yet@1.1.5 ├─ argparse@1.0.10 ├─ arity-n@1.0.4 ├─ arr-flatten@1.1.0 ├─ array-union@1.0.2 ├─ array-uniq@1.0.3 ├─ asap@2.0.6 ├─ asn1.js@4.10.1 ├─ assert@1.4.1 ├─ assign-symbols@1.0.0 ├─ ast-types@0.13.2 ├─ async-each@1.0.3 ├─ async-retry@1.2.3 ├─ async-sema@3.0.0 ├─ atob@2.1.2 ├─ autodll-webpack-plugin@0.4.2 ├─ autoprefixer@9.7.4 ├─ babel-code-frame@6.26.0 ├─ babel-core@7.0.0-bridge.0 ├─ babel-loader@8.0.6 ├─ babel-plugin-transform-define@2.0.0 ├─ babel-plugin-transform-react-remove-prop-types@0.4.24 ├─ babel-runtime@6.26.0 ├─ babel-types@6.26.0 ├─ base@0.11.2 ├─ base64-js@1.3.1 ├─ binary-extensions@2.0.0 ├─ bindings@1.5.0 ├─ bluebird@3.7.2 ├─ brace-expansion@1.1.11 ├─ braces@2.3.2 ├─ browserify-aes@1.2.0 ├─ browserify-cipher@1.0.1 ├─ browserify-des@1.0.2 ├─ browserify-sign@4.0.4 ├─ browserify-zlib@0.2.0 ├─ buffer-equal-constant-time@1.0.1 ├─ buffer-json@2.0.0 ├─ buffer-xor@1.0.3 ├─ buffer@4.9.2 ├─ builtin-status-codes@3.0.0 ├─ bytes@3.0.0 ├─ cacache@12.0.3 ├─ cache-base@1.0.1 ├─ cache-loader@4.1.0 ├─ caller-callsite@2.0.0 ├─ caller-path@2.0.0 ├─ callsites@2.0.0 ├─ camelcase@5.3.1 ├─ caniuse-lite@1.0.30001028 ├─ chalk@2.4.2 ├─ chokidar@3.3.1 ├─ chownr@1.1.4 ├─ chrome-trace-event@1.0.2 ├─ ci-info@2.0.0 ├─ class-utils@0.3.6 ├─ cli-cursor@2.1.0 ├─ cli-spinners@2.2.0 ├─ clone-deep@4.0.1 ├─ clone@1.0.4 ├─ code-point-at@1.1.0 ├─ collection-visit@1.0.0 ├─ color-convert@1.9.3 ├─ color-name@1.1.3 ├─ colors@1.1.2 ├─ compose-function@3.0.3 ├─ compressible@2.0.18 ├─ compression@1.7.4 ├─ concat-map@0.0.1 ├─ concat-stream@1.6.2 ├─ conf@5.0.0 ├─ console-browserify@1.2.0 ├─ console-control-strings@1.1.0 ├─ constants-browserify@1.0.0 ├─ content-type@1.0.4 ├─ cookie@0.4.0 ├─ copy-concurrently@1.0.5 ├─ copy-descriptor@0.1.1 ├─ core-js-compat@3.6.4 ├─ core-js@2.6.11 ├─ core-util-is@1.0.2 ├─ cosmiconfig@5.2.1 ├─ create-ecdh@4.0.3 ├─ create-hmac@1.1.7 ├─ crypto-browserify@3.12.0 ├─ css-blank-pseudo@0.1.4 ├─ css-has-pseudo@0.10.0 ├─ css-loader@3.3.0 ├─ css-prefers-color-scheme@3.1.1 ├─ css@2.2.4 ├─ cssdb@4.4.0 ├─ cssnano-preset-simple@1.0.3 ├─ cssnano-simple@1.0.0 ├─ cyclist@1.0.1 ├─ d@1.0.1 ├─ debug@2.6.9 ├─ decode-uri-component@0.2.0 ├─ deep-extend@0.6.0 ├─ defaults@1.0.3 ├─ define-properties@1.1.3 ├─ del@3.0.0 ├─ delegates@1.0.0 ├─ des.js@1.0.1 ├─ destroy@1.0.4 ├─ detect-libc@1.0.3 ├─ devalue@2.0.1 ├─ diffie-hellman@5.0.3 ├─ dom-serializer@0.2.2 ├─ domain-browser@1.2.0 ├─ domutils@2.0.0 ├─ dot-prop@5.2.0 ├─ duplexer@0.1.1 ├─ duplexify@3.7.1 ├─ ecdsa-sig-formatter@1.0.11 ├─ ee-first@1.1.1 ├─ electron-to-chromium@1.3.358 ├─ emojis-list@3.0.0 ├─ encodeurl@1.0.2 ├─ enhanced-resolve@4.1.1 ├─ env-paths@2.2.0 ├─ errno@0.1.7 ├─ error-ex@1.3.2 ├─ es5-ext@0.10.53 ├─ es6-iterator@2.0.3 ├─ es6-symbol@3.1.3 ├─ escape-html@1.0.3 ├─ escape-string-regexp@1.0.5 ├─ eslint-scope@4.0.3 ├─ esprima@4.0.1 ├─ esrecurse@4.2.1 ├─ estraverse@4.3.0 ├─ esutils@2.0.3 ├─ etag@1.8.1 ├─ eventemitter3@4.0.0 ├─ events@3.1.0 ├─ evp_bytestokey@1.0.3 ├─ expand-brackets@2.1.4 ├─ ext@1.4.0 ├─ extglob@2.0.4 ├─ fast-deep-equal@3.1.1 ├─ fast-json-stable-stringify@2.1.0 ├─ file-loader@4.2.0 ├─ file-uri-to-path@1.0.0 ├─ fill-range@4.0.0 ├─ finally-polyfill@0.1.0 ├─ find-cache-dir@2.1.0 ├─ flatten@1.0.3 ├─ flush-write-stream@1.1.1 ├─ follow-redirects@1.10.0 ├─ for-in@1.0.2 ├─ fork-ts-checker-webpack-plugin@3.1.1 ├─ from2@2.3.0 ├─ fs-minipass@1.2.7 ├─ fs.realpath@1.0.0 ├─ fsevents@2.1.2 ├─ gauge@2.7.4 ├─ get-value@2.0.6 ├─ glob-parent@5.1.0 ├─ glob-to-regexp@0.4.1 ├─ glob@7.1.6 ├─ globby@6.1.0 ├─ graceful-readlink@1.0.1 ├─ gzip-size@5.1.1 ├─ has-ansi@2.0.0 ├─ has-symbols@1.0.1 ├─ has-unicode@2.0.1 ├─ has-value@1.0.0 ├─ has@1.0.3 ├─ hash.js@1.1.7 ├─ hmac-drbg@1.0.1 ├─ hosted-git-info@2.8.5 ├─ html-entities@1.2.1 ├─ htmlparser2@4.0.0 ├─ http-errors@1.7.2 ├─ http-proxy@1.18.0 ├─ https-browserify@1.0.0 ├─ iconv-lite@0.4.24 ├─ icss-utils@4.1.1 ├─ ieee754@1.1.13 ├─ ignore-loader@0.1.2 ├─ ignore-walk@3.0.3 ├─ import-cwd@2.1.0 ├─ import-fresh@2.0.0 ├─ import-from@2.1.0 ├─ infer-owner@1.0.4 ├─ inflight@1.0.6 ├─ ini@1.3.5 ├─ invariant@2.2.4 ├─ is-accessor-descriptor@1.0.0 ├─ is-arrayish@0.2.1 ├─ is-binary-path@2.1.0 ├─ is-data-descriptor@1.0.0 ├─ is-descriptor@1.0.2 ├─ is-directory@0.3.1 ├─ is-docker@2.0.0 ├─ is-extglob@2.1.1 ├─ is-fullwidth-code-point@1.0.0 ├─ is-glob@4.0.1 ├─ is-obj@2.0.0 ├─ is-path-cwd@1.0.0 ├─ is-path-in-cwd@1.0.1 ├─ is-path-inside@1.0.1 ├─ is-plain-obj@1.1.0 ├─ is-plain-object@2.0.4 ├─ is-windows@1.0.2 ├─ is-wsl@2.1.1 ├─ isarray@1.0.0 ├─ jest-worker@24.9.0 ├─ js-levenshtein@1.1.6 ├─ js-tokens@4.0.0 ├─ js-yaml@3.13.1 ├─ jsesc@2.5.2 ├─ json-parse-better-errors@1.0.2 ├─ json-schema-traverse@0.4.1 ├─ json-schema-typed@7.0.3 ├─ jsonwebtoken@8.5.1 ├─ jwa@1.4.1 ├─ jws@3.2.2 ├─ launch-editor@2.2.1 ├─ load-json-file@2.0.0 ├─ loader-runner@2.4.0 ├─ lodash.curry@4.1.1 ├─ lodash.includes@4.3.0 ├─ lodash.isboolean@3.0.3 ├─ lodash.isinteger@4.0.4 ├─ lodash.isnumber@3.0.3 ├─ lodash.isplainobject@4.0.6 ├─ lodash.isstring@4.0.1 ├─ lodash.once@4.1.1 ├─ lodash.template@4.5.0 ├─ lodash.templatesettings@4.2.0 ├─ log-symbols@2.2.0 ├─ loose-envify@1.4.0 ├─ lru-cache@5.1.1 ├─ mamacro@0.0.3 ├─ map-visit@1.0.0 ├─ merge-stream@2.0.0 ├─ microevent.ts@0.1.1 ├─ miller-rabin@4.0.1 ├─ mime-db@1.43.0 ├─ mime-types@2.1.26 ├─ mime@1.6.0 ├─ mimic-fn@1.2.0 ├─ mini-css-extract-plugin@0.8.0 ├─ minimalistic-crypto-utils@1.0.1 ├─ minimatch@3.0.4 ├─ minimist@1.2.0 ├─ minipass@2.9.0 ├─ minizlib@1.3.3 ├─ mississippi@3.0.0 ├─ mixin-deep@1.3.2 ├─ move-concurrently@1.0.1 ├─ nan@2.14.0 ├─ nanomatch@1.2.13 ├─ needle@2.3.2 ├─ negotiator@0.6.2 ├─ next-tick@1.0.0 ├─ next@9.2.2 ├─ node-libs-browser@2.2.1 ├─ node-pre-gyp@0.14.0 ├─ node-releases@1.1.50 ├─ nopt@4.0.1 ├─ normalize-html-whitespace@1.0.0 ├─ normalize-package-data@2.5.0 ├─ normalize-range@0.1.2 ├─ normalize-url@1.9.1 ├─ npm-bundled@1.1.1 ├─ npm-packlist@1.4.8 ├─ npmlog@4.1.2 ├─ num2fraction@1.2.2 ├─ number-is-nan@1.0.1 ├─ object-assign@4.1.1 ├─ object-copy@0.1.0 ├─ object-keys@1.1.1 ├─ object-path@0.11.4 ├─ on-finished@2.3.0 ├─ on-headers@1.0.2 ├─ onetime@2.0.1 ├─ ora@3.4.0 ├─ os-browserify@0.3.0 ├─ os-homedir@1.0.2 ├─ os-tmpdir@1.0.2 ├─ osenv@0.1.5 ├─ p-limit@2.2.2 ├─ p-locate@4.1.0 ├─ p-map@1.2.0 ├─ p-try@2.2.0 ├─ pako@1.0.11 ├─ parallel-transform@1.2.0 ├─ parse-json@2.2.0 ├─ pascalcase@0.1.1 ├─ path-browserify@0.0.1 ├─ path-dirname@1.0.2 ├─ path-is-inside@1.0.2 ├─ path-parse@1.0.6 ├─ path-to-regexp@6.1.0 ├─ path-type@2.0.0 ├─ picomatch@2.2.1 ├─ pinkie-promise@2.0.1 ├─ pinkie@2.0.4 ├─ pkg-dir@3.0.0 ├─ pkg-up@3.1.0 ├─ pnp-webpack-plugin@1.5.0 ├─ posix-character-classes@0.1.1 ├─ postcss-attribute-case-insensitive@4.0.2 ├─ postcss-color-functional-notation@2.0.1 ├─ postcss-color-gray@5.0.0 ├─ postcss-color-hex-alpha@5.0.3 ├─ postcss-color-mod-function@3.0.3 ├─ postcss-color-rebeccapurple@4.0.1 ├─ postcss-custom-media@7.0.8 ├─ postcss-custom-properties@8.0.11 ├─ postcss-custom-selectors@5.1.2 ├─ postcss-dir-pseudo-class@5.0.0 ├─ postcss-double-position-gradients@1.0.0 ├─ postcss-env-function@2.0.2 ├─ postcss-flexbugs-fixes@4.1.0 ├─ postcss-focus-visible@4.0.0 ├─ postcss-focus-within@3.0.0 ├─ postcss-font-variant@4.0.0 ├─ postcss-gap-properties@2.0.0 ├─ postcss-image-set-function@3.0.1 ├─ postcss-initial@3.0.2 ├─ postcss-lab-function@2.0.1 ├─ postcss-load-config@2.1.0 ├─ postcss-loader@3.0.0 ├─ postcss-logical@3.0.0 ├─ postcss-media-minmax@4.0.0 ├─ postcss-modules-extract-imports@2.0.0 ├─ postcss-modules-local-by-default@3.0.2 ├─ postcss-modules-scope@2.1.1 ├─ postcss-modules-values@3.0.0 ├─ postcss-nesting@7.0.1 ├─ postcss-overflow-shorthand@2.0.0 ├─ postcss-page-break@2.0.0 ├─ postcss-place@4.0.1 ├─ postcss-preset-env@6.7.0 ├─ postcss-pseudo-class-any-link@6.0.0 ├─ postcss-replace-overflow-wrap@3.0.0 ├─ postcss-selector-matches@4.0.0 ├─ postcss-selector-not@4.0.0 ├─ prepend-http@1.0.4 ├─ private@0.1.8 ├─ process-nextick-args@2.0.1 ├─ process@0.11.10 ├─ promise-inflight@1.0.1 ├─ promise@7.1.1 ├─ prop-types-exact@1.2.0 ├─ prop-types@15.7.2 ├─ prr@1.0.1 ├─ public-encrypt@4.0.3 ├─ pump@3.0.0 ├─ pumpify@1.5.1 ├─ punycode@1.3.2 ├─ query-string@4.3.4 ├─ querystring-es3@0.2.1 ├─ querystring@0.2.0 ├─ randomfill@1.0.4 ├─ range-parser@1.2.1 ├─ raw-body@2.4.0 ├─ rc@1.2.8 ├─ react-dom@16.12.0 ├─ react-error-overlay@5.1.6 ├─ react-is@16.8.6 ├─ read-pkg@2.0.0 ├─ readable-stream@2.3.7 ├─ readdirp@3.3.0 ├─ recast@0.18.5 ├─ reflect.ownkeys@0.2.0 ├─ regenerate-unicode-properties@8.1.0 ├─ regenerator-transform@0.14.1 ├─ regex-parser@2.2.10 ├─ regexpu-core@4.6.0 ├─ regjsgen@0.5.1 ├─ regjsparser@0.6.3 ├─ remove-trailing-separator@1.1.0 ├─ repeat-element@1.1.3 ├─ requires-port@1.0.0 ├─ resolve-url-loader@3.1.1 ├─ resolve-url@0.2.1 ├─ resolve@1.15.1 ├─ restore-cursor@2.0.0 ├─ ret@0.1.15 ├─ retry@0.12.0 ├─ rework-visit@1.0.0 ├─ rework@1.0.1 ├─ run-queue@1.0.3 ├─ safer-buffer@2.1.2 ├─ sass-loader@8.0.2 ├─ sax@1.2.4 ├─ scheduler@0.18.0 ├─ schema-utils@2.6.4 ├─ semver@5.7.1 ├─ send@0.17.1 ├─ serialize-javascript@2.1.2 ├─ set-blocking@2.0.0 ├─ set-value@2.0.1 ├─ setimmediate@1.0.5 ├─ shallow-clone@3.0.1 ├─ shell-quote@1.7.2 ├─ signal-exit@3.0.2 ├─ snapdragon-node@2.1.1 ├─ snapdragon-util@3.0.1 ├─ sort-keys@1.1.2 ├─ source-list-map@2.0.1 ├─ source-map-resolve@0.5.3 ├─ source-map-url@0.4.0 ├─ spdx-correct@3.1.0 ├─ spdx-exceptions@2.2.0 ├─ split-string@3.1.0 ├─ sprintf-js@1.0.3 ├─ ssri@6.0.1 ├─ static-extend@0.1.2 ├─ stream-browserify@2.0.2 ├─ stream-each@1.2.3 ├─ stream-http@2.8.3 ├─ strict-uri-encode@1.1.0 ├─ string_decoder@1.1.1 ├─ string-width@1.0.2 ├─ strip-ansi@3.0.1 ├─ strip-bom@3.0.0 ├─ strip-json-comments@2.0.1 ├─ style-loader@1.0.0 ├─ styled-jsx@3.2.4 ├─ stylis-rule-sheet@0.0.10 ├─ stylis@3.5.4 ├─ tar@4.4.13 ├─ terser-webpack-plugin@1.4.3 ├─ terser@4.6.3 ├─ thread-loader@2.1.3 ├─ through2@2.0.5 ├─ timers-browserify@2.0.11 ├─ to-arraybuffer@1.0.1 ├─ to-fast-properties@1.0.3 ├─ to-object-path@0.3.0 ├─ to-regex-range@2.1.1 ├─ traverse@0.6.6 ├─ ts-pnp@1.1.6 ├─ tslib@1.11.0 ├─ tty-browserify@0.0.0 ├─ type@1.2.0 ├─ typedarray-to-buffer@3.1.5 ├─ typedarray@0.0.6 ├─ unfetch@4.1.0 ├─ unicode-canonical-property-names-ecmascript@1.0.4 ├─ unicode-match-property-ecmascript@1.0.4 ├─ unicode-match-property-value-ecmascript@1.1.0 ├─ unicode-property-aliases-ecmascript@1.0.5 ├─ union-value@1.0.1 ├─ unique-filename@1.1.1 ├─ unique-slug@2.0.2 ├─ unpipe@1.0.0 ├─ unset-value@1.0.0 ├─ upath@1.2.0 ├─ uri-js@4.2.2 ├─ url-polyfill@1.1.7 ├─ url@0.11.0 ├─ use-subscription@1.1.1 ├─ use@3.1.1 ├─ util-deprecate@1.0.2 ├─ uuid@3.4.0 ├─ validate-npm-package-license@3.0.4 ├─ vary@1.1.2 ├─ vm-browserify@1.1.2 ├─ watchpack@2.0.0-beta.5 ├─ wcwidth@1.0.1 ├─ webpack-dev-middleware@3.7.0 ├─ webpack-hot-middleware@2.25.0 ├─ webpack-log@2.0.0 ├─ webpack-merge@4.2.2 ├─ webpack-sources@1.4.3 ├─ webpack@4.41.2 ├─ wide-align@1.1.3 ├─ worker-farm@1.7.0 ├─ worker-rpc@0.1.1 ├─ write-file-atomic@3.0.1 ├─ xtend@4.0.2 ├─ y18n@4.0.0 └─ yallist@3.1.1 ✨ Done in 10.63s. $ mkdir -p src/pages $ yarn add --save-dev typescript @types/react @types/node yarn add v1.22.0 [1/4] 🔍 Resolving packages... [2/4] 🚚 Fetching packages... [3/4] 🔗 Linking dependencies... warning " > next@9.2.2" has unmet peer dependency "react@^16.6.0". warning "next > styled-jsx@3.2.4" has unmet peer dependency "react@15.x.x || 16.x.x". warning "next > use-subscription@1.1.1" has unmet peer dependency "react@^16.8.0". warning " > react-dom@16.12.0" has unmet peer dependency "react@^16.0.0". [4/4] 🔨 Building fresh packages... success Saved lockfile. success Saved 4 new dependencies. info Direct dependencies ├─ @types/node@13.7.4 └─ @types/react@16.9.22 info All dependencies ├─ @types/node@13.7.4 ├─ @types/prop-types@15.7.3 ├─ @types/react@16.9.22 └─ csstype@2.6.9 ✨ Done in 2.02s. $ yarn add react yarn add v1.22.0 [1/4] 🔍 Resolving packages... [2/4] 🚚 Fetching packages... [3/4] 🔗 Linking dependencies... [4/4] 🔨 Building fresh packages... success Saved lockfile. success Saved 1 new dependency. info Direct dependencies └─ react@16.12.0 info All dependencies └─ react@16.12.0 ✨ Done in 1.73s. $ yarn run dev yarn run v1.22.0 $ next [ wait ] starting the development server ... [ info ] waiting on http://localhost:3000 ... It looks like you're trying to use TypeScript but do not have the required package(s) installed. Please install typescript by running: yarn add --dev typescript If you are not trying to use TypeScript, please remove the tsconfig.json file from your package root (and any TypeScript files). error Command failed with exit code 1. info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command. $ yarn add --dev typescript yarn add v1.22.0 [1/4] 🔍 Resolving packages... [2/4] 🚚 Fetching packages... [3/4] 🔗 Linking dependencies... [4/4] 🔨 Building fresh packages... success Saved lockfile. success Saved 1 new dependency. info Direct dependencies └─ typescript@3.8.2 info All dependencies └─ typescript@3.8.2 ✨ Done in 2.02s.
tsconfig.json や、 next.config.js 、public/sw.js などは各自調べて追加してください。(ぉぃ
地味に大変なので、テンプレートリポジトリー化しています。
2. amplify の導入
オフィシャルドキュメント https://aws-amplify.github.io/docs/ のとおり、CLIインストールと設定を行います。
npm install -g @aws-amplify/cli amplify configure
AWS 管理コンソールが起動して、使うリージョンだとか、amplify を管理するための(?) IAM ユーザーの作成などをターミナルに表示されたメッセージに従って行います。
3. アプリケーションへの適用
3.1. nom モジュールのインストール
amplify には色々な AWS サービスを使うための npm モジュールがあるようですが、今回は以下の 3つを使用します。
yarn add aws-amplify @aws-amplify/auth aws-amplify-react
3.2. amplify アプリの初期化
3.2.1. amplify init
amplify init
を実行すると、プロジェクト名や使用するエディター、環境名などの選択や入力を求められます。 指示に従って進めると、バックエンドコードが出力されます。
これは、後ほど amplify コマンドで使うことになる CloudFormation テンプレートや CloudFormation Stack などです。
$ amplify init Note: It is recommended to run this command from the root of your app directory ? Enter a name for the project next-amplify-example ? Enter a name for the environment dev ? Choose your default editor: Visual Studio Code ? Choose the type of app that you're building javascript Please tell us about your project ? What javascript framework are you using react ? Source Directory Path: src ? Distribution Directory Path: build ? Build Command: yarn build ? Start Command: yarn start 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? Yes ? Please choose the profile you want to use amplify Adding backend environment dev to AWS Amplify Console app: d1ntmmvoqyxue2 ⠏ Initializing project in the cloud... CREATE_IN_PROGRESS DeploymentBucket AWS::S3::Bucket Sat Feb 22 2020 19:27:48 GMT+0900 (日本標準時) Resource creation Initiated CREATE_IN_PROGRESS UnauthRole AWS::IAM::Role Sat Feb 22 2020 19:27:47 GMT+0900 (日本標準時) Resource creation Initiated CREATE_IN_PROGRESS AuthRole AWS::IAM::Role Sat Feb 22 2020 19:27:47 GMT+0900 (日本標準時) Resource creation Initiated CREATE_IN_PROGRESS UnauthRole AWS::IAM::Role Sat Feb 22 2020 19:27:46 GMT+0900 (日本標準時) CREATE_IN_PROGRESS DeploymentBucket AWS::S3::Bucket Sat Feb 22 2020 19:27:46 GMT+0900 (日本標準時) CREATE_IN_PROGRESS AuthRole AWS::IAM::Role Sat Feb 22 2020 19:27:46 GMT+0900 (日本標準時) CREATE_IN_PROGRESS amplify-next-amplify-example-dev-192739 AWS::CloudFormation::Stack Sat Feb 22 2020 19:27:43 GMT+0900 (日本標準時) User Initiated ⠼ Initializing project in the cloud... CREATE_COMPLETE UnauthRole AWS::IAM::Role Sat Feb 22 2020 19:28:01 GMT+0900 (日本標準時) CREATE_COMPLETE AuthRole AWS::IAM::Role Sat Feb 22 2020 19:28:01 GMT+0900 (日本標準時) ⠼ Initializing project in the cloud... CREATE_COMPLETE DeploymentBucket AWS::S3::Bucket Sat Feb 22 2020 19:28:08 GMT+0900 (日本標準時) ⠦ Initializing project in the cloud... CREATE_COMPLETE amplify-next-amplify-example-dev-192739 AWS::CloudFormation::Stack Sat Feb 22 2020 19:28:11 GMT+0900 (日本標準時) ✔ 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 publish" to deploy everything
import React from 'react' class Home extends React.Component { render() { return ( <div> <div className="hero"> <h1 className="title">Welcome to Next.js!</h1> <p className="description"> To get started, edit <code>pages/index.js</code> and save to reload. </p> <div className="row"> <a href="https://nextjs.org/docs" className="card"> <h3>Documentation →</h3> <p>Learn more about Next.js in the documentation.</p> </a> <a href="https://nextjs.org/learn" className="card"> <h3>Next.js Learn →</h3> <p>Learn about Next.js by following an interactive tutorial!</p> </a> <a href="https://github.com/zeit/next.js/tree/master/examples" className="card" > <h3>Examples →</h3> <p>Find other example boilerplates on the Next.js GitHub.</p> </a> </div> </div> <style jsx>{` .hero { width: 100%; color: #333; } .title { margin: 0; width: 100%; padding-top: 80px; line-height: 1.15; font-size: 48px; } .title, .description { text-align: center; } .row { max-width: 880px; margin: 80px auto 40px; display: flex; flex-direction: row; justify-content: space-around; } .card { padding: 18px 18px 24px; width: 220px; text-align: left; text-decoration: none; color: #434343; border: 1px solid #9b9b9b; } .card:hover { border-color: #067df7; } .card h3 { margin: 0; color: #067df7; font-size: 18px; } .card p { margin: 0; padding: 12px 0 0; font-size: 13px; color: #333; } `}</style> </div> ) } } export default Home
3.2.2. amplify add auth
amplify から Cognito を使用して認証するため、 amplify add auth を行います。 多分、Cognito 以外も使えそうですが、今回は Cognito を使うために追加するとお考えください。
amplify add auth
こんな感じです。今回はザルセキュリティで良い(あくまでもサンプルなので)ので、ユーザー名とパスワードでのみの認証とします。 (本来なら、メールアドレス他、色々と設定すべきでしょう)
$ amplify add auth Using service: Cognito, provided by: awscloudformation The current configured provider is Amazon Cognito. Do you want to use the default authentication and security configuration? Default configuration Warning: you will not be able to edit these selections. How do you want users to be able to sign in? Username Do you want to configure advanced settings? No, I am done. Successfully added resource nextamplifyexample6c8f8585 locally Some next steps: "amplify push" will build all your local backend resources and provision it in the cloud "amplify publish" will build all your local backend and frontend resources (if you have hosting category added) and provision it in the cloud
3.3. amplify バックグラウンド(AWS側のリソース)の構築
"amplify push" will build all your local backend resources and provision it in the cloud
とあるように、AWS側のリソースを構築する必要があります。
amplify push
を実行すると、CloudFormation スタックが更新されて ネステッドスタックとなります。 また、Cognito のリソースが作られます。
$ amplify push ✔ Successfully pulled backend environment dev from the cloud. Current Environment: dev | Category | Resource name | Operation | Provider plugin | | -------- | -------------------------- | --------- | ----------------- | | Auth | nextamplifyexample0dde88af | Create | awscloudformation | ? Are you sure you want to continue? Yes ⠏ Updating resources in the cloud. This may take a few minutes... CREATE_IN_PROGRESS authnextamplifyexample0dde88af AWS::CloudFormation::Stack Sat Feb 22 2020 19:37:35 GMT+0900 (日本標準時) Resource creation Initiated CREATE_IN_PROGRESS authnextamplifyexample0dde88af AWS::CloudFormation::Stack Sat Feb 22 2020 19:37:34 GMT+0900 (日本標準時) CREATE_IN_PROGRESS UpdateRolesWithIDPFunctionRole AWS::IAM::Role Sat Feb 22 2020 19:37:34 GMT+0900 (日本標準時) Resource creation Initiated CREATE_IN_PROGRESS UpdateRolesWithIDPFunctionRole AWS::IAM::Role Sat Feb 22 2020 19:37:33 GMT+0900 (日本標準時) UPDATE_IN_PROGRESS amplify-next-amplify-example-dev-192739 AWS::CloudFormation::Stack Sat Feb 22 2020 19:37:29 GMT+0900 (日本標準時) User Initiated ⠴ Updating resources in the cloud. This may take a few minutes... CREATE_IN_PROGRESS amplify-next-amplify-example-dev-192739-authnextamplifyexample0dde88af-1PWQ9Y8ZW1F9F AWS::CloudFormation::Stack Sat Feb 22 2020 19:37:35 GMT+0900 (日本標準時) User Initiated ⠇ Updating resources in the cloud. This may take a few minutes... CREATE_IN_PROGRESS SNSRole AWS::IAM::Role Sat Feb 22 2020 19:37:40 GMT+0900 (日本標準時) Resource creation Initiated CREATE_IN_PROGRESS SNSRole AWS::IAM::Role Sat Feb 22 2020 19:37:40 GMT+0900 (日本標準時) ⠴ Updating resources in the cloud. This may take a few minutes... CREATE_COMPLETE UpdateRolesWithIDPFunctionRole AWS::IAM::Role Sat Feb 22 2020 19:37:48 GMT+0900 (日本標準時) ⠹ Updating resources in the cloud. This may take a few minutes... CREATE_COMPLETE SNSRole AWS::IAM::Role Sat Feb 22 2020 19:37:55 GMT+0900 (日本標準時) ⠼ Updating resources in the cloud. This may take a few minutes... CREATE_IN_PROGRESS UserPool AWS::Cognito::UserPool Sat Feb 22 2020 19:37:58 GMT+0900 (日本標準時) ⠸ Updating resources in the cloud. This may take a few minutes... CREATE_COMPLETE UserPool AWS::Cognito::UserPool Sat Feb 22 2020 19:38:01 GMT+0900 (日本標準時) CREATE_IN_PROGRESS UserPool AWS::Cognito::UserPool Sat Feb 22 2020 19:38:01 GMT+0900 (日本標準時) Resource creation Initiated ⠴ Updating resources in the cloud. This may take a few minutes... CREATE_COMPLETE UserPoolClient AWS::Cognito::UserPoolClient Sat Feb 22 2020 19:38:06 GMT+0900 (日本標準時) CREATE_IN_PROGRESS UserPoolClient AWS::Cognito::UserPoolClient Sat Feb 22 2020 19:38:05 GMT+0900 (日本標準時) Resource creation Initiated CREATE_COMPLETE UserPoolClientWeb AWS::Cognito::UserPoolClient Sat Feb 22 2020 19:38:05 GMT+0900 (日本標準時) CREATE_IN_PROGRESS UserPoolClientWeb AWS::Cognito::UserPoolClient Sat Feb 22 2020 19:38:05 GMT+0900 (日本標準時) Resource creation Initiated CREATE_IN_PROGRESS UserPoolClient AWS::Cognito::UserPoolClient Sat Feb 22 2020 19:38:04 GMT+0900 (日本標準時) CREATE_IN_PROGRESS UserPoolClientWeb AWS::Cognito::UserPoolClient Sat Feb 22 2020 19:38:04 GMT+0900 (日本標準時) ⠇ Updating resources in the cloud. This may take a few minutes... CREATE_IN_PROGRESS UserPoolClientRole AWS::IAM::Role Sat Feb 22 2020 19:38:10 GMT+0900 (日本標準時) Resource creation Initiated CREATE_IN_PROGRESS UserPoolClientRole AWS::IAM::Role Sat Feb 22 2020 19:38:09 GMT+0900 (日本標準時) ⠸ Updating resources in the cloud. This may take a few minutes... CREATE_COMPLETE UserPoolClientRole AWS::IAM::Role Sat Feb 22 2020 19:38:24 GMT+0900 (日本標準時) ⠸ Updating resources in the cloud. This may take a few minutes... CREATE_COMPLETE UserPoolClientLambda AWS::Lambda::Function Sat Feb 22 2020 19:38:28 GMT+0900 (日本標準時) CREATE_IN_PROGRESS UserPoolClientLambda AWS::Lambda::Function Sat Feb 22 2020 19:38:27 GMT+0900 (日本標準時) Resource creation Initiated CREATE_IN_PROGRESS UserPoolClientLambda AWS::Lambda::Function Sat Feb 22 2020 19:38:27 GMT+0900 (日本標準時) ⠹ Updating resources in the cloud. This may take a few minutes... CREATE_IN_PROGRESS UserPoolClientLambdaPolicy AWS::IAM::Policy Sat Feb 22 2020 19:38:31 GMT+0900 (日本標準時) ⠼ Updating resources in the cloud. This may take a few minutes... CREATE_IN_PROGRESS UserPoolClientLambdaPolicy AWS::IAM::Policy Sat Feb 22 2020 19:38:32 GMT+0900 (日本標準時) Resource creation Initiated ⠇ Updating resources in the cloud. This may take a few minutes... CREATE_COMPLETE UserPoolClientLambdaPolicy AWS::IAM::Policy Sat Feb 22 2020 19:38:45 GMT+0900 (日本標準時) ⠧ Updating resources in the cloud. This may take a few minutes... CREATE_IN_PROGRESS UserPoolClientLogPolicy AWS::IAM::Policy Sat Feb 22 2020 19:38:49 GMT+0900 (日本標準時) Resource creation Initiated CREATE_IN_PROGRESS UserPoolClientLogPolicy AWS::IAM::Policy Sat Feb 22 2020 19:38:48 GMT+0900 (日本標準時) ⠹ Updating resources in the cloud. This may take a few minutes... CREATE_IN_PROGRESS UserPoolClientInputs Custom::LambdaCallout Sat Feb 22 2020 19:39:05 GMT+0900 (日本標準時) CREATE_COMPLETE UserPoolClientLogPolicy AWS::IAM::Policy Sat Feb 22 2020 19:39:03 GMT+0900 (日本標準時) ⠹ Updating resources in the cloud. This may take a few minutes... CREATE_COMPLETE UserPoolClientInputs Custom::LambdaCallout Sat Feb 22 2020 19:39:09 GMT+0900 (日本標準時) CREATE_IN_PROGRESS UserPoolClientInputs Custom::LambdaCallout Sat Feb 22 2020 19:39:09 GMT+0900 (日本標準時) Resource creation Initiated ⠦ Updating resources in the cloud. This may take a few minutes... CREATE_COMPLETE IdentityPool AWS::Cognito::IdentityPool Sat Feb 22 2020 19:39:14 GMT+0900 (日本標準時) CREATE_IN_PROGRESS IdentityPool AWS::Cognito::IdentityPool Sat Feb 22 2020 19:39:13 GMT+0900 (日本標準時) Resource creation Initiated CREATE_IN_PROGRESS IdentityPool AWS::Cognito::IdentityPool Sat Feb 22 2020 19:39:12 GMT+0900 (日本標準時) ⠦ Updating resources in the cloud. This may take a few minutes... CREATE_COMPLETE IdentityPoolRoleMap AWS::Cognito::IdentityPoolRoleAttachment Sat Feb 22 2020 19:39:20 GMT+0900 (日本標準時) CREATE_IN_PROGRESS IdentityPoolRoleMap AWS::Cognito::IdentityPoolRoleAttachment Sat Feb 22 2020 19:39:20 GMT+0900 (日本標準時) Resource creation Initiated CREATE_IN_PROGRESS IdentityPoolRoleMap AWS::Cognito::IdentityPoolRoleAttachment Sat Feb 22 2020 19:39:18 GMT+0900 (日本標準時) ⠙ Updating resources in the cloud. This may take a few minutes... CREATE_COMPLETE amplify-next-amplify-example-dev-192739-authnextamplifyexample0dde88af-1PWQ9Y8ZW1F9F AWS::CloudFormation::Stack Sat Feb 22 2020 19:39:22 GMT+0900 (日本標準時) ⠋ Updating resources in the cloud. This may take a few minutes... CREATE_COMPLETE authnextamplifyexample0dde88af AWS::CloudFormation::Stack Sat Feb 22 2020 19:39:29 GMT+0900 (日本標準時) ⠏ Updating resources in the cloud. This may take a few minutes... CREATE_IN_PROGRESS UpdateRolesWithIDPFunction AWS::Lambda::Function Sat Feb 22 2020 19:39:31 GMT+0900 (日本標準時) Resource creation Initiated CREATE_IN_PROGRESS UpdateRolesWithIDPFunction AWS::Lambda::Function Sat Feb 22 2020 19:39:30 GMT+0900 (日本標準時) ⠹ Updating resources in the cloud. This may take a few minutes... CREATE_IN_PROGRESS UpdateRolesWithIDPFunctionOutputs Custom::LambdaCallout Sat Feb 22 2020 19:39:33 GMT+0900 (日本標準時) CREATE_COMPLETE UpdateRolesWithIDPFunction AWS::Lambda::Function Sat Feb 22 2020 19:39:31 GMT+0900 (日本標準時) ⠼ Updating resources in the cloud. This may take a few minutes... UPDATE_COMPLETE amplify-next-amplify-example-dev-192739 AWS::CloudFormation::Stack Sat Feb 22 2020 19:39:39 GMT+0900 (日本標準時) UPDATE_COMPLETE_CLEANUP_IN_PROGRESS amplify-next-amplify-example-dev-192739 AWS::CloudFormation::Stack Sat Feb 22 2020 19:39:39 GMT+0900 (日本標準時) CREATE_COMPLETE UpdateRolesWithIDPFunctionOutputs Custom::LambdaCallout Sat Feb 22 2020 19:39:37 GMT+0900 (日本標準時) CREATE_IN_PROGRESS UpdateRolesWithIDPFunctionOutputs Custom::LambdaCallout Sat Feb 22 2020 19:39:36 GMT+0900 (日本標準時) Resource creation Initiated ✔ All resources are updated in the cloud
ここまでで、Cognito を呼び出す下地は出来ました。
あとは、アプリのコードから amplify を使って Cognito を呼び出すだけです!
3.4. アプリへの組み込み
に従って組み込んでみましょう!
因みに、今回は pages/index.tsx へ組み込みました。 Layout など、components 配下のコンポーネントを必ず組み込むようにする場合は、そちらに記述した方が良いかもしれません。
import Amplify from 'aws-amplify'; import config from '../aws-exports'; Amplify.configure(config); class Home extends React.Component { render() { return ( <div> // 以下略
続いて pages/_app.tsx
import * as React from 'react'; import App from 'next/app'; import { withAuthenticator } from 'aws-amplify-react'; class MyApp extends App { render() { const { Component, pageProps } = this.props; return (<Component {...pageProps} />) } } export default withAuthenticator(MyApp)
さぁ!これで yarn run dev
すっぞ!
$ yarn run dev yarn run v1.22.0 $ next [ wait ] starting the development server ... [ info ] waiting on http://localhost:3000 ... [ error ] ./node_modules/@aws-amplify/ui/dist/style.css Global CSS cannot be imported from within node_modules. Read more: https://err.sh/next.js/css-npm Location: node_modules/aws-amplify-react/lib-esm/Amplify-UI/Amplify-UI-Components-React.js
はい。。。コケました。
@zeit/next-css
を追加して、 next.config.js
を修正すれば良いようです。
$ yarn add -D @zeit/next-css yarn add v1.22.0 [1/4] 🔍 Resolving packages... [2/4] 🚚 Fetching packages... [3/4] 🔗 Linking dependencies... warning "aws-amplify > @aws-amplify/api@2.1.5" has incorrect peer dependency "@aws-amplify/pubsub@^1.2.4". warning " > aws-amplify-react@3.1.6" has unmet peer dependency "@aws-amplify/analytics@^2.0.0". warning " > aws-amplify-react@3.1.6" has unmet peer dependency "@aws-amplify/api@^2.0.0". warning " > aws-amplify-react@3.1.6" has unmet peer dependency "@aws-amplify/auth@^2.0.0". warning " > aws-amplify-react@3.1.6" has unmet peer dependency "@aws-amplify/core@^2.0.0". warning " > aws-amplify-react@3.1.6" has unmet peer dependency "@aws-amplify/interactions@^2.0.0". warning " > aws-amplify-react@3.1.6" has unmet peer dependency "@aws-amplify/storage@^2.0.0". warning " > aws-amplify-react@3.1.6" has unmet peer dependency "@aws-amplify/ui@^2.0.0". warning "@zeit/next-css > css-loader@1.0.0" has unmet peer dependency "webpack@^4.0.0". warning "@zeit/next-css > mini-css-extract-plugin@0.4.3" has unmet peer dependency "webpack@^4.4.0". [4/4] 🔨 Building fresh packages... warning "@zeit/next-css" is already in "dependencies". Please remove existing entry first before adding it to "devDependencies". success Saved 1 new dependency. info Direct dependencies └─ @zeit/next-css@1.0.1 info All dependencies └─ @zeit/next-css@1.0.1 ✨ Done in 1.85s.
const withCSS = require("@zeit/next-css"); if (typeof require !== "undefined") { require.extensions[".less"] = () => {}; require.extensions[".css"] = (file) => {}; } const config = { target: process.env.NODE_ENV !== 'production' ? 'server' : 'serverless', dontAutoRegisterSw: false, generateSw: false, devSwSrc: 'src/public/sw.js', workboxOpts: { swSrc: 'src/public/sw.js', swDest: 'src/public/service-worker.js' } } module.exports = withCSS(config)
としました。
$ yarn run dev yarn run v1.22.0 $ next [ wait ] starting the development server ... [ info ] waiting on http://localhost:3000 ... [ info ] bundled successfully, waiting for typecheck results... [ wait ] compiling ... [ info ] bundled successfully, waiting for typecheck results... [ ready ] compiled successfully - ready on http://localhost:3000 [ event ] build page: /next/dist/pages/_error [ wait ] compiling ... [ info ] bundled successfully, waiting for typecheck results... [ ready ] compiled successfully - ready on http://localhost:3000 [ event ] build page: / [ wait ] compiling ... [ info ] bundled successfully, waiting for typecheck results... [ ready ] compiled successfully - ready on http://localhost:3000 [ info ] bundled successfully, waiting for typecheck results... [ ready ] compiled successfully - ready on http://localhost:3000
エラーがなくなりました。
http://localhost:3000 へアクセスしましょう。
きたー!
ユーザー登録(Create account をクリック)時に入力したメールアドレスに以下のようなワンタイムトークンが送られてくるため、 遷移した画面で入力します。
すると。。。
に戻ります。
ここで、登録したユーザー名とパスワードを入力して SIGN IN をクリックするとログイン出来ます。
4. サインアウト機能
さて、ここまでで Amplify と Cognitoを使用して、ローカルでサインイン出来るようになりました。
でも、サインアウト出来るようにしておかないとダメですよね?(滅多に使わないから期間過ぎたら自動的にサインアウトするように Cognito を設定しておけばよくね?というツッコミは無しで)
テキストリンクでも良いのですが、ボタンを配置してみましょう。
Material UI コンポーネントを追加します。
yarn add @material-ui/core @material-ui/icons
$ yarn add @material-ui/core @material-ui/icons yarn add v1.22.0 [1/4] 🔍 Resolving packages... warning @material-ui/core > popper.js@1.16.1: You can find the new Popper v2 at @popperjs/core, this package is dedicated to the legacy v1 [2/4] 🚚 Fetching packages... [3/4] 🔗 Linking dependencies... warning "@zeit/next-css > css-loader@1.0.0" has unmet peer dependency "webpack@^4.0.0". warning "@zeit/next-css > mini-css-extract-plugin@0.4.3" has unmet peer dependency "webpack@^4.4.0". warning "aws-amplify > @aws-amplify/api@2.1.5" has incorrect peer dependency "@aws-amplify/pubsub@^1.2.4". warning " > aws-amplify-react@3.1.6" has unmet peer dependency "@aws-amplify/analytics@^2.0.0". warning " > aws-amplify-react@3.1.6" has unmet peer dependency "@aws-amplify/api@^2.0.0". warning " > aws-amplify-react@3.1.6" has unmet peer dependency "@aws-amplify/auth@^2.0.0". warning " > aws-amplify-react@3.1.6" has unmet peer dependency "@aws-amplify/core@^2.0.0". warning " > aws-amplify-react@3.1.6" has unmet peer dependency "@aws-amplify/interactions@^2.0.0". warning " > aws-amplify-react@3.1.6" has unmet peer dependency "@aws-amplify/storage@^2.0.0". warning " > aws-amplify-react@3.1.6" has unmet peer dependency "@aws-amplify/ui@^2.0.0". [4/4] 🔨 Building fresh packages... success Saved lockfile. success Saved 21 new dependencies. info Direct dependencies ├─ @material-ui/core@4.9.3 └─ @material-ui/icons@4.9.1 info All dependencies ├─ @emotion/hash@0.7.4 ├─ @material-ui/core@4.9.3 ├─ @material-ui/icons@4.9.1 ├─ @material-ui/styles@4.9.0 ├─ @material-ui/system@4.9.3 ├─ @types/react-transition-group@4.2.3 ├─ convert-css-length@2.0.1 ├─ css-vendor@2.0.7 ├─ dom-helpers@5.1.3 ├─ hoist-non-react-statics@3.3.2 ├─ hyphenate-style-name@1.0.3 ├─ is-in-browser@1.1.3 ├─ jss-plugin-camel-case@10.0.4 ├─ jss-plugin-default-unit@10.0.4 ├─ jss-plugin-global@10.0.4 ├─ jss-plugin-nested@10.0.4 ├─ jss-plugin-props-sort@10.0.4 ├─ jss-plugin-rule-value-function@10.0.4 ├─ jss-plugin-vendor-prefixer@10.0.4 ├─ popper.js@1.16.1 └─ react-transition-group@4.3.0 ✨ Done in 5.88s.
index.tsx には以下のように追加します。
に記載されている通り、 Auth
モジュールの signOut()
を呼び出せば良いだけですね。
import React from 'react' import Amplify, { Auth } from 'aws-amplify'; import config from '../aws-exports'; import Button from '@material-ui/core/Button'; import ExitToAppIcon from '@material-ui/icons/ExitToApp'; Amplify.configure(config); class Home extends React.Component { logout() { Auth.signOut() .then(data => console.log(data)) .catch(err => console.log(err)); } render() { return ( <div> <Button onClick={this.logout} variant="contained" color="primary" startIcon={<ExitToAppIcon />} > SIGN OUT </Button> // (以下略)
はい、出来ました。
5. amplify アプリの publish までの道のり
実は未だ、amplify アプリの publish は出来ません。
$ amplify publish Please add hosting to your project before publishing your project Command: amplify hosting add
5.1. amplify hosting add
amplify hosting add
を行うと、以下のように聞かれます。
$ amplify hosting add ? Select the environment setup: (Use arrow keys) ❯ DEV (S3 only with HTTP) PROD (S3 with CloudFront using HTTPS)
とりえず、DEV を選択してCloudFront経由にしないようにして進めます。
$ amplify publish ✔ Successfully pulled backend environment dev from the cloud. Current Environment: dev | Category | Resource name | Operation | Provider plugin | | -------- | -------------------------- | --------- | ----------------- | | Hosting | S3AndCloudFront | Create | awscloudformation | | Auth | nextamplifyexample0dde88af | No Change | awscloudformation | ? Are you sure you want to continue? (Y/n)
何か、CloudFront の文字が見えるような… まぁ、無料枠ならお金かからないから良いや。
$ amplify publish ✔ Successfully pulled backend environment dev from the cloud. Current Environment: dev | Category | Resource name | Operation | Provider plugin | | -------- | -------------------------- | --------- | ----------------- | | Hosting | S3AndCloudFront | Create | awscloudformation | | Auth | nextamplifyexample0dde88af | No Change | awscloudformation | ? Are you sure you want to continue? Yes ⠹ Updating resources in the cloud. This may take a few minutes... UPDATE_COMPLETE authnextamplifyexample0dde88af AWS::CloudFormation::Stack Sat Feb 22 2020 21:46:27 GMT+0900 (日本標準時) UPDATE_IN_PROGRESS authnextamplifyexample0dde88af AWS::CloudFormation::Stack Sat Feb 22 2020 21:46:26 GMT+0900 (日本標準時) CREATE_IN_PROGRESS hostingS3AndCloudFront AWS::CloudFormation::Stack Sat Feb 22 2020 21:46:26 GMT+0900 (日本標準時) Resource creation Initiated CREATE_IN_PROGRESS hostingS3AndCloudFront AWS::CloudFormation::Stack Sat Feb 22 2020 21:46:25 GMT+0900 (日本標準時) UPDATE_IN_PROGRESS amplify-next-amplify-example-dev-192739 AWS::CloudFormation::Stack Sat Feb 22 2020 21:46:22 GMT+0900 (日本標準時) User Initiated ⠇ Updating resources in the cloud. This may take a few minutes... CREATE_IN_PROGRESS amplify-next-amplify-example-dev-192739-hostingS3AndCloudFront-153OK6UCXJPBA AWS::CloudFormation::Stack Sat Feb 22 2020 21:46:26 GMT+0900 (日本標準時) User Initiated ⠋ Updating resources in the cloud. This may take a few minutes... CREATE_IN_PROGRESS S3Bucket AWS::S3::Bucket Sat Feb 22 2020 21:46:29 GMT+0900 (日本標準時) ⠋ Updating resources in the cloud. This may take a few minutes... CREATE_IN_PROGRESS S3Bucket AWS::S3::Bucket Sat Feb 22 2020 21:46:30 GMT+0900 (日本標準時) Resource creation Initiated ⠙ Updating resources in the cloud. This may take a few minutes... CREATE_COMPLETE amplify-next-amplify-example-dev-192739-hostingS3AndCloudFront-153OK6UCXJPBA AWS::CloudFormation::Stack Sat Feb 22 2020 21:46:53 GMT+0900 (日本標準時) CREATE_COMPLETE S3Bucket AWS::S3::Bucket Sat Feb 22 2020 21:46:52 GMT+0900 (日本標準時) ⠹ Updating resources in the cloud. This may take a few minutes... UPDATE_COMPLETE_CLEANUP_IN_PROGRESS amplify-next-amplify-example-dev-192739 AWS::CloudFormation::Stack Sat Feb 22 2020 21:47:02 GMT+0900 (日本標準時) CREATE_COMPLETE hostingS3AndCloudFront AWS::CloudFormation::Stack Sat Feb 22 2020 21:47:00 GMT+0900 (日本標準時) ⠋ Updating resources in the cloud. This may take a few minutes... UPDATE_COMPLETE amplify-next-amplify-example-dev-192739 AWS::CloudFormation::Stack Sat Feb 22 2020 21:47:03 GMT+0900 (日本標準時) UPDATE_COMPLETE authnextamplifyexample0dde88af AWS::CloudFormation::Stack Sat Feb 22 2020 21:47:03 GMT+0900 (日本標準時) ✔ All resources are updated in the cloud Hosting endpoint: http://next-amplify-example-20200222214113-hostingbucket-dev.s3-website-us-west-2.amazonaws.com yarn run v1.22.0 $ next build Creating an optimized production build Compiled with warnings. ./node_modules/next/dist/next-server/server/load-components.js Critical dependency: the request of a dependency is an expression ./node_modules/next/dist/next-server/server/load-components.js Critical dependency: the request of a dependency is an expression ./node_modules/next/dist/next-server/server/load-components.js Critical dependency: the request of a dependency is an expression ./node_modules/next/dist/next-server/server/load-components.js Critical dependency: the request of a dependency is an expression ./node_modules/next/dist/next-server/server/require.js Critical dependency: the request of a dependency is an expression ./node_modules/next/dist/next-server/server/require.js Critical dependency: the request of a dependency is an expression Automatically optimizing pages Page Size First Load ┌ ○ / 256 kB 608 kB └ /_app 46.4 kB 315 kB + shared by all 315 kB ├ static/_buildManifest.js 189 B ├ static/pages/_app.js 46.4 kB ├ chunks/242e76a06b3fa367d89c78b62af50ae3b459294c.a43009.js 11.7 kB ├ chunks/29107295.d41bbf.js 24.5 kB ├ chunks/c277677ab6f8ae068064b60157bc6d3cd2fd2c95.ea5b2a.js 173 kB ├ chunks/commons.af9b44.js 13 kB ├ chunks/framework.74d547.js 40.8 kB ├ chunks/styles.15b445.js 87 B ├ runtime/main.e744f1.js 4.74 kB └ runtime/webpack.4b444d.js 746 B λ (Lambda) server-side renders at runtime (uses getInitialProps or getServerProps) ○ (Static) automatically rendered as static HTML (uses no initial props) ● (SSG) automatically generated as static HTML + JSON (uses getStaticProps) ✨ Done in 15.16s. frontend build command exited with code 0 Cannot find the distribution folder. Distribution folder is currently set as: /Users/ken-yo/next-amplify-example/build Cannot find the distribution folder. Error: Cannot find the distribution folder. at Object.scan (/usr/local/lib/node_modules/@aws-amplify/cli/node_modules/amplify-category-hosting/lib/S3AndCloudFront/helpers/file-scanner.js:38:11) at Object.run (/usr/local/lib/node_modules/@aws-amplify/cli/node_modules/amplify-category-hosting/lib/S3AndCloudFront/helpers/file-uploader.js:16:32) at Object.publish (/usr/local/lib/node_modules/@aws-amplify/cli/node_modules/amplify-category-hosting/lib/S3AndCloudFront/index.js:116:6) at Object.runServiceAction (/usr/local/lib/node_modules/@aws-amplify/cli/node_modules/amplify-category-hosting/lib/category-manager.js:63:31) at Object.publish (/usr/local/lib/node_modules/@aws-amplify/cli/node_modules/amplify-category-hosting/index.js:69:30) at publishToHostingBucket (/usr/local/lib/node_modules/@aws-amplify/cli/node_modules/amplify-frontend-javascript/lib/publisher.js:22:30) at processTicksAndRejections (internal/process/task_queues.js:97:5)
コケて上手く行きません…
build ディレクトリーが無いと言われてますね。
以下のように修正しました。
{ "name": "next-amplify-example", "version": "1.0.0", "private": true, "license": "MIT", "scripts": { "test": "jest --passWithNoTests", "dev": "next", "build": "next build && next export && rm -rf build && mv out build", "start": "next start", "lint": "eslint --ext .ts,.js,.tsx,.jsx src" }, "lint-staged": { "src/*.{ts,js,tsx,jsx}": "eslint" }, "husky": { "hooks": { "pre-commit": "lint-staged" } }, "dependencies": { "@material-ui/core": "^4.9.3", "@material-ui/icons": "^4.9.1", "@types/node": "^13.7.4", "@types/react": "^16.9.22", "@zeit/next-css": "^1.0.1", "aws-amplify": "^2.2.5", "aws-amplify-react": "^3.1.6", "next": "^9.2.2", "react": "^16.12.0", "react-dom": "^16.12.0" }, "devDependencies": { "typescript": "^3.8.2" } }
"build": "next build && next export && rm -rf build && mv out build"
がポイントですね。
$ amplify publish ✔ Successfully pulled backend environment dev from the cloud. Current Environment: dev | Category | Resource name | Operation | Provider plugin | | -------- | -------------------------- | --------- | ----------------- | | Auth | nextamplifyexample0dde88af | No Change | awscloudformation | | Hosting | S3AndCloudFront | No Change | awscloudformation | No changes detected yarn run v1.22.0 $ next build && next export && mv out build Creating an optimized production build Compiled with warnings. ./node_modules/next/dist/next-server/server/load-components.js Critical dependency: the request of a dependency is an expression ./node_modules/next/dist/next-server/server/load-components.js Critical dependency: the request of a dependency is an expression ./node_modules/next/dist/next-server/server/load-components.js Critical dependency: the request of a dependency is an expression ./node_modules/next/dist/next-server/server/load-components.js Critical dependency: the request of a dependency is an expression ./node_modules/next/dist/next-server/server/require.js Critical dependency: the request of a dependency is an expression ./node_modules/next/dist/next-server/server/require.js Critical dependency: the request of a dependency is an expression Automatically optimizing pages Page Size First Load ┌ ○ / 256 kB 608 kB └ /_app 46.4 kB 315 kB + shared by all 315 kB ├ static/_buildManifest.js 189 B ├ static/pages/_app.js 46.4 kB ├ chunks/29107295.6cce3a.js 24.5 kB ├ chunks/5d3dd53bfefaaba7d132131a0ba097ceb6bf38d5.961381.js 11.7 kB ├ chunks/79d124448b8210c46ac0124c1c9c03bef3930399.ea5b2a.js 173 kB ├ chunks/commons.af9b44.js 13 kB ├ chunks/framework.74d547.js 40.8 kB ├ chunks/styles.15b445.js 87 B ├ runtime/main.d64045.js 4.74 kB └ runtime/webpack.4b444d.js 746 B λ (Lambda) server-side renders at runtime (uses getInitialProps or getServerProps) ○ (Static) automatically rendered as static HTML (uses no initial props) ● (SSG) automatically generated as static HTML + JSON (uses getStaticProps) > using build directory: /Users/ken-yo/next-amplify-example/.next copying "static build" directory > No "exportPathMap" found in "next.config.js". Generating map from "./pages" launching 15 workers Exporting (5/5) Export successful ✨ Done in 11.93s. frontend build command exited with code 0 ✔ Uploaded files successfully. Your app is published successfully. http://next-amplify-example-20200222214113-hostingbucket-dev.s3-website-us-west-2.amazonaws.com
出来ました!
ただ、 GitHub - poad/next-ts-template のブランチを元に作成した場合、next.config.js を次のように修正しないと、
aws-amplify-react
の Global Stylesheet 関連の処理やら styled-jsx やらとの兼ね合いでコケました。(styled-jsx は結果的に使っていないので yarn remove しました)
因みに、 yarn run dev
ではコケずに yarn build
でだけコケるとかあったのでご注意を!
const withCSS = require('@zeit/next-css') if (typeof require !== "undefined") { require.extensions[".less"] = () => { }; require.extensions[".css"] = (file) => { }; } const resolve = require('resolve') global.navigator = () => null const config = { webpack(config, options) { const { dir, isServer } = options config.externals = [] if (isServer) { config.externals.push((context, request, callback) => { resolve(request, { basedir: dir, preserveSymlinks: true }, (err, res) => { if (err) { return callback() } if ( res.match(/node_modules[/\\].*\.css/) && !res.match(/node_modules[/\\]webpack/) && !res.match(/node_modules[/\\]@aws-amplify/) ) { return callback(null, `css ${request}`) } callback() }) }) } return config } } module.exports = withCSS(config)
と、なかなかハマりどころ多いですが、Nuxt.js(Vue.js) + TypeScript + amplify よりは簡単そうです。
next.config.js の修正が不味いケース
その1
$ yarn build yarn run v1.22.0 $ next build Creating an optimized production build Compiled successfully. Automatically optimizing pages ..Service Worker Loaded... > Build error occurred ReferenceError: self is not defined at Object.C+qz (/Users/ken-yo/git/es-examples/next-examples/next-amplify-example/.next/server/static/23FhuuakIG-ehoL-uwoCM/pages/sw.js:108:1) at __webpack_require__ (/Users/ken-yo/git/es-examples/next-examples/next-amplify-example/.next/server/static/23FhuuakIG-ehoL-uwoCM/pages/sw.js:23:31) at Object.3 (/Users/ken-yo/git/es-examples/next-examples/next-amplify-example/.next/server/static/23FhuuakIG-ehoL-uwoCM/pages/sw.js:99:18) at __webpack_require__ (/Users/ken-yo/git/es-examples/next-examples/next-amplify-example/.next/server/static/23FhuuakIG-ehoL-uwoCM/pages/sw.js:23:31) at /Users/ken-yo/git/es-examples/next-examples/next-amplify-example/.next/server/static/23FhuuakIG-ehoL-uwoCM/pages/sw.js:91:18 at Object.<anonymous> (/Users/ken-yo/git/es-examples/next-examples/next-amplify-example/.next/server/static/23FhuuakIG-ehoL-uwoCM/pages/sw.js:94:10) at Module._compile (internal/modules/cjs/loader.js:1151:30) at Object.Module._extensions..js (internal/modules/cjs/loader.js:1171:10) at Module.load (internal/modules/cjs/loader.js:1000:32) at Function.Module._load (internal/modules/cjs/loader.js:899:14) { type: 'ReferenceError' } error Command failed with exit code 1. info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
とりあえず、next.config.js の中の記述で service worker周りの設定を削って、上述の一番最後に書いた next.config.js へ置き換えてみてください。
その2
$ yarn run dev yarn run v1.22.0 $ next [ wait ] starting the development server ... [ info ] waiting on http://localhost:3000 ... > Using external babel configuration > Location: "/Users/ken-yo/git/es-examples/next-examples/next-amplify-example/.babelrc" [ error ] ./node_modules/@aws-amplify/ui/dist/style.css Global CSS cannot be imported from within node_modules. Read more: https://err.sh/next.js/css-npm Location: node_modules/aws-amplify-react/lib-esm/Amplify-UI/Amplify-UI-Components-React.js
Next.js 公式では非推奨の @zeit/next-css
を追加して…という上述の記事に記載している next.config.js を設定してください。