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 を設定してください。
今回作成したサンプルコード
テンプレートリポジトリーをベースにしたもの
Scala で AWS CDK Javaを使ってみる
はじめに
Scala Advent Calendar 2019 - Qiita の 16日目への寄稿です。
AWS CDK が、 2019年7月11日 に Generally Available となりました。
そして、2019年11月26日に AWS CDK for Java も Generally Available となりました。
Scalaから使ったら更に読み書きし易くなったりしないものだろうか?と思い立ったので試してみます。
環境構築
AWS CDK の Getting Started Prerequisites を見ると、
Node.js が必要とのこと。
マシンのOSに依存させるのは嫌なので、ここではDockerイメージ内で作業することとします。
実行方法は、GitHubリポジトリーのREADMEをご覧ください。
いざ!CDK
実行したコンテナー内で cdk init --language java
を実行します。
[zsh@d535e914ac9e cdk]$ dk init --language java Applying project template app for java Initializing a new git repository... *** Please tell me who you are. Run git config --global user.email "you@example.com" git config --global user.name "Your Name" to set your account's default identity. Omit --global to set the identity only in this repository. fatal: unable to auto-detect email address (got 'zsh@be05ff957502.(none)') Unable to initialize git repository for your project. Executing mvn package... # Welcome to your CDK Java project! This is a blank project for Java development with CDK. The `cdk.json` file tells the CDK Toolkit how to execute your app. It is a [Maven](https://maven.apache.org/) based project, so you can open this project with any Maven compatible Java IDE to build and run tests. ## Useful commands * `mvn package` compile and run tests * `cdk ls` list all stacks in the app * `cdk synth` emits the synthesized CloudFormation template * `cdk deploy` deploy this stack to your default AWS account/region * `cdk diff` compare deployed stack with current state * `cdk docs` open CDK documentation Enjoy! [zsh@d535e914ac9e cdk (master +)]$
これで、 pom.xml が出来ました。
[zsh@d535e914ac9e cdk (master +)]$ ls src target README.md cdk.json pom.xml [zsh@d535e914ac9e cdk (master +)]$
pomの中身とCDKのバージョン
作られたpom.xmlを見てみると、グループIDは software.amazon.awscdk
、バージョンはCDK本体のバージョンの後ろに .DEVPREVIEW
が付与された形。
おそらくGAになったら外れるでしょう。
[zsh@d535e914ac9e cdk (master +)]$ cat pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <modelVersion>4.0.0</modelVersion> <groupId>com.myorg</groupId> <artifactId>cdk</artifactId> <version>0.1</version> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.7.0</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>1.6.0</version> <configuration> <mainClass>com.myorg.CdkApp</mainClass> </configuration> </plugin> </plugins> </build> <dependencies> <!-- AWS Cloud Development Kit --> <dependency> <groupId>software.amazon.awscdk</groupId> <artifactId>core</artifactId> <version>1.18.0</version> </dependency> <!-- https://mvnrepository.com/artifact/junit/junit --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> </dependencies> </project> [zsh@d535e914ac9e cdk (master +)]$ cdk --version 1.18.0 (build bc924bc) [zsh@d535e914ac9e cdk (master +)]$
sbtへ移植
new project
[zsh@73d67aca507d ~]$ sbt new scala/hello-world.g8 [info] Set current project to zsh (in build file:/home/zsh/) [info] Set current project to zsh (in build file:/home/zsh/) A template to demonstrate a minimal Scala application name [Hello World template]: Template applied in /home/zsh/./cdk [zsh@73d67aca507d ~]$ ls cdk target [zsh@73d67aca507d ~]$ cd cdk [zsh@73d67aca507d cdk (master +%)]$ ls project src target README.md build.sbt cdk.json pom.xml [zsh@73d67aca507d cdk (master +%)]$
これで、CDKを使うアプリの本体のベースが出来ました。
build.sbt へ pom.xml の内容を記述して、Scalaのコードを記述していきます。
build.sbt はこんな感じにしました。
import sbt.Keys.{libraryDependencies, scalaVersion} scalaVersion := "2.13.1" name := "hello-world" organization := "com.github.poad" version := "1.0" val cdkVersion = "1.18.0" libraryDependencies ++= Seq( "software.amazon.awscdk" % "core" % cdkVersion )
流石に Java のコードを Scala へ移植する部分や、Javdocを調べてScalaのコードを記述する部分の説明については割愛します。
cdk.json
Getting Started With the AWS CDK - AWS Cloud Development Kit (AWS CDK) の 「cdk ls」を実行すると以下のようなエラーが出力されます。 (Javaのクラスを残したままだと発生しないかと思います。。。)
[zsh@bd8ee7c9cbb6 cdk (master *+)]$ cdk ls [ERROR] Failed to execute goal org.codehaus.mojo:exec-maven-plugin:1.6.0:java (default-cli) on project cdk: An exception occured while executing the Java class. com.myorg.HelloApp -> [Help 1] [ERROR] [ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch. [ERROR] Re-run Maven using the -X switch to enable full debug logging. [ERROR] [ERROR] For more information about the errors and possible solutions, please read the following articles: [ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException Subprocess exited with error 1
あるいは、pom.xml を削除していると、以下のようなエラーが出力されます。
[zsh@bd8ee7c9cbb6 cdk (master *+%)]$ cdk ls [ERROR] Failed to execute goal org.codehaus.mojo:exec-maven-plugin:1.6.0:java (default-cli): Goal requires a project to execute but there is no POM in this directory (/home/zsh/cdk). Please verify you invoked Maven from the correct directory. -> [Help 1] [ERROR] [ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch. [ERROR] Re-run Maven using the -X switch to enable full debug logging. [ERROR] [ERROR] For more information about the errors and possible solutions, please read the following articles: [ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MissingProjectException Subprocess exited with error 1
これらの原因は、cdk init で生成される cdk.json というファイルです。
{ "app": "mvn -e -q exec:java", "context": { "@aws-cdk/core:enableStackNameDuplicates": "true" } }
以下のように書き換えます。
{ "app": "sbt run", "context": { "@aws-cdk/core:enableStackNameDuplicates": "true" } }
これで正しく動くようになります。
[zsh@bd8ee7c9cbb6 cdk (master *+%)]$ cdk ls [info] [launcher] getting org.scala-sbt sbt 1.3.4 (this may take some time)... downloading https://repo1.maven.org/maven2/org/scala-sbt/sbt/1.3.4/sbt-1.3.4.jar ... :: loading settings :: url = jar:file:/usr/local/sbt/bin/sbt-launch.jar!/org/apache/ivy/core/settings/ivysettings.xml downloading https://repo1.maven.org/maven2/org/scala-sbt/main_2.12/1.3.4/main_2.12-1.3.4.jar ... :: loading settings :: url = jar:file:/usr/local/sbt/bin/sbt-launch.jar!/org/apache/ivy/core/settings/ivysettings.xml downloading https://repo1.maven.org/maven2/org/scala-sbt/io_2.12/1.3.1/io_2.12-1.3.1.jar ... downloading https://repo1.maven.org/maven2/org/scala-lang/scala-library/2.12.10/scala-library-2.12.10.jar ... :: loading settings :: url = jar:file:/usr/local/sbt/bin/sbt-launch.jar!/org/apache/ivy/core/settings/ivysettings.xml :: loading settings :: url = jar:file:/usr/local/sbt/bin/sbt-launch.jar!/org/apache/ivy/core/settings/ivysettings.xml [SUCCESSFUL ] org.scala-sbt#sbt;1.3.4!sbt.jar (1087ms) downloading https://repo1.maven.org/maven2/org/scala-sbt/logic_2.12/1.3.4/logic_2.12-1.3.4.jar ... [SUCCESSFUL ] org.scala-sbt#logic_2.12;1.3.4!logic_2.12.jar (460ms) [SUCCESSFUL ] org.scala-sbt#io_2.12;1.3.1!io_2.12.jar (1526ms) downloading https://repo1.maven.org/maven2/org/scala-sbt/main-settings_2.12/1.3.4/main-settings_2.12-1.3.4.jar ... downloading https://repo1.maven.org/maven2/org/scala-sbt/actions_2.12/1.3.4/actions_2.12-1.3.4.jar ... [SUCCESSFUL ] org.scala-sbt#actions_2.12;1.3.4!actions_2.12.jar (595ms) downloading https://repo1.maven.org/maven2/org/scala-sbt/run_2.12/1.3.4/run_2.12-1.3.4.jar ... [SUCCESSFUL ] org.scala-sbt#main-settings_2.12;1.3.4!main-settings_2.12.jar (612ms) downloading https://repo1.maven.org/maven2/org/scala-sbt/command_2.12/1.3.4/command_2.12-1.3.4.jar ... [SUCCESSFUL ] org.scala-sbt#run_2.12;1.3.4!run_2.12.jar (452ms) downloading https://repo1.maven.org/maven2/org/scala-sbt/collections_2.12/1.3.4/collections_2.12-1.3.4.jar ... [SUCCESSFUL ] org.scala-sbt#command_2.12;1.3.4!command_2.12.jar (466ms) downloading https://repo1.maven.org/maven2/org/scala-sbt/scripted-sbt-redux_2.12/1.3.4/scripted-sbt-redux_2.12-1.3.4.jar ... [SUCCESSFUL ] org.scala-lang#scala-library;2.12.10!scala-library.jar (2808ms) downloading https://repo1.maven.org/maven2/org/scala-sbt/scripted-plugin_2.12/1.3.4/scripted-plugin_2.12-1.3.4.jar ... [SUCCESSFUL ] org.scala-sbt#scripted-sbt-redux_2.12;1.3.4!scripted-sbt-redux_2.12.jar (450ms) downloading https://repo1.maven.org/maven2/org/scala-sbt/zinc-lm-integration_2.12/1.3.4/zinc-lm-integration_2.12-1.3.4.jar ... [SUCCESSFUL ] org.scala-sbt#collections_2.12;1.3.4!collections_2.12.jar (569ms) downloading https://repo1.maven.org/maven2/org/scala-lang/modules/scala-xml_2.12/1.2.0/scala-xml_2.12-1.2.0.jar ... [SUCCESSFUL ] org.scala-sbt#scripted-plugin_2.12;1.3.4!scripted-plugin_2.12.jar (441ms) downloading https://repo1.maven.org/maven2/org/scala-sbt/launcher-interface/1.1.3/launcher-interface-1.1.3.jar ... [SUCCESSFUL ] org.scala-sbt#zinc-lm-integration_2.12;1.3.4!zinc-lm-integration_2.12.jar (450ms) downloading https://repo1.maven.org/maven2/org/apache/logging/log4j/log4j-api/2.11.2/log4j-api-2.11.2.jar ... [SUCCESSFUL ] org.scala-sbt#launcher-interface;1.1.3!launcher-interface.jar (454ms) downloading https://repo1.maven.org/maven2/org/apache/logging/log4j/log4j-core/2.11.2/log4j-core-2.11.2.jar ... [SUCCESSFUL ] org.scala-lang.modules#scala-xml_2.12;1.2.0!scala-xml_2.12.jar(bundle) (685ms) downloading https://repo1.maven.org/maven2/org/apache/logging/log4j/log4j-slf4j-impl/2.11.2/log4j-slf4j-impl-2.11.2.jar ... [SUCCESSFUL ] org.apache.logging.log4j#log4j-api;2.11.2!log4j-api.jar (465ms) downloading https://repo1.maven.org/maven2/com/github/cb372/scalacache-caffeine_2.12/0.20.0/scalacache-caffeine_2.12-0.20.0.jar ... [SUCCESSFUL ] org.apache.logging.log4j#log4j-slf4j-impl;2.11.2!log4j-slf4j-impl.jar (469ms) downloading https://repo1.maven.org/maven2/io/get-coursier/lm-coursier-shaded_2.12/2.0.0-RC5-2/lm-coursier-shaded_2.12-2.0.0-RC5-2.jar ... [SUCCESSFUL ] com.github.cb372#scalacache-caffeine_2.12;0.20.0!scalacache-caffeine_2.12.jar (449ms) downloading https://repo1.maven.org/maven2/org/scala-sbt/util-logging_2.12/1.3.2/util-logging_2.12-1.3.2.jar ... [SUCCESSFUL ] org.apache.logging.log4j#log4j-core;2.11.2!log4j-core.jar (811ms) downloading https://repo1.maven.org/maven2/org/scala-sbt/librarymanagement-core_2.12/1.3.0/librarymanagement-core_2.12-1.3.0.jar ... [SUCCESSFUL ] org.scala-sbt#util-logging_2.12;1.3.2!util-logging_2.12.jar (476ms) downloading https://repo1.maven.org/maven2/org/scala-sbt/librarymanagement-ivy_2.12/1.3.0/librarymanagement-ivy_2.12-1.3.0.jar ... [SUCCESSFUL ] org.scala-sbt#librarymanagement-core_2.12;1.3.0!librarymanagement-core_2.12.jar (601ms) downloading https://repo1.maven.org/maven2/org/scala-sbt/compiler-interface/1.3.1/compiler-interface-1.3.1.jar ... [SUCCESSFUL ] org.scala-sbt#compiler-interface;1.3.1!compiler-interface.jar (456ms) downloading https://repo1.maven.org/maven2/org/scala-sbt/zinc-compile_2.12/1.3.1/zinc-compile_2.12-1.3.1.jar ... [SUCCESSFUL ] org.scala-sbt#librarymanagement-ivy_2.12;1.3.0!librarymanagement-ivy_2.12.jar (687ms) downloading https://repo1.maven.org/maven2/org/scala-sbt/util-relation_2.12/1.3.2/util-relation_2.12-1.3.2.jar ... [SUCCESSFUL ] org.scala-sbt#util-relation_2.12;1.3.2!util-relation_2.12.jar (437ms) downloading https://repo1.maven.org/maven2/com/eed3si9n/sjson-new-scalajson_2.12/0.8.2/sjson-new-scalajson_2.12-0.8.2.jar ... [SUCCESSFUL ] org.scala-sbt#zinc-compile_2.12;1.3.1!zinc-compile_2.12.jar (445ms) downloading https://repo1.maven.org/maven2/org/scala-sbt/util-position_2.12/1.3.2/util-position_2.12-1.3.2.jar ... [SUCCESSFUL ] com.eed3si9n#sjson-new-scalajson_2.12;0.8.2!sjson-new-scalajson_2.12.jar (448ms) downloading https://repo1.maven.org/maven2/com/eed3si9n/shaded-scalajson_2.12/1.0.0-M4/shaded-scalajson_2.12-1.0.0-M4.jar ... [SUCCESSFUL ] org.scala-sbt#util-position_2.12;1.3.2!util-position_2.12.jar (456ms) downloading https://repo1.maven.org/maven2/org/spire-math/jawn-parser_2.12/0.10.4/jawn-parser_2.12-0.10.4.jar ... [SUCCESSFUL ] com.eed3si9n#shaded-scalajson_2.12;1.0.0-M4!shaded-scalajson_2.12.jar (463ms) downloading https://repo1.maven.org/maven2/org/scala-sbt/completion_2.12/1.3.4/completion_2.12-1.3.4.jar ... [SUCCESSFUL ] org.spire-math#jawn-parser_2.12;0.10.4!jawn-parser_2.12.jar (468ms) downloading https://repo1.maven.org/maven2/org/scala-sbt/task-system_2.12/1.3.4/task-system_2.12-1.3.4.jar ... [SUCCESSFUL ] org.scala-sbt#completion_2.12;1.3.4!completion_2.12.jar (448ms) downloading https://repo1.maven.org/maven2/org/scala-sbt/tasks_2.12/1.3.4/tasks_2.12-1.3.4.jar ... [SUCCESSFUL ] org.scala-sbt#task-system_2.12;1.3.4!task-system_2.12.jar (524ms) downloading https://repo1.maven.org/maven2/org/scala-sbt/testing_2.12/1.3.4/testing_2.12-1.3.4.jar ... [SUCCESSFUL ] org.scala-sbt#tasks_2.12;1.3.4!tasks_2.12.jar (455ms) downloading https://repo1.maven.org/maven2/org/scala-sbt/util-tracking_2.12/1.3.2/util-tracking_2.12-1.3.2.jar ... [SUCCESSFUL ] org.scala-sbt#testing_2.12;1.3.4!testing_2.12.jar (465ms) downloading https://repo1.maven.org/maven2/org/scala-sbt/zinc-classpath_2.12/1.3.1/zinc-classpath_2.12-1.3.1.jar ... [SUCCESSFUL ] org.scala-sbt#util-tracking_2.12;1.3.2!util-tracking_2.12.jar (443ms) downloading https://repo1.maven.org/maven2/org/scala-sbt/zinc-apiinfo_2.12/1.3.1/zinc-apiinfo_2.12-1.3.1.jar ... [SUCCESSFUL ] org.scala-sbt#zinc-classpath_2.12;1.3.1!zinc-classpath_2.12.jar (459ms) downloading https://repo1.maven.org/maven2/org/scala-sbt/zinc_2.12/1.3.1/zinc_2.12-1.3.1.jar ... [SUCCESSFUL ] org.scala-sbt#zinc-apiinfo_2.12;1.3.1!zinc-apiinfo_2.12.jar (453ms) downloading https://repo1.maven.org/maven2/jline/jline/2.14.6/jline-2.14.6.jar ... [SUCCESSFUL ] org.scala-sbt#zinc_2.12;1.3.1!zinc_2.12.jar (448ms) downloading https://repo1.maven.org/maven2/org/scala-sbt/util-control_2.12/1.3.2/util-control_2.12-1.3.2.jar ... [SUCCESSFUL ] org.scala-sbt#main_2.12;1.3.4!main_2.12.jar (9125ms) downloading https://repo1.maven.org/maven2/com/swoval/file-tree-views/2.1.3/file-tree-views-2.1.3.jar ... [SUCCESSFUL ] jline#jline;2.14.6!jline.jar (447ms) downloading https://repo1.maven.org/maven2/net/java/dev/jna/jna/4.5.0/jna-4.5.0.jar ... [SUCCESSFUL ] org.scala-sbt#util-control_2.12;1.3.2!util-control_2.12.jar (451ms) downloading https://repo1.maven.org/maven2/net/java/dev/jna/jna-platform/4.5.0/jna-platform-4.5.0.jar ... [SUCCESSFUL ] net.java.dev.jna#jna;4.5.0!jna.jar (904ms) downloading https://repo1.maven.org/maven2/org/scala-sbt/util-interface/1.3.2/util-interface-1.3.2.jar ... [SUCCESSFUL ] com.swoval#file-tree-views;2.1.3!file-tree-views.jar (1016ms) downloading https://repo1.maven.org/maven2/com/eed3si9n/sjson-new-core_2.12/0.8.3/sjson-new-core_2.12-0.8.3.jar ... [SUCCESSFUL ] net.java.dev.jna#jna-platform;4.5.0!jna-platform.jar (839ms) downloading https://repo1.maven.org/maven2/com/lmax/disruptor/3.4.2/disruptor-3.4.2.jar ... [SUCCESSFUL ] org.scala-sbt#util-interface;1.3.2!util-interface.jar (434ms) downloading https://repo1.maven.org/maven2/com/google/protobuf/protobuf-java/3.7.0/protobuf-java-3.7.0.jar ... [SUCCESSFUL ] com.eed3si9n#sjson-new-core_2.12;0.8.3!sjson-new-core_2.12.jar (577ms) downloading https://repo1.maven.org/maven2/org/scala-sbt/util-cache_2.12/1.3.2/util-cache_2.12-1.3.2.jar ... [SUCCESSFUL ] com.lmax#disruptor;3.4.2!disruptor.jar (676ms) downloading https://repo1.maven.org/maven2/com/eed3si9n/sjson-new-murmurhash_2.12/0.8.3/sjson-new-murmurhash_2.12-0.8.3.jar ... [SUCCESSFUL ] com.eed3si9n#sjson-new-murmurhash_2.12;0.8.3!sjson-new-murmurhash_2.12.jar (444ms) downloading https://repo1.maven.org/maven2/org/scala-sbt/test-agent/1.3.4/test-agent-1.3.4.jar ... [SUCCESSFUL ] io.get-coursier#lm-coursier-shaded_2.12;2.0.0-RC5-2!lm-coursier-shaded_2.12.jar (7176ms) downloading https://repo1.maven.org/maven2/org/scala-sbt/test-interface/1.0/test-interface-1.0.jar ... [SUCCESSFUL ] com.google.protobuf#protobuf-java;3.7.0!protobuf-java.jar(bundle) (1011ms) downloading https://repo1.maven.org/maven2/org/scala-sbt/compiler-bridge_2.12/1.3.1/compiler-bridge_2.12-1.3.1.jar ... [SUCCESSFUL ] org.scala-sbt#util-cache_2.12;1.3.2!util-cache_2.12.jar (987ms) downloading https://repo1.maven.org/maven2/org/scala-sbt/zinc-classfile_2.12/1.3.1/zinc-classfile_2.12-1.3.1.jar ... [SUCCESSFUL ] org.scala-sbt#test-agent;1.3.4!test-agent.jar (449ms) downloading https://repo1.maven.org/maven2/com/jcraft/jsch/0.1.54/jsch-0.1.54.jar ... [SUCCESSFUL ] org.scala-sbt#test-interface;1.0!test-interface.jar (443ms) downloading https://repo1.maven.org/maven2/com/eed3si9n/gigahorse-okhttp_2.12/0.5.0/gigahorse-okhttp_2.12-0.5.0.jar ... [SUCCESSFUL ] org.scala-sbt#compiler-bridge_2.12;1.3.1!compiler-bridge_2.12.jar (446ms) downloading https://repo1.maven.org/maven2/com/squareup/okhttp3/okhttp-urlconnection/3.7.0/okhttp-urlconnection-3.7.0.jar ... [SUCCESSFUL ] com.jcraft#jsch;0.1.54!jsch.jar (459ms) downloading https://repo1.maven.org/maven2/com/eed3si9n/gigahorse-core_2.12/0.5.0/gigahorse-core_2.12-0.5.0.jar ... [SUCCESSFUL ] org.scala-sbt#zinc-classfile_2.12;1.3.1!zinc-classfile_2.12.jar (670ms) downloading https://repo1.maven.org/maven2/com/squareup/okhttp3/okhttp/3.14.2/okhttp-3.14.2.jar ... [SUCCESSFUL ] com.eed3si9n#gigahorse-okhttp_2.12;0.5.0!gigahorse-okhttp_2.12.jar (452ms) downloading https://repo1.maven.org/maven2/com/typesafe/ssl-config-core_2.12/0.4.0/ssl-config-core_2.12-0.4.0.jar ... [SUCCESSFUL ] com.squareup.okhttp3#okhttp-urlconnection;3.7.0!okhttp-urlconnection.jar (447ms) downloading https://repo1.maven.org/maven2/org/reactivestreams/reactive-streams/1.0.2/reactive-streams-1.0.2.jar ... [SUCCESSFUL ] com.eed3si9n#gigahorse-core_2.12;0.5.0!gigahorse-core_2.12.jar (475ms) downloading https://repo1.maven.org/maven2/org/slf4j/slf4j-api/1.7.26/slf4j-api-1.7.26.jar ... [SUCCESSFUL ] org.reactivestreams#reactive-streams;1.0.2!reactive-streams.jar (454ms) downloading https://repo1.maven.org/maven2/org/scala-lang/modules/scala-parser-combinators_2.12/1.1.2/scala-parser-combinators_2.12-1.1.2.jar ... [SUCCESSFUL ] com.typesafe#ssl-config-core_2.12;0.4.0!ssl-config-core_2.12.jar(bundle) (1013ms) downloading https://repo1.maven.org/maven2/com/typesafe/config/1.3.3/config-1.3.3.jar ... [SUCCESSFUL ] org.slf4j#slf4j-api;1.7.26!slf4j-api.jar (783ms) downloading https://repo1.maven.org/maven2/com/squareup/okio/okio/1.17.2/okio-1.17.2.jar ... [SUCCESSFUL ] org.scala-lang.modules#scala-parser-combinators_2.12;1.1.2!scala-parser-combinators_2.12.jar(bundle) (690ms) downloading https://repo1.maven.org/maven2/org/scala-sbt/zinc-core_2.12/1.3.1/zinc-core_2.12-1.3.1.jar ... [SUCCESSFUL ] com.squareup.okhttp3#okhttp;3.14.2!okhttp.jar (1709ms) [SUCCESSFUL ] com.typesafe#config;1.3.3!config.jar(bundle) (693ms) downloading https://repo1.maven.org/maven2/org/scala-sbt/zinc-persist_2.12/1.3.1/zinc-persist_2.12-1.3.1.jar ... downloading https://repo1.maven.org/maven2/org/scala-sbt/zinc-compile-core_2.12/1.3.1/zinc-compile-core_2.12-1.3.1.jar ... [SUCCESSFUL ] org.scala-sbt#zinc-core_2.12;1.3.1!zinc-core_2.12.jar (788ms) downloading https://repo1.maven.org/maven2/com/trueaccord/scalapb/scalapb-runtime_2.12/0.6.0/scalapb-runtime_2.12-0.6.0.jar ... [SUCCESSFUL ] org.scala-sbt#zinc-compile-core_2.12;1.3.1!zinc-compile-core_2.12.jar (672ms) downloading https://repo1.maven.org/maven2/com/trueaccord/lenses/lenses_2.12/0.4.12/lenses_2.12-0.4.12.jar ... [SUCCESSFUL ] com.squareup.okio#okio;1.17.2!okio.jar (1405ms) downloading https://repo1.maven.org/maven2/com/lihaoyi/fastparse_2.12/0.4.2/fastparse_2.12-0.4.2.jar ... [SUCCESSFUL ] com.trueaccord.lenses#lenses_2.12;0.4.12!lenses_2.12.jar (481ms) downloading https://repo1.maven.org/maven2/com/lihaoyi/fastparse-utils_2.12/0.4.2/fastparse-utils_2.12-0.4.2.jar ... [SUCCESSFUL ] com.lihaoyi#fastparse_2.12;0.4.2!fastparse_2.12.jar (635ms) downloading https://repo1.maven.org/maven2/com/lihaoyi/sourcecode_2.12/0.1.3/sourcecode_2.12-0.1.3.jar ... [SUCCESSFUL ] com.lihaoyi#fastparse-utils_2.12;0.4.2!fastparse-utils_2.12.jar (478ms) downloading https://repo1.maven.org/maven2/org/scala-sbt/sbinary_2.12/0.5.0/sbinary_2.12-0.5.0.jar ... [SUCCESSFUL ] com.trueaccord.scalapb#scalapb-runtime_2.12;0.6.0!scalapb-runtime_2.12.jar (1505ms) downloading https://repo1.maven.org/maven2/org/scala-sbt/core-macros_2.12/1.3.4/core-macros_2.12-1.3.4.jar ... [SUCCESSFUL ] com.lihaoyi#sourcecode_2.12;0.1.3!sourcecode_2.12.jar (482ms) downloading https://repo1.maven.org/maven2/org/scala-sbt/protocol_2.12/1.3.4/protocol_2.12-1.3.4.jar ... [SUCCESSFUL ] org.scala-sbt#core-macros_2.12;1.3.4!core-macros_2.12.jar (518ms) downloading https://repo1.maven.org/maven2/org/scala-sbt/template-resolver/0.1/template-resolver-0.1.jar ... [SUCCESSFUL ] org.scala-sbt#sbinary_2.12;0.5.0!sbinary_2.12.jar (743ms) downloading https://repo1.maven.org/maven2/org/scala-sbt/ipcsocket/ipcsocket/1.0.0/ipcsocket-1.0.0.jar ... [SUCCESSFUL ] org.scala-sbt#template-resolver;0.1!template-resolver.jar (441ms) downloading https://repo1.maven.org/maven2/org/scala-lang/scala-compiler/2.12.10/scala-compiler-2.12.10.jar ... [SUCCESSFUL ] org.scala-sbt.ipcsocket#ipcsocket;1.0.0!ipcsocket.jar (455ms) downloading https://repo1.maven.org/maven2/org/scala-lang/scala-reflect/2.12.10/scala-reflect-2.12.10.jar ... [SUCCESSFUL ] org.scala-sbt#protocol_2.12;1.3.4!protocol_2.12.jar (1202ms) downloading https://repo1.maven.org/maven2/org/scala-sbt/util-scripted_2.12/1.3.2/util-scripted_2.12-1.3.2.jar ... [SUCCESSFUL ] org.scala-sbt#util-scripted_2.12;1.3.2!util-scripted_2.12.jar (450ms) downloading https://repo1.maven.org/maven2/com/github/cb372/scalacache-core_2.12/0.20.0/scalacache-core_2.12-0.20.0.jar ... [SUCCESSFUL ] com.github.cb372#scalacache-core_2.12;0.20.0!scalacache-core_2.12.jar (457ms) downloading https://repo1.maven.org/maven2/com/github/ben-manes/caffeine/caffeine/2.5.6/caffeine-2.5.6.jar ... [SUCCESSFUL ] com.github.ben-manes.caffeine#caffeine;2.5.6!caffeine.jar (1017ms) downloading https://repo1.maven.org/maven2/org/scala-sbt/ivy/ivy/2.3.0-sbt-cb9cc189e9f3af519f9f102e6c5d446488ff6832/ivy-2.3.0-sbt-cb9cc189e9f3af519f9f102e6c5d446488ff6832.jar ... [SUCCESSFUL ] org.scala-sbt#zinc-persist_2.12;1.3.1!zinc-persist_2.12.jar (5683ms) [SUCCESSFUL ] org.scala-sbt.ivy#ivy;2.3.0-sbt-cb9cc189e9f3af519f9f102e6c5d446488ff6832!ivy.jar (1037ms) [SUCCESSFUL ] org.scala-lang#scala-reflect;2.12.10!scala-reflect.jar (6224ms) [SUCCESSFUL ] org.scala-lang#scala-compiler;2.12.10!scala-compiler.jar (8766ms) :: retrieving :: org.scala-sbt#boot-app confs: [default] 81 artifacts copied, 0 already retrieved [info] [launcher] getting Scala 2.12.10 (for sbt)... downloading https://repo1.maven.org/maven2/org/scala-lang/modules/scala-xml_2.12/1.0.6/scala-xml_2.12-1.0.6.jar ... downloading https://repo1.maven.org/maven2/org/fusesource/jansi/jansi/1.12/jansi-1.12.jar ... [SUCCESSFUL ] org.fusesource.jansi#jansi;1.12!jansi.jar (1318ms) [SUCCESSFUL ] org.scala-lang.modules#scala-xml_2.12;1.0.6!scala-xml_2.12.jar(bundle) (2602ms) :: retrieving :: org.scala-sbt#boot-scala confs: [default] 6 artifacts copied, 0 already retrieved [info] Loading project definition from /home/zsh/cdk/project [info] Loading settings for project cdk from build.sbt ... [info] Set current project to hello-world (in build file:/home/zsh/cdk/) [warn] There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings. [info] Compiling 2 Scala sources to /home/zsh/cdk/target/scala-2.13/classes ... [info] Non-compiled module 'compiler-bridge_2.13' for Scala 2.13.1. Compiling... 8 warnings found [info] Compilation completed in 7.349s. [info] Done compiling. [info] running com.myorg.CdkApp [success] Total time: 27 s, completed Dec 10, 2019 2:32:33 PM CdkStack [zsh@bd8ee7c9cbb6 cdk (master *+%)]$
cdk.json の記述を変えれば Gradle などでも動きそうですね。
cdk deploy
[zsh@bd8ee7c9cbb6 cdk (master *+%)]$cdk deploy [info] Loading project definition from /home/zsh/cdk/project [info] Loading settings for project cdk from build.sbt ... [info] Set current project to hello-world (in build file:/home/zsh/cdk/) [info] running com.myorg.CdkApp [success] Total time: 2 s, completed Dec 10, 2019 2:33:53 PM CdkStack: deploying... CdkStack: creating CloudFormation changeset... 0/2 | 2:34:07 PM | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata 0/2 | 2:34:09 PM | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata Resource creation Initiated 1/2 | 2:34:09 PM | CREATE_COMPLETE | AWS::CDK::Metadata | CDKMetadata 2/2 | 2:34:11 PM | CREATE_COMPLETE | AWS::CloudFormation::Stack | CdkStack ✅ CdkStack Stack ARN: arn:aws:cloudformation:us-west-2:XXXXXXXXXXXX:stack/CdkStack/xxxxxxxx-xxxx-xxxx-xxxx-067aa3cae1e0 [zsh@bd8ee7c9cbb6 cdk (master *+%)]$
これで CloudFormation Stack が出来ました。
当然ながら、それで作られるリソースも居ます。
cdk destroy
cdkで作ったStackやリソースを削除するには、 cdk destroy
を使います。
[zsh@bd8ee7c9cbb6 cdk (master *+%)]$ cdk destroy [info] Loading project definition from /home/zsh/cdk/project [info] Loading settings for project cdk from build.sbt ... [info] Set current project to hello-world (in build file:/home/zsh/cdk/) [info] running com.myorg.CdkApp [success] Total time: 2 s, completed Dec 10, 2019 2:38:36 PM Are you sure you want to delete: CdkStack (y/n)? y CdkStack: destroying... ✅ CdkStack: destroyed [zsh@bd8ee7c9cbb6 cdk (master *+%)]$
これで CloudFormation Stack が削除されました。
流石に CloudFormation や CDK の API は調べていただくということで、説明はここまでとなります。
まとめ
以下の設定を行うだけで、とても簡単にAWS CDK を Scala で使うことが出来ました。
- cdk init で生成される pom.xml を参考に build.sbt に CDK の Maven アーティファクトを記述する。
- cdk.json の mvn 〜 をsbt run に書き換える
ただし、CDKのAPIが良くできていて、Scalaでやるメリットは大きくはなさそうです。(メリットがあるケースはアプリもScalaだから、CDKもScalaで使いたいといった言った程度でしょうか?)
検証コード
今回作った検証コードは こちら