0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

「AWS Hands-on for Beginners AWS Amplify を用いた Web サイトの構築方法を学ぼう」をAWS CLIでやってみる

Last updated at Posted at 2024-10-13

上記、「AWS Hands-on for Beginners AWS Amplify を用いた Web サイトの構築方法を学ぼう」 をAWS CLIでやってみる
image.png
ハンズオンから引用

Cloud9は新規利用できなくなりました。
今まで利用したことがあるアカウントはまだ利用できるようです。

02 AWS Amplify のハンズオン(環境構築、Cloud9 編)

Cloud9環境構築

Cloud9環境構築 (CloudShellで実施)

コマンド
# Cloud9環境名
CLOUD9_ENVIRONMENT_NAME="handson" \
&& echo ${CLOUD9_ENVIRONMENT_NAME}

# インスタンスタイプ
CLOUD9_INSTANCE_TYPE="t3.small" \
&& echo ${CLOUD9_INSTANCE_TYPE}

# プラットフォーム
CLOUD9_IMAGE_ID="resolve:ssm:/aws/service/cloud9/amis/amazonlinux-2-x86_64" \
&& echo ${CLOUD9_IMAGE_ID}

# Cloud9環境作成
CLOUD9_ENVIRONMENT_ID=$(
    aws cloud9 create-environment-ec2 \
        --name ${CLOUD9_ENVIRONMENT_NAME} \
        --instance-type ${CLOUD9_INSTANCE_TYPE} \
        --image-id ${CLOUD9_IMAGE_ID} \
        --connection-type CONNECT_SSM \
        --automatic-stop-time-minutes 30 \
        --query environmentId \
        --output text
) \
&& echo ${CLOUD9_ENVIRONMENT_ID}

出力
[cloudshell-user@ip-10-132-68-36 ~]$ # Cloud9環境名
[cloudshell-user@ip-10-132-68-36 ~]$ CLOUD9_ENVIRONMENT_NAME="handson" \
> && echo ${CLOUD9_ENVIRONMENT_NAME}
handson
[cloudshell-user@ip-10-132-68-36 ~]$ 
[cloudshell-user@ip-10-132-68-36 ~]$ # インスタンスタイプ
[cloudshell-user@ip-10-132-68-36 ~]$ CLOUD9_INSTANCE_TYPE="t3.small" \
> && echo ${CLOUD9_INSTANCE_TYPE}
t3.small
[cloudshell-user@ip-10-132-68-36 ~]$ 
[cloudshell-user@ip-10-132-68-36 ~]$ # プラットフォーム
[cloudshell-user@ip-10-132-68-36 ~]$ CLOUD9_IMAGE_ID="resolve:ssm:/aws/service/cloud9/amis/amazonlinux-2-x86_64" \
> && echo ${CLOUD9_IMAGE_ID}
resolve:ssm:/aws/service/cloud9/amis/amazonlinux-2-x86_64
[cloudshell-user@ip-10-132-68-36 ~]$ 
[cloudshell-user@ip-10-132-68-36 ~]$ # Cloud9環境作成
[cloudshell-user@ip-10-132-68-36 ~]$ CLOUD9_ENVIRONMENT_ID=$(
>     aws cloud9 create-environment-ec2 \
>         --name ${CLOUD9_ENVIRONMENT_NAME} \
>         --instance-type ${CLOUD9_INSTANCE_TYPE} \
>         --image-id ${CLOUD9_IMAGE_ID} \
>         --connection-type CONNECT_SSM \
>         --automatic-stop-time-minutes 30 \
>         --query environmentId \
>         --output text
> ) \
> && echo ${CLOUD9_ENVIRONMENT_ID}
04fe8f6beae044f088baf19dfc89bef8

クレデンシャル無効化 (CloudShellで実施)

コマンド
aws cloud9 update-environment \
    --environment-id ${CLOUD9_ENVIRONMENT_ID} \
    --managed-credentials-action DISABLE

出力
[cloudshell-user@ip-10-132-68-36 ~]$ aws cloud9 update-environment \
>     --environment-id ${CLOUD9_ENVIRONMENT_ID} \
>     --managed-credentials-action DISABLE

EC2ストレージ容量拡張

ファイルシステムの確認 (Cloud9で実施)

コマンド
# 容量の確認
df -h

# ファイルシステムの確認
df -Th /

# パーティション確認
lsblk

出力
admin:~/environment $ # 容量の確認
admin:~/environment $ df -h
Filesystem      Size  Used Avail Use% Mounted on
devtmpfs        953M     0  953M   0% /dev
tmpfs           963M     0  963M   0% /dev/shm
tmpfs           963M  468K  962M   1% /run
tmpfs           963M     0  963M   0% /sys/fs/cgroup
/dev/nvme0n1p1   10G  5.8G  4.3G  58% /
tmpfs           193M     0  193M   0% /run/user/1000
admin:~/environment $ 
admin:~/environment $ # ファイルシステムの確認
admin:~/environment $ df -Th /
Filesystem     Type  Size  Used Avail Use% Mounted on
/dev/nvme0n1p1 xfs    10G  5.8G  4.3G  58% /
admin:~/environment $ 
admin:~/environment $ # パーティション確認
admin:~/environment $ lsblk
NAME          MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
nvme0n1       259:0    0  10G  0 disk 
├─nvme0n1p1   259:1    0  10G  0 part /
└─nvme0n1p128 259:2    0   1M  0 part 

EC2ストレージ容量拡張 (CloudShellで実施)

コマンド
# インスタンスのボリュームID確認
EC2_VOLUME_ID=$(
    aws ec2 describe-instances \
        --filters "Name=tag:Name,Values=aws-cloud9-${CLOUD9_ENVIRONMENT_NAME}-${CLOUD9_ENVIRONMENT_ID}" \
        --query 'Reservations[*].Instances[*].[BlockDeviceMappings[*].Ebs.VolumeId]' \
        --output text
) \
&& echo ${EC2_VOLUME_ID}

# EBSボリュームのサイズを変更
aws ec2 modify-volume \
    --volume-id ${EC2_VOLUME_ID} \
    --size 32

出力
[cloudshell-user@ip-10-132-68-36 ~]$ # インスタンスのボリュームID確認
[cloudshell-user@ip-10-132-68-36 ~]$ EC2_VOLUME_ID=$(
>     aws ec2 describe-instances \
>         --filters "Name=tag:Name,Values=aws-cloud9-${CLOUD9_ENVIRONMENT_NAME}-${CLOUD9_ENVIRONMENT_ID}" \
>         --query 'Reservations[*].Instances[*].[BlockDeviceMappings[*].Ebs.VolumeId]' \
>         --output text
> ) \
> && echo ${EC2_VOLUME_ID}
vol-0e9aec950c9647239
[cloudshell-user@ip-10-132-68-36 ~]$ 
[cloudshell-user@ip-10-132-68-36 ~]$ # EBSボリュームのサイズを変更
[cloudshell-user@ip-10-132-68-36 ~]$ aws ec2 modify-volume \
>     --volume-id ${EC2_VOLUME_ID} \
>     --size 32
{
    "VolumeModification": {
        "VolumeId": "vol-0e9aec950c9647239",
        "ModificationState": "modifying",
        "TargetSize": 32,
        "TargetIops": 3000,
        "TargetVolumeType": "gp3",
        "TargetThroughput": 125,
        "TargetMultiAttachEnabled": false,
        "OriginalSize": 10,
        "OriginalIops": 3000,
        "OriginalVolumeType": "gp3",
        "OriginalThroughput": 125,
        "OriginalMultiAttachEnabled": false,
        "Progress": 0,
        "StartTime": "2024-10-12T11:57:17+00:00"
    }
}

ファイルシステム拡張 (Cloud9で実施)

コマンド
# パーティションを拡張
sudo growpart /dev/nvme0n1 1

# ファイルシステムを拡張 (XFSの場合)
sudo xfs_growfs -d /

# 容量の確認
df -h

出力
admin:~/environment $ # パーティションを拡張
admin:~/environment $ sudo growpart /dev/nvme0n1 1
CHANGED: partition=1 start=4096 old: size=20967391 end=20971487 new: size=67104735 end=67108831
admin:~/environment $ 
admin:~/environment $ # ファイルシステムを拡張 (XFSの場合)
admin:~/environment $ sudo xfs_growfs -d /
meta-data=/dev/nvme0n1p1         isize=512    agcount=6, agsize=524159 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=1, sparse=0, rmapbt=0
         =                       reflink=0    bigtime=0 inobtcount=0
data     =                       bsize=4096   blocks=2620923, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0, ftype=1
log      =internal log           bsize=4096   blocks=2560, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
data blocks changed from 2620923 to 8388091
admin:~/environment $ 
admin:~/environment $ # 容量の確認
admin:~/environment $ df -h
Filesystem      Size  Used Avail Use% Mounted on
devtmpfs        953M     0  953M   0% /dev
tmpfs           963M     0  963M   0% /dev/shm
tmpfs           963M  456K  962M   1% /run
tmpfs           963M     0  963M   0% /sys/fs/cgroup
/dev/nvme0n1p1   32G  5.8G   27G  19% /
tmpfs           193M     0  193M   0% /run/user/1000

03 AWS Amplify のハンズオン(環境構築、CLI 編)

Amplify用ユーザーの作成 (CloudShellで実施)

コマンド
# ユーザー名
USER_NAME="amplify-dev " \
&& echo ${USER_NAME}

# ポリシー名
POLICY_NAME="AdministratorAccess-Amplify" \
&& echo ${POLICY_NAME}

# ユーザー作成
aws iam create-user --user-name ${USER_NAME}

# ポリシーのアタッチ
aws iam attach-user-policy \
    --user-name ${USER_NAME} \
    --policy-arn arn:aws:iam::aws:policy/${POLICY_NAME}

# アクセスキーの作成
aws iam create-access-key --user-name ${USER_NAME}

出力
[cloudshell-user@ip-10-132-68-36 ~]$ # ユーザー名
[cloudshell-user@ip-10-132-68-36 ~]$ USER_NAME="amplify-dev " \
> && echo ${USER_NAME}
amplify-dev
[cloudshell-user@ip-10-132-68-36 ~]$ 
[cloudshell-user@ip-10-132-68-36 ~]$ # ポリシー名
[cloudshell-user@ip-10-132-68-36 ~]$ POLICY_NAME="AdministratorAccess-Amplify" \
> && echo ${POLICY_NAME}
AdministratorAccess-Amplify
[cloudshell-user@ip-10-132-68-36 ~]$ 
[cloudshell-user@ip-10-132-68-36 ~]$ # ユーザー作成
[cloudshell-user@ip-10-132-68-36 ~]$ aws iam create-user --user-name ${USER_NAME}
{
    "User": {
        "Path": "/",
        "UserName": "amplify-dev",
        "UserId": "AIDAWFKRCMKO6LDGRI7LL",
        "Arn": "arn:aws:iam::999999999999:user/amplify-dev",
        "CreateDate": "2024-10-12T11:58:02+00:00"
    }
}
[cloudshell-user@ip-10-132-68-36 ~]$ 
[cloudshell-user@ip-10-132-68-36 ~]$ # ポリシーのアタッチ
[cloudshell-user@ip-10-132-68-36 ~]$ aws iam attach-user-policy \
>     --user-name ${USER_NAME} \
>     --policy-arn arn:aws:iam::aws:policy/${POLICY_NAME}
[cloudshell-user@ip-10-132-68-36 ~]$ 
[cloudshell-user@ip-10-132-68-36 ~]$ # アクセスキーの作成
[cloudshell-user@ip-10-132-68-36 ~]$ aws iam create-access-key --user-name ${USER_NAME}
{
    "AccessKey": {
        "UserName": "amplify-dev",
        "AccessKeyId": "********************",
        "Status": "Active",
        "SecretAccessKey": "****************************************",
        "CreateDate": "2024-10-12T11:58:07+00:00"
    }
}

以降、Cloud9で実施

Node.js 環境のセットアップ(インスタンスにインストール済み)

コマンド
node -v

出力
admin:~/environment $ node -v
v18.20.2

Amplify CLI のインストールとセットアップ

Amplify CLI のインストール

コマンド
npm install -g @aws-amplify/cli

出力
admin:~/environment $ npm install -g @aws-amplify/cli
npm error code EACCES
npm error syscall mkdir
npm error path /usr/local/nodejs/v18.20.2/lib/node_modules/@aws-amplify
npm error errno -13
npm error [Error: EACCES: permission denied, mkdir '/usr/local/nodejs/v18.20.2/lib/node_modules/@aws-amplify'] {
npm error   errno: -13,
npm error   code: 'EACCES',
npm error   syscall: 'mkdir',
npm error   path: '/usr/local/nodejs/v18.20.2/lib/node_modules/@aws-amplify'
npm error }
npm error
npm error The operation was rejected by your operating system.
npm error It is likely you do not have the permissions to access this file as the current user
npm error
npm error If you believe this might be a permissions issue, please double-check the
npm error permissions of the file and its containing directories, or try running
npm error the command again as root/Administrator.
npm error A complete log of this run can be found in: /home/ec2-user/.npm/_logs/2024-10-12T11_58_35_584Z-debug-0.log

npmのデフォルトディレクトリを手動で変更する

インストール用のディレクトリを作成

コマンド
mkdir -p ~/.npm-global/lib

出力
admin:~/environment $ mkdir -p ~/.npm-global/lib

インストール用のディレクトリを作成

コマンド
mkdir -p ~/.npm-global/lib

出力
admin:~/environment $ mkdir -p ~/.npm-global/lib

新しいディレクトリ パスを使用するように npm を構成

コマンド
npm config set prefix '~/.npm-global'

出力
admin:~/environment $ npm config set prefix '~/.npm-global'

~/.profileを更新

コマンド
cat << "EOF" >> ~/.profile
export PATH=~/.npm-global/bin:$PATH
EOF

出力
admin:~/environment $ cat << "EOF" >> ~/.profile
> export PATH=~/.npm-global/bin:$PATH
> EOF

システム変数を更新

コマンド
source ~/.profile

出力
admin:~/environment $ source ~/.profile

新しい設定をテスト

コマンド
npm install -g jshint

出力
admin:~/environment $ npm install -g jshint
npm warn deprecated inflight@1.0.6: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
npm warn deprecated glob@7.2.3: Glob versions prior to v9 are no longer supported

added 31 packages in 5s

3 packages are looking for funding
  run `npm fund` for details

Amplify CLI の再インストール

コマンド
npm install -g @aws-amplify/cli

出力
admin:~/environment $ npm install -g @aws-amplify/cli
npm warn deprecated inflight@1.0.6: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
npm warn deprecated glob@7.2.3: Glob versions prior to v9 are no longer supported
npm warn deprecated rimraf@3.0.2: Rimraf versions prior to v4 are no longer supported

added 33 packages in 16s

7 packages are looking for funding
  run `npm fund` for details

Amplify CLIを設定

コマンド
amplify configure

出力
admin:~/environment $ amplify configure
Follow these steps to set up access to your AWS account:

Sign in to your AWS administrator account:
https://console.aws.amazon.com/
Press Enter to continue
Unable to open https://console.aws.amazon.com/: spawn xdg-open ENOENT
Have you installed `xdg-utils` on your machine?
^C
^Aborted!

xdg-utilsがインストールされていないのでエラーになる

xdg-utilsのインストール

コマンド
sudo yum -y install xdg-utils

出力
admin:~/environment $ sudo yum -y install xdg-utils
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
237 packages excluded due to repository priority protections
Resolving Dependencies
--> Running transaction check
---> Package xdg-utils.noarch 0:1.1.0-0.17.20120809git.amzn2.0.1 will be installed
--> Processing Dependency: desktop-file-utils for package: xdg-utils-1.1.0-0.17.20120809git.amzn2.0.1.noarch
--> Running transaction check
---> Package desktop-file-utils.x86_64 0:0.23-2.amzn2 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

====================================================================================================================================================================================================================================================
 Package                                                     Arch                                            Version                                                                      Repository                                           Size
====================================================================================================================================================================================================================================================
Installing:
 xdg-utils                                                   noarch                                          1.1.0-0.17.20120809git.amzn2.0.1                                             amzn2-core                                           70 k
Installing for dependencies:
 desktop-file-utils                                          x86_64                                          0.23-2.amzn2                                                                 amzn2-core                                           68 k

Transaction Summary
====================================================================================================================================================================================================================================================
Install  1 Package (+1 Dependent package)

Total download size: 138 k
Installed size: 474 k
Downloading packages:
(1/2): desktop-file-utils-0.23-2.amzn2.x86_64.rpm                                                                                                                                                                            |  68 kB  00:00:00     
(2/2): xdg-utils-1.1.0-0.17.20120809git.amzn2.0.1.noarch.rpm                                                                                                                                                                 |  70 kB  00:00:00     
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Total                                                                                                                                                                                                               1.0 MB/s | 138 kB  00:00:00     
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : desktop-file-utils-0.23-2.amzn2.x86_64                                                                                                                                                                                           1/2 
  Installing : xdg-utils-1.1.0-0.17.20120809git.amzn2.0.1.noarch                                                                                                                                                                                2/2 
  Verifying  : xdg-utils-1.1.0-0.17.20120809git.amzn2.0.1.noarch                                                                                                                                                                                1/2 
  Verifying  : desktop-file-utils-0.23-2.amzn2.x86_64                                                                                                                                                                                           2/2 

Installed:
  xdg-utils.noarch 0:1.1.0-0.17.20120809git.amzn2.0.1                                                                                                                                                                                               

Dependency Installed:
  desktop-file-utils.x86_64 0:0.23-2.amzn2                                                                                                                                                                                                          

Complete!

Amplify CLIを再設定

コマンド
amplify configure

出力
admin:~/environment $ amplify configure
Follow these steps to set up access to your AWS account:

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

Specify the AWS Region
? region:  ap-northeast-1
Follow the instructions at
https://docs.amplify.aws/cli/start/install/#configure-the-amplify-cli

to complete the user creation in the AWS console
https://console.aws.amazon.com/iamv2/home#/users/create
Press Enter to continue

Enter the access key of the newly created user:
? accessKeyId:  ********************
? secretAccessKey:  ****************************************
This would update/create the AWS Profile in your local machine
? Profile Name:  default

Successfully set up the new user.

Reactアプリの作成

現在の公式手順は上記リンク先になりハンズオンの手順と異なる。しかし、現在の公式手順では動作確認時のローカルサーバの起動ポート番号の変更ができず、Cloud9のPreview機能での動作確認ができなかったのでハンズオンの手順のまま実施

Reactアプリの作成

コマンド
npx create-react-app react-amplified

出力
admin:~/environment $ npx create-react-app react-amplified
Need to install the following packages:
create-react-app@5.0.1
Ok to proceed? (y) y

npm warn deprecated inflight@1.0.6: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
npm warn deprecated glob@7.2.3: Glob versions prior to v9 are no longer supported
npm warn deprecated rimraf@2.7.1: Rimraf versions prior to v4 are no longer supported
npm warn deprecated uid-number@0.0.6: This package is no longer supported.
npm warn deprecated fstream-ignore@1.0.5: This package is no longer supported.
npm warn deprecated fstream@1.0.12: This package is no longer supported.
npm warn deprecated tar@2.2.2: This version of tar is no longer supported, and will not receive security updates. Please upgrade asap.

Creating a new React app in /home/ec2-user/environment/react-amplified.

Installing packages. This might take a couple of minutes.
Installing react, react-dom, and react-scripts with cra-template...


added 1478 packages in 2m

262 packages are looking for funding
  run `npm fund` for details

Initialized a git repository.

Installing template dependencies using npm...

added 63 packages, and changed 1 package in 24s

262 packages are looking for funding
  run `npm fund` for details
Removing template package using npm...


removed 1 package, and audited 1541 packages in 15s

262 packages are looking for funding
  run `npm fund` for details

8 vulnerabilities (2 moderate, 6 high)

To address all issues (including breaking changes), run:
  npm audit fix --force

Run `npm audit` for details.

Created git commit.

Success! Created react-amplified at /home/ec2-user/environment/react-amplified
Inside that directory, you can run several commands:

  npm start
    Starts the development server.

  npm run build
    Bundles the app into static files for production.

  npm test
    Starts the test runner.

  npm run eject
    Removes this tool and copies build dependencies, configuration files
    and scripts into the app directory. If you do this, you can’t go back!

We suggest that you begin by typing:

  cd react-amplified
  npm start

Happy hacking!

ディレクトリ移動

コマンド
cd react-amplified

出力
admin:~/environment $ cd react-amplified
admin:~/environment/react-amplified (master) $ 

動作確認

コマンド
npm start

出力
Compiled successfully!

You can now view react-amplified in the browser.

  Local:            http://localhost:8080
  On Your Network:  http://172.31.6.39:8080

Note that the development build is not optimized.
To create a production build, use npm run build.

webpack compiled successfully

Preview > Preview Running Applicationから表示確認
image.png

Amplify Project の初期化コマンド

コマンド
amplify init

出力
admin:~/environment/react-amplified (master) $ amplify init
⚠️ For new projects, we recommend starting with AWS Amplify Gen 2, our new code-first developer experience. Get started at https://docs.amplify.aws/react/start/quickstart/
✔ Do you want to continue with Amplify Gen 1? (y/N) · yes
✔ Why would you like to use Amplify Gen 1? · Prefer not to answer
Note: It is recommended to run this command from the root of your app directory
? Enter a name for the project reactamplified
The following configuration will be applied:

Project information
| Name: reactamplified
| Environment: dev
| Default editor: Visual Studio Code
| App type: javascript
| Javascript framework: react
| Source Directory Path: src
| Distribution Directory Path: build
| Build Command: npm run-script build
| Start Command: npm run-script start

? Initialize the project with the above configuration? Yes
Using default provider  awscloudformation
? Select the authentication method you want to use: AWS profile

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

? Please choose the profile you want to use default
Adding backend environment dev to AWS Amplify app: d14fd37vg009fk

Deployment completed.
Deploying root stack reactamplified [ ==========------------------------------ ] 1/4
        amplify-reactamplified-dev-54… AWS::CloudFormation::Stack     CREATE_IN_PROGRESS             Sat Oct 12 2024 12:14:41…     
        UnauthRole                     AWS::IAM::Role                 CREATE_IN_PROGRESS             Sat Oct 12 2024 12:14:43…     
        AuthRole                       AWS::IAM::Role                 CREATE_IN_PROGRESS             Sat Oct 12 2024 12:14:43…     
        DeploymentBucket               AWS::S3::Bucket                CREATE_COMPLETE                Sat Oct 12 2024 12:14:59…     

✔ Help improve Amplify CLI by sharing non-sensitive project configurations on failures (y/N) · no

    You can always opt-in by running "amplify configure --share-project-config-on"
Deployment state saved successfully.
✔ Initialized provider successfully.
✅ Initialized your environment successfully.
✅ Your project has been successfully initialized and connected to the cloud!
Some next steps:

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


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

Amplify Framework のインストール

コマンド
npm install aws-amplify @aws-amplify/ui-react

出力
admin:~/environment/react-amplified (master) $ npm install aws-amplify @aws-amplify/ui-react

added 290 packages, and audited 1831 packages in 2m

270 packages are looking for funding
  run `npm fund` for details

8 vulnerabilities (2 moderate, 6 high)

To address all issues (including breaking changes), run:
  npm audit fix --force

Run `npm audit` for details.

フロントエンドの設定

コマンド
cat << EOF > src/index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

import { Amplify } from 'aws-amplify';
import amplifyconfig from './amplifyconfiguration.json';
Amplify.configure(amplifyconfig);

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
EOF

出力
admin:~/environment/react-amplified (master) $ cat << EOF > src/index.js
> import React from 'react';
> import ReactDOM from 'react-dom/client';
> import './index.css';
> import App from './App';
> import reportWebVitals from './reportWebVitals';
> 
> import { Amplify } from 'aws-amplify';
> import amplifyconfig from './amplifyconfiguration.json';
> Amplify.configure(amplifyconfig);
> 
> const root = ReactDOM.createRoot(document.getElementById('root'));
> root.render(
>   <React.StrictMode>
>     <App />
>   </React.StrictMode>
> );
> 
> // If you want to start measuring performance in your app, pass a function
> // to log results (for example: reportWebVitals(console.log))
> // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
> reportWebVitals();
> EOF

04 AWS Amplify のハンズオン(FE/API/DB 編)

Amplify CLI で API の追加

コマンド
amplify add api

出力
admin:~/environment/react-amplified (master) $ amplify add api
? Select from one of the below mentioned services: GraphQL
? Here is the GraphQL API that we will create. Select a setting to edit or continue Continue
? Choose a schema template: Single object with fields (e.g., “Todo” with ID, name, description)

⚠️  WARNING: your GraphQL API currently allows public create, read, update, and delete access to all models via an API Key. To configure PRODUCTION-READY authorization rules, review: https://docs.amplify.aws/cli/graphql/authorization-rules

✅ GraphQL schema compiled successfully.

Edit your schema at /home/ec2-user/environment/react-amplified/amplify/backend/api/reactamplified/schema.graphql or place .graphql files in a directory at /home/ec2-user/environment/react-amplified/amplify/backend/api/reactamplified/schema
✔ Do you want to edit the schema now? (Y/n) · no
✅ Successfully added resource reactamplified 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

AWS への反映

現状のAmplify上リソースの状態確認

コマンド
amplify status

出力
admin:~/environment/react-amplified (master) $ amplify status

    Current Environment: dev
    
┌──────────┬────────────────┬───────────┬───────────────────┐
│ Category │ Resource name  │ Operation │ Provider plugin   │
├──────────┼────────────────┼───────────┼───────────────────┤
│ Api      │ reactamplified │ Create    │ awscloudformation │
└──────────┴────────────────┴───────────┴───────────────────┘

GraphQL transformer version: 2

AWS への反映

コマンド
amplify push

出力
admin:~/environment/react-amplified (master) $ amplify push
⠼ Fetching updates to backend environment: dev from the cloud.⠋ Building resource api/reactamplified
⚠️  WARNING: your GraphQL API currently allows public create, read, update, and delete access to all models via an API Key. To configure PRODUCTION-READY authorization rules, review: https://docs.amplify.aws/cli/graphql/authorization-rules

⠹ Building resource api/reactamplified✅ GraphQL schema compiled successfully.

Edit your schema at /home/ec2-user/environment/react-amplified/amplify/backend/api/reactamplified/schema.graphql or place .graphql files in a directory at /home/ec2-user/environment/react-amplified/amplify/backend/api/reactamplified/schema
✔ Successfully pulled backend environment dev from the cloud.
⠋ Building resource api/reactamplified
⚠️  WARNING: your GraphQL API currently allows public create, read, update, and delete access to all models via an API Key. To configure PRODUCTION-READY authorization rules, review: https://docs.amplify.aws/cli/graphql/authorization-rules

⠸ Building resource api/reactamplified✅ GraphQL schema compiled successfully.

Edit your schema at /home/ec2-user/environment/react-amplified/amplify/backend/api/reactamplified/schema.graphql or place .graphql files in a directory at /home/ec2-user/environment/react-amplified/amplify/backend/api/reactamplified/schema

    Current Environment: dev
    
┌──────────┬────────────────┬───────────┬───────────────────┐
│ Category │ Resource name  │ Operation │ Provider plugin   │
├──────────┼────────────────┼───────────┼───────────────────┤
│ Api      │ reactamplified │ Create    │ awscloudformation │
└──────────┴────────────────┴───────────┴───────────────────┘
✔ Are you sure you want to continue? (Y/n) · yes

⚠️  WARNING: your GraphQL API currently allows public create, read, update, and delete access to all models via an API Key. To configure PRODUCTION-READY authorization rules, review: https://docs.amplify.aws/cli/graphql/authorization-rules

✅ GraphQL schema compiled successfully.

Edit your schema at /home/ec2-user/environment/react-amplified/amplify/backend/api/reactamplified/schema.graphql or place .graphql files in a directory at /home/ec2-user/environment/react-amplified/amplify/backend/api/reactamplified/schema
⠋ Building resource api/reactamplified
⚠️  WARNING: your GraphQL API currently allows public create, read, update, and delete access to all models via an API Key. To configure PRODUCTION-READY authorization rules, review: https://docs.amplify.aws/cli/graphql/authorization-rules

⠸ Building resource api/reactamplified✅ GraphQL schema compiled successfully.

Edit your schema at /home/ec2-user/environment/react-amplified/amplify/backend/api/reactamplified/schema.graphql or place .graphql files in a directory at /home/ec2-user/environment/react-amplified/amplify/backend/api/reactamplified/schema
? Do you want to generate code for your newly created GraphQL API Yes
? Choose the code generation language target javascript
? Enter the file name pattern of graphql queries, mutations and subscriptions src/graphql/**/*.js
? Do you want to generate/update all possible GraphQL operations - queries, mutations and subscriptions Yes
? Enter maximum statement depth [increase from default if your schema is deeply nested] 2

Deployment completed.
Deploying root stack reactamplified [ ---------------------------------------- ] 0/2
        amplify-reactamplified-dev-54… AWS::CloudFormation::Stack     UPDATE_IN_PROGRESS             Sat Oct 12 2024 12:32:20…     
        apireactamplified              AWS::CloudFormation::Stack     CREATE_IN_PROGRESS             Sat Oct 12 2024 12:32:23…     
Deploying api reactamplified [ =================================------- ] 5/6
        GraphQLAPI                     AWS::AppSync::GraphQLApi       CREATE_COMPLETE                Sat Oct 12 2024 12:32:29…     
        GraphQLAPINONEDS95A13CF0       AWS::AppSync::DataSource       CREATE_COMPLETE                Sat Oct 12 2024 12:32:31…     
        GraphQLAPITransformerSchema3C… AWS::AppSync::GraphQLSchema    CREATE_COMPLETE                Sat Oct 12 2024 12:32:33…     
        GraphQLAPIDefaultApiKey215A6D… AWS::AppSync::ApiKey           CREATE_COMPLETE                Sat Oct 12 2024 12:32:31…     
        Todo                           AWS::CloudFormation::Stack     CREATE_COMPLETE                Sat Oct 12 2024 12:33:21…     
        CustomResourcesjson            AWS::CloudFormation::Stack     CREATE_IN_PROGRESS             Sat Oct 12 2024 12:33:22…     

✔ Generated GraphQL operations successfully and saved at src/graphql
Deployment state saved successfully.

GraphQL endpoint: https://5dn6xw5cfreunflz64dma2lizm.appsync-api.ap-northeast-1.amazonaws.com/graphql
GraphQL API KEY: da2-jntwjassfzcwbd2ave47jjss4m

GraphQL transformer version: 2

srcコードの変更

srcコードは下記、公式ドキュメントを参照
https://docs.amplify.aws/gen1/react/start/getting-started/data-model/

コマンド
cat << EOF > src/App.js
import { useEffect, useState } from 'react';

import { generateClient } from 'aws-amplify/api';

import { createTodo } from './graphql/mutations';
import { listTodos } from './graphql/queries';

const initialState = { name: '', description: '' };
const client = generateClient();

const App = () => {
  const [formState, setFormState] = useState(initialState);
  const [todos, setTodos] = useState([]);

  useEffect(() => {
    fetchTodos();
  }, []);

  function setInput(key, value) {
    setFormState({ ...formState, [key]: value });
  }

  async function fetchTodos() {
    try {
      const todoData = await client.graphql({
        query: listTodos
      });
      const todos = todoData.data.listTodos.items;
      setTodos(todos);
    } catch (err) {
      console.log('error fetching todos');
    }
  }

  async function addTodo() {
    try {
      if (!formState.name || !formState.description) return;
      const todo = { ...formState };
      setTodos([...todos, todo]);
      setFormState(initialState);
      await client.graphql({
        query: createTodo,
        variables: {
          input: todo
        }
      });
    } catch (err) {
      console.log('error creating todo:', err);
    }
  }

  return (
    <div style={styles.container}>
      <h2>Amplify Todos</h2>
      <input
        onChange={(event) => setInput('name', event.target.value)}
        style={styles.input}
        value={formState.name}
        placeholder="Name"
      />
      <input
        onChange={(event) => setInput('description', event.target.value)}
        style={styles.input}
        value={formState.description}
        placeholder="Description"
      />
      <button style={styles.button} onClick={addTodo}>
        Create Todo
      </button>
      {todos.map((todo, index) => (
        <div key={todo.id ? todo.id : index} style={styles.todo}>
          <p style={styles.todoName}>{todo.name}</p>
          <p style={styles.todoDescription}>{todo.description}</p>
        </div>
      ))}
    </div>
  );
};

const styles = {
  container: {
    width: 400,
    margin: '0 auto',
    display: 'flex',
    flexDirection: 'column',
    justifyContent: 'center',
    padding: 20
  },
  todo: { marginBottom: 15 },
  input: {
    border: 'none',
    backgroundColor: '#ddd',
    marginBottom: 10,
    padding: 8,
    fontSize: 18
  },
  todoName: { fontSize: 20, fontWeight: 'bold' },
  todoDescription: { marginBottom: 0 },
  button: {
    backgroundColor: 'black',
    color: 'white',
    outline: 'none',
    fontSize: 18,
    padding: '12px 0px'
  }
};

export default App;
EOF

出力
admin:~/environment/react-amplified (master) $ cat << EOF > src/App.js
> import { useEffect, useState } from 'react';
> 
> import { generateClient } from 'aws-amplify/api';
> 
> import { createTodo } from './graphql/mutations';
> import { listTodos } from './graphql/queries';
> 
> const initialState = { name: '', description: '' };
> const client = generateClient();
> 
> const App = () => {
>   const [formState, setFormState] = useState(initialState);
>   const [todos, setTodos] = useState([]);
> 
>   useEffect(() => {
>     fetchTodos();
>   }, []);
> 
>   function setInput(key, value) {
>     setFormState({ ...formState, [key]: value });
>   }
> 
>   async function fetchTodos() {
>     try {
>       const todoData = await client.graphql({
>         query: listTodos
>       });
>       const todos = todoData.data.listTodos.items;
>       setTodos(todos);
>     } catch (err) {
>       console.log('error fetching todos');
>     }
>   }
> 
>   async function addTodo() {
>     try {
>       if (!formState.name || !formState.description) return;
>       const todo = { ...formState };
>       setTodos([...todos, todo]);
>       setFormState(initialState);
>       await client.graphql({
>         query: createTodo,
>         variables: {
>           input: todo
>         }
>       });
>     } catch (err) {
>       console.log('error creating todo:', err);
>     }
>   }
> 
>   return (
>     <div style={styles.container}>
>       <h2>Amplify Todos</h2>
>       <input
>         onChange={(event) => setInput('name', event.target.value)}
>         style={styles.input}
>         value={formState.name}
>         placeholder="Name"
>       />
>       <input
>         onChange={(event) => setInput('description', event.target.value)}
>         style={styles.input}
>         value={formState.description}
>         placeholder="Description"
>       />
>       <button style={styles.button} onClick={addTodo}>
>         Create Todo
>       </button>
>       {todos.map((todo, index) => (
>         <div key={todo.id ? todo.id : index} style={styles.todo}>
>           <p style={styles.todoName}>{todo.name}</p>
>           <p style={styles.todoDescription}>{todo.description}</p>
>         </div>
>       ))}
>     </div>
>   );
> };
> 
> const styles = {
>   container: {
>     width: 400,
>     margin: '0 auto',
>     display: 'flex',
>     flexDirection: 'column',
>     justifyContent: 'center',
>     padding: 20
>   },
>   todo: { marginBottom: 15 },
>   input: {
>     border: 'none',
>     backgroundColor: '#ddd',
>     marginBottom: 10,
>     padding: 8,
>     fontSize: 18
>   },
>   todoName: { fontSize: 20, fontWeight: 'bold' },
>   todoDescription: { marginBottom: 0 },
>   button: {
>     backgroundColor: 'black',
>     color: 'white',
>     outline: 'none',
>     fontSize: 18,
>     padding: '12px 0px'
>   }
> };
> 
> export default App;
> EOF

動作確認

コマンド
npm start

出力
Compiled successfully!

You can now view react-amplified in the browser.

  Local:            http://localhost:8080
  On Your Network:  http://172.31.6.39:8080

Note that the development build is not optimized.
To create a production build, use npm run build.

webpack compiled successfully

Preview > Preview Running Applicationから表示確認
image.png

05 AWS Amplify のハンズオン(Auth 編)

Amplify CLI で Auth の追加

コマンド
amplify add auth

出力
admin:~/environment/react-amplified (master) $ 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 auth resource reactamplified8f10cd21 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

AWS へ反映

現状のAmplify上リソースの状態確認

コマンド
amplify status

出力
admin:~/environment/react-amplified (master) $ amplify status

    Current Environment: dev
    
┌──────────┬────────────────────────┬───────────┬───────────────────┐
│ Category │ Resource name          │ Operation │ Provider plugin   │
├──────────┼────────────────────────┼───────────┼───────────────────┤
│ Auth     │ reactamplified8f10cd21 │ Create    │ awscloudformation │
├──────────┼────────────────────────┼───────────┼───────────────────┤
│ Api      │ reactamplified         │ No Change │ awscloudformation │
└──────────┴────────────────────────┴───────────┴───────────────────┘

GraphQL endpoint: https://5dn6xw5cfreunflz64dma2lizm.appsync-api.ap-northeast-1.amazonaws.com/graphql
GraphQL API KEY: da2-jntwjassfzcwbd2ave47jjss4m

GraphQL transformer version: 2

AWS への反映

コマンド
amplify push

出力
admin:~/environment/react-amplified (master) $ amplify push
⠧ Fetching updates to backend environment: dev from the cloud.⠋ Building resource api/reactamplified
⚠️  WARNING: your GraphQL API currently allows public create, read, update, and delete access to all models via an API Key. To configure PRODUCTION-READY authorization rules, review: https://docs.amplify.aws/cli/graphql/authorization-rules

⠼ Building resource api/reactamplified✅ GraphQL schema compiled successfully.

Edit your schema at /home/ec2-user/environment/react-amplified/amplify/backend/api/reactamplified/schema.graphql or place .graphql files in a directory at /home/ec2-user/environment/react-amplified/amplify/backend/api/reactamplified/schema
✔ Successfully pulled backend environment dev from the cloud.

    Current Environment: dev
    
┌──────────┬────────────────────────┬───────────┬───────────────────┐
│ Category │ Resource name          │ Operation │ Provider plugin   │
├──────────┼────────────────────────┼───────────┼───────────────────┤
│ Auth     │ reactamplified8f10cd21 │ Create    │ awscloudformation │
├──────────┼────────────────────────┼───────────┼───────────────────┤
│ Api      │ reactamplified         │ No Change │ awscloudformation │
└──────────┴────────────────────────┴───────────┴───────────────────┘
✔ Are you sure you want to continue? (Y/n) · yes

Deployment completed.
Deployed root stack reactamplified [ ======================================== ] 3/3
        amplify-reactamplified-dev-54… AWS::CloudFormation::Stack     UPDATE_COMPLETE                Sat Oct 12 2024 12:52:15…     
        apireactamplified              AWS::CloudFormation::Stack     UPDATE_COMPLETE                Sat Oct 12 2024 12:51:23…     
        authreactamplified8f10cd21     AWS::CloudFormation::Stack     CREATE_COMPLETE                Sat Oct 12 2024 12:51:48…     
Deployed auth reactamplified8f10cd21 [ ======================================== ] 6/6
        UserPoolClientRole             AWS::IAM::Role                 CREATE_IN_PROGRESS             Sat Oct 12 2024 12:51:16…     
        UserPool                       AWS::Cognito::UserPool         CREATE_COMPLETE                Sat Oct 12 2024 12:51:18…     
        UserPoolClient                 AWS::Cognito::UserPoolClient   CREATE_COMPLETE                Sat Oct 12 2024 12:51:20…     
        UserPoolClientWeb              AWS::Cognito::UserPoolClient   CREATE_COMPLETE                Sat Oct 12 2024 12:51:20…     
        IdentityPool                   AWS::Cognito::IdentityPool     CREATE_COMPLETE                Sat Oct 12 2024 12:51:22…     
        IdentityPoolRoleMap            AWS::Cognito::IdentityPoolRol… CREATE_COMPLETE                Sat Oct 12 2024 12:51:25…     

Deployment state saved successfully.

GraphQL transformer version: 2

srcコードの変更

srcコードは下記、公式ドキュメントを参照
https://docs.amplify.aws/gen1/react/start/getting-started/auth/

コマンド
cat << EOF > src/App.js
import { useEffect, useState } from 'react';

import { generateClient } from 'aws-amplify/api';

import { createTodo } from './graphql/mutations';
import { listTodos } from './graphql/queries';

import { withAuthenticator, Button, Heading } from '@aws-amplify/ui-react';
import '@aws-amplify/ui-react/styles.css';

const initialState = { name: '', description: '' };
const client = generateClient();

const App = ({ signOut, user }) => {
  const [formState, setFormState] = useState(initialState);
  const [todos, setTodos] = useState([]);

  useEffect(() => {
    fetchTodos();
  }, []);

  function setInput(key, value) {
    setFormState({ ...formState, [key]: value });
  }

  async function fetchTodos() {
    try {
      const todoData = await client.graphql({
        query: listTodos
      });
      const todos = todoData.data.listTodos.items;
      setTodos(todos);
    } catch (err) {
      console.log('error fetching todos');
    }
  }

  async function addTodo() {
    try {
      if (!formState.name || !formState.description) return;
      const todo = { ...formState };
      setTodos([...todos, todo]);
      setFormState(initialState);
      await client.graphql({
        query: createTodo,
        variables: {
          input: todo
        }
      });
    } catch (err) {
      console.log('error creating todo:', err);
    }
  }

  return (
    <div style={styles.container}>
      <Heading level={1}>Hello {user.username}</Heading>
      <Button onClick={signOut} style={styles.button}>
        Sign out
      </Button>
      <h2>Amplify Todos</h2>
      <input
        onChange={(event) => setInput('name', event.target.value)}
        style={styles.input}
        value={formState.name}
        placeholder="Name"
      />
      <input
        onChange={(event) => setInput('description', event.target.value)}
        style={styles.input}
        value={formState.description}
        placeholder="Description"
      />
      <button style={styles.button} onClick={addTodo}>
        Create Todo
      </button>
      {todos.map((todo, index) => (
        <div key={todo.id ? todo.id : index} style={styles.todo}>
          <p style={styles.todoName}>{todo.name}</p>
          <p style={styles.todoDescription}>{todo.description}</p>
        </div>
      ))}
    </div>
  );
};

const styles = {
  container: {
    width: 400,
    margin: '0 auto',
    display: 'flex',
    flexDirection: 'column',
    justifyContent: 'center',
    padding: 20
  },
  todo: { marginBottom: 15 },
  input: {
    border: 'none',
    backgroundColor: '#ddd',
    marginBottom: 10,
    padding: 8,
    fontSize: 18
  },
  todoName: { fontSize: 20, fontWeight: 'bold' },
  todoDescription: { marginBottom: 0 },
  button: {
    backgroundColor: 'black',
    color: 'white',
    outline: 'none',
    fontSize: 18,
    padding: '12px 0px'
  }
};

export default withAuthenticator(App);
EOF

出力
admin:~/environment/react-amplified (master) $ cat << EOF > src/App.js
> import { useEffect, useState } from 'react';
> 
> import { generateClient } from 'aws-amplify/api';
> 
> import { createTodo } from './graphql/mutations';
> import { listTodos } from './graphql/queries';
> 
> import { withAuthenticator, Button, Heading } from '@aws-amplify/ui-react';
> import '@aws-amplify/ui-react/styles.css';
> 
> const initialState = { name: '', description: '' };
> const client = generateClient();
> 
> const App = ({ signOut, user }) => {
>   const [formState, setFormState] = useState(initialState);
>   const [todos, setTodos] = useState([]);
> 
>   useEffect(() => {
>     fetchTodos();
>   }, []);
> 
>   function setInput(key, value) {
>     setFormState({ ...formState, [key]: value });
>   }
> 
>   async function fetchTodos() {
>     try {
>       const todoData = await client.graphql({
>         query: listTodos
>       });
>       const todos = todoData.data.listTodos.items;
>       setTodos(todos);
>     } catch (err) {
>       console.log('error fetching todos');
>     }
>   }
> 
>   async function addTodo() {
>     try {
>       if (!formState.name || !formState.description) return;
>       const todo = { ...formState };
>       setTodos([...todos, todo]);
>       setFormState(initialState);
>       await client.graphql({
>         query: createTodo,
>         variables: {
>           input: todo
>         }
>       });
>     } catch (err) {
>       console.log('error creating todo:', err);
>     }
>   }
> 
>   return (
>     <div style={styles.container}>
>       <Heading level={1}>Hello {user.username}</Heading>
>       <Button onClick={signOut} style={styles.button}>
>         Sign out
>       </Button>
>       <h2>Amplify Todos</h2>
>       <input
>         onChange={(event) => setInput('name', event.target.value)}
>         style={styles.input}
>         value={formState.name}
>         placeholder="Name"
>       />
>       <input
>         onChange={(event) => setInput('description', event.target.value)}
>         style={styles.input}
>         value={formState.description}
>         placeholder="Description"
>       />
>       <button style={styles.button} onClick={addTodo}>
>         Create Todo
>       </button>
>       {todos.map((todo, index) => (
>         <div key={todo.id ? todo.id : index} style={styles.todo}>
>           <p style={styles.todoName}>{todo.name}</p>
>           <p style={styles.todoDescription}>{todo.description}</p>
>         </div>
>       ))}
>     </div>
>   );
> };
> 
> const styles = {
>   container: {
>     width: 400,
>     margin: '0 auto',
>     display: 'flex',
>     flexDirection: 'column',
>     justifyContent: 'center',
>     padding: 20
>   },
>   todo: { marginBottom: 15 },
>   input: {
>     border: 'none',
>     backgroundColor: '#ddd',
>     marginBottom: 10,
>     padding: 8,
>     fontSize: 18
>   },
>   todoName: { fontSize: 20, fontWeight: 'bold' },
>   todoDescription: { marginBottom: 0 },
>   button: {
>     backgroundColor: 'black',
>     color: 'white',
>     outline: 'none',
>     fontSize: 18,
>     padding: '12px 0px'
>   }
> };
> 
> export default withAuthenticator(App);
> EOF

動作確認

コマンド
npm start

出力
Compiled successfully!

You can now view react-amplified in the browser.

  Local:            http://localhost:8080
  On Your Network:  http://172.31.6.39:8080

Note that the development build is not optimized.
To create a production build, use npm run build.

webpack compiled successfully

Preview > Preview Running Applicationから表示確認
image.png
image_!.png
image_3.png
image_4.png

06 AWS Amplify のハンズオン(Hosting 編)

アプリケーションのホスティング

コマンド
amplify add hosting

出力
admin:~/environment/react-amplified (master) $ amplify add hosting
✔ Select the plugin module to execute · Hosting with Amplify Console (Managed hosting with custom domains, Continuous deployment)
? Choose a type Manual deployment

You can now publish your app using the following command:

Command: amplify publish

クラウドリソースの変更とホスティングするアプリのビルド、デプロイ

現状のAmplify上リソースの状態確認

コマンド
amplify status

出力
admin:~/environment/react-amplified (master) $ amplify status

    Current Environment: dev
    
┌──────────┬────────────────────────┬───────────┬───────────────────┐
│ Category │ Resource name          │ Operation │ Provider plugin   │
├──────────┼────────────────────────┼───────────┼───────────────────┤
│ Hosting  │ amplifyhosting         │ Create    │ awscloudformation │
├──────────┼────────────────────────┼───────────┼───────────────────┤
│ Api      │ reactamplified         │ No Change │ awscloudformation │
├──────────┼────────────────────────┼───────────┼───────────────────┤
│ Auth     │ reactamplified8f10cd21 │ No Change │ awscloudformation │
└──────────┴────────────────────────┴───────────┴───────────────────┘

GraphQL endpoint: https://5dn6xw5cfreunflz64dma2lizm.appsync-api.ap-northeast-1.amazonaws.com/graphql
GraphQL API KEY: da2-jntwjassfzcwbd2ave47jjss4m

GraphQL transformer version: 2

No amplify console domain detected

アプリを公開する

コマンド
amplify publish

出力
admin:~/environment/react-amplified (master) $ amplify publish
⠇ Fetching updates to backend environment: dev from the cloud.⠋ Building resource api/reactamplified
⚠️  WARNING: your GraphQL API currently allows public create, read, update, and delete access to all models via an API Key. To configure PRODUCTION-READY authorization rules, review: https://docs.amplify.aws/cli/graphql/authorization-rules

⠇ Building resource api/reactamplified✅ GraphQL schema compiled successfully.

Edit your schema at /home/ec2-user/environment/react-amplified/amplify/backend/api/reactamplified/schema.graphql or place .graphql files in a directory at /home/ec2-user/environment/react-amplified/amplify/backend/api/reactamplified/schema
✔ Successfully pulled backend environment dev from the cloud.

    Current Environment: dev
    
┌──────────┬────────────────────────┬───────────┬───────────────────┐
│ Category │ Resource name          │ Operation │ Provider plugin   │
├──────────┼────────────────────────┼───────────┼───────────────────┤
│ Hosting  │ amplifyhosting         │ Create    │ awscloudformation │
├──────────┼────────────────────────┼───────────┼───────────────────┤
│ Api      │ reactamplified         │ No Change │ awscloudformation │
├──────────┼────────────────────────┼───────────┼───────────────────┤
│ Auth     │ reactamplified8f10cd21 │ No Change │ awscloudformation │
└──────────┴────────────────────────┴───────────┴───────────────────┘
✔ Are you sure you want to continue? (Y/n) · yes

Deployment completed.
Deploying root stack reactamplified [ ==============================---------- ] 3/4
        amplify-reactamplified-dev-54… AWS::CloudFormation::Stack     UPDATE_COMPLETE_CLEANUP_IN_PR… Sat Oct 12 2024 12:59:23…     
        hostingamplifyhosting          AWS::CloudFormation::Stack     CREATE_COMPLETE                Sat Oct 12 2024 12:59:21…     
        apireactamplified              AWS::CloudFormation::Stack     UPDATE_COMPLETE                Sat Oct 12 2024 12:59:20…     
        authreactamplified8f10cd21     AWS::CloudFormation::Stack     UPDATE_COMPLETE                Sat Oct 12 2024 12:59:12…     
Deployed hosting amplifyhosting [ ======================================== ] 1/1
        AmplifyBranch                  AWS::Amplify::Branch           CREATE_COMPLETE                Sat Oct 12 2024 12:59:14…     

Deployment state saved successfully.

GraphQL transformer version: 2

Publish started for amplifyhosting

> react-amplified@0.1.0 build
> react-scripts build

Creating an optimized production build...
One of your dependencies, babel-preset-react-app, is importing the
"@babel/plugin-proposal-private-property-in-object" package without
declaring it in its dependencies. This is currently working because
"@babel/plugin-proposal-private-property-in-object" is already in your
node_modules folder for unrelated reasons, but it may break at any time.

babel-preset-react-app is part of the create-react-app project, which
is not maintianed anymore. It is thus unlikely that this bug will
ever be fixed. Add "@babel/plugin-proposal-private-property-in-object" to
your devDependencies to work around this error. This will make this message
go away.
  
Compiled successfully.

File sizes after gzip:

  193.07 kB  build/static/js/main.640d1653.js
  30.12 kB   build/static/css/main.a38340b4.css
  1.78 kB    build/static/js/453.75d5ea3a.chunk.js

The project was built assuming it is hosted at /.
You can control this with the homepage field in your package.json.

The build folder is ready to be deployed.
You may serve it with a static server:

  npm install -g serve
  serve -s build

Find out more about deployment here:

  https://cra.link/deployment

✔ Zipping artifacts completed.
✔ Deployment complete!
https://dev.d14fd37vg009fk.amplifyapp.com

動作確認

ブラウザから上記URLにアクセス
image0.png

image_1.png

07 本シリーズのまとめ、リソースの削除

Amplify (Cloud9で実施)

コマンド
amplify delete

出力
admin:~/environment/react-amplified (master) $ amplify delete
✔ Are you sure you want to continue? This CANNOT be undone. (This will delete all the environments of the project from the cloud and wipe out all the local files created by Amplify CLI) (y/N) · yes
⠋ Deleting resources from the cloud. This will take a few minutes.
Deleting env: dev.
✔ Project deleted in the cloud.
✅ Project deleted locally.

Cloud9削除 (CloudShellで実施)

コマンド
# Cloud9削除
aws cloud9 delete-environment \
    --environment-id ${CLOUD9_ENVIRONMENT_ID}

出力
[cloudshell-user@ip-10-132-68-36 ~]$ # Cloud9削除
[cloudshell-user@ip-10-132-68-36 ~]$ aws cloud9 delete-environment \
>     --environment-id ${CLOUD9_ENVIRONMENT_ID}

IAMユーザーの削除

コマンド
# ユーザーにアタッチされているポリシーをリスト
POLICIES=$(
    aws iam list-attached-user-policies \
        --user-name ${USER_NAME} \
        --query 'AttachedPolicies[*].PolicyArn' \
        --output text
) \
&& echo ${POLICIES}

# リスト内のポリシーをデタッチする
for POLICY in ${POLICIES}; do
    aws iam detach-user-policy \
        --user-name ${USER_NAME} \
        --policy-arn ${POLICY}
done

# アクセスキーIDの確認
IAM_ACCESSKEY_ID=$(
    aws iam list-access-keys \
        --user-name ${USER_NAME} \
        --query 'AccessKeyMetadata[*].AccessKeyId' \
        --output text
) \
&& echo ${IAM_ACCESSKEY_ID}

# アクセスキーの削除
aws iam delete-access-key \
    --user-name ${USER_NAME}\
    --access-key-id ${IAM_ACCESSKEY_ID}

# ユーザーの削除
aws iam delete-user --user-name ${USER_NAME}

出力
[cloudshell-user@ip-10-132-68-36 ~]$ # ユーザーにアタッチされているポリシーをリスト
[cloudshell-user@ip-10-132-68-36 ~]$ POLICIES=$(
>     aws iam list-attached-user-policies \
>         --user-name ${USER_NAME} \
>         --query 'AttachedPolicies[*].PolicyArn' \
>         --output text
> ) \
> && echo ${POLICIES}
arn:aws:iam::aws:policy/AdministratorAccess-Amplify
[cloudshell-user@ip-10-132-68-36 ~]$ 
[cloudshell-user@ip-10-132-68-36 ~]$ # リスト内のポリシーをデタッチする
[cloudshell-user@ip-10-132-68-36 ~]$ for POLICY in ${POLICIES}; do
>     aws iam detach-user-policy \
>         --user-name ${USER_NAME} \
>         --policy-arn ${POLICY}
> done
[cloudshell-user@ip-10-132-68-36 ~]$ 
[cloudshell-user@ip-10-132-68-36 ~]$ # アクセスキーIDの確認
[cloudshell-user@ip-10-132-68-36 ~]$ IAM_ACCESSKEY_ID=$(
>     aws iam list-access-keys \
>         --user-name ${USER_NAME} \
>         --query 'AccessKeyMetadata[*].AccessKeyId' \
>         --output text
> ) \
> && echo ${IAM_ACCESSKEY_ID}
AKIAWFKRCMKOVMB6JSX5
[cloudshell-user@ip-10-132-68-36 ~]$ 
[cloudshell-user@ip-10-132-68-36 ~]$ # アクセスキーの削除
[cloudshell-user@ip-10-132-68-36 ~]$ aws iam delete-access-key \
>     --user-name ${USER_NAME}\
>     --access-key-id ${IAM_ACCESSKEY_ID}
[cloudshell-user@ip-10-132-68-36 ~]$ 
[cloudshell-user@ip-10-132-68-36 ~]$ # ユーザーの削除
[cloudshell-user@ip-10-132-68-36 ~]$ aws iam delete-user --user-name ${USER_NAME}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?