Cloud9でAmplifyの開発をはじめるまで

どうも、Javascriptを猛勉強中の寺内です。

サーバレスでWebアプリケーションを作りたいとなったとき、AWS Amplifyっていう便利なフレームワークがあるんだよなぁ、と思いながらも、その開発環境を用意するところでつまずきがちです。

開発環境といえばAWS Cloud9があるじゃない、ということでその両方を使って、ブラウザのみで オールAWSな開発環境を作ってみましょう。

ここで想定するWebアプリケーションはVue.jsで作る基本的なものとし、バックエンドはS3+API Gateway+Lambdaの構成を作るところまでとします。慣れてくれば、この構成にCognitoやDynamoDBも追加できるようになるでしょう。

Cloud9環境の作成

なにはともあれ、Cloud9のサービスで「Create environment」を押下し、IDE環境を作成します。
環境名は何でもよいですがプロジェクト名と個人名を付けておくのがいいでしょう。

Environment settings

以下の点に注意します。

  • Environment type
    作業環境ができるEC2へCloud9からの接続方法を選びます。 direct accessがよいです。
  • Instance type
    Amplifyを動かすのでメモリを確保するため t3.small を選びます。
  • Platform
    OSの選択です。お好みですが、以降は Amazon Linux 2 として説明していきます。
  • Cost-saving setting
    IDEを終了するまでのアイドルタイムを選択します。デフォルトの30分のままで大丈夫です。
  • Network settings (advanced)
    作業環境となるEC2が起動するVPCを選べます。デフォルトではdefault VPCが選ばれますが、できれば自分で管理できるVPCを選んだほうがいいでしょう。 インターネットへの接続ができるVPCとサブネットを選択してください。

これで数分待てば環境ができあがります。

開発環境の準備

まずはCloud9環境そのものの設定をしていきます。

ディスクストレージの拡大

Cloud9のEC2インスタンスはストレージ(EBS)が10GBです。これでは少々心もとないので32GBに拡大します。 以下のコマンドをそのまま打ち込みます。

$ INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
$ VOLUME_ID=$(aws ec2 describe-volumes --query "Volumes[?Attachments[?InstanceId=='$INSTANCE_ID']].{ID:VolumeId}" --output text)
$ aws ec2 modify-volume --volume-id $VOLUME_ID --size 32

1行目で INSTANCE_ID という環境変数に、EC2インスタンスIDをメタDBから取得します。
2行目でそのインスタンスIDからEBSボリュームIDをAWS CLIで取得し、 VOLUME_ID 環境変数に格納します。
3行目でAWS CLIを使いEBSのボリュームサイズを変更します。

Python 3.8のインストール

Lambdaで使うPythonをインストールします。
ベースになっているAmazon Linux 2のOSにはPython 3.7 がインストールされています。しかしAmplifyではLambda関数のラインタイムがPython 3.8を想定しているため、このままではAmplifyでエラーが出てしまいます。 そのため、Pythonの仮想環境であるpyenvとpipenvをインストールし、Python 3.8を使えるようにしておきます。

現状のPythonバージョンを確認します。

$ python --version
Python 3.7.10

pyenvをホームディレクトリ以下 ~/.pyenv にインストールします。

$ git clone <https://github.com/pyenv/pyenv.git> ~/.pyenv

実行できるか確認します。

$ ~/.pyenv/bin/pyenv --version
pyenv 2.3.3-1-gae22c695

bashの設定ファイル ~/.bash_profile に環境変数を設定します。

$ echo -e "# pyenv paths" >> ~/.bash_profile
$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
$ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(pyenv init -)"' >> ~/.bash_profile

bashに設定ファイルを読み込ませます。

$ source ~/.bash_profile

pyenvでインストール可能なPythonのバージョンを検索します。

$ pyenv install --list|grep 3.8
  3.8.0
  3.8-dev
  3.8.1
  3.8.2
  3.8.3
  3.8.4
  3.8.5
  3.8.6
  3.8.7
  3.8.8
  3.8.9
  3.8.10
  3.8.11
  3.8.12
  3.8.13
  miniconda-3.8.3
(以下略)

Pythonのコンパイルに足りないライブラリがあるのでインストールします。

$ sudo yum -y install bzip2-devel 

いよいよpythonのインストールです。コンパイルするので少し時間がかかります。

$ pyenv install 3.8.13

次に、Pythonの仮想環境ツールである pipenv をインストールします。

$ pip install pipenv

pipenv環境に、入れたばかりのPython 3.8.13 を組み込みます。

$ pipenv install --python 3.8.13

では、その仮想環境に入りましょう。

$ pipenv shell

これでPython 3.8.13が起動するシェルに入りました。確認しましょう。

$ python --version
Python 3.8.13

最後に仮想環境にboto3をインストールします。

$ pipenv install boto3

シェルとgitコマンドの設定

作業を効率的に実施するため、自分好みの設定やgitコマンドの初期設定を行っておきます。

bashの環境変数にnode.jsの使用メモリサイズを取る設定を入れるため、~/.bash_profile に以下を追記します。
その他、コマンドエイリアスを好みで入れておきましょう。

export NODE_OPTIONS="--max-old-space-size=2048"
alias ll="ls -la"
alias la="ls -a"
alias cls=clear

次にgitコマンドの初期設定をしておきます。
エディタは初期ではnanoが設定されています。vimに変更したい場合は以下のように入れてください。

$ git config --global user.name "your_name"
$ git config --global user.email "xxx@xxx.xx"
$ git config --global core.editor 'vim -c "set fenc=utf-8"'

認証情報の設定

Cloud9内で使うIAM認証の情報を設定します。

Cloud9では標準で独自の一時認証情報がSTSで払い出されています。以下のコマンドで、現在の認証情報を確認できます。

$ cat ~/.aws/credentials

Amplifyでは独自にIAMユーザを作成して使うこととなりますので、この認証情報は不要です。そこで、Cloud9設定で一時認証情報の無効化をします。
左上のCloud9ロゴからPreferenceを選び設定画面を表示します。(もしくは Ctrl+, で出ます)
「AWS Settings」から「Credentials」のスイッチをOFFにします。

OFFにした時点で、 ~/.aws/credentials ファイルを再度確認すると、無くなっていることがわかります。

開発ソフトウェアの準備

Cloud9にAmplifyとVue.jsを入れていきます。

Amplifyのインストール

まずはnodeコマンドが使えるか確認を兼ねて、node.jsのバージョンを確認しましょう。

$ node -v
v16.16.0

次にAmplify CLIをインストールします。

$ npm install -g @aws-amplify/cli

Amplifyコマンドが使えるようになりました。

$ amplify --version
9.2.1

以下のコマンドでAmplifyで使うIAMユーザを作成し認証情報を設定します。

$ amplify configure

以下のようなメッセージが出るので、ブラウザでAWS Management Consoleに管理者権限でログインします。

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

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

次にリージョンをカーソルキーを使って選び、エンターキーで確定します。

次にユーザ名を聞かれます。これがAmplifyで使用するIAMユーザであり、これから新たに作るIAMユーザ名です。 適切なIAMユーザ名を入力するとリンクが表示されます。

このリンクをブラウザで開きます。
さきほど入力したIAMユーザ名が既に入力された状態で、IAMユーザ追加画面が表示されます。 このIAMユーザではConsoleログインはしない状態になっていますので、そのまま次のステップにいきます。

次の画面ではIAMユーザの権限を設定します。Amplify用のAdministrator権限 AdministratorAccess-Amplify が選択されていますので、そのまま次のステップにいきます。

タグ設定を適当に行いIAMユーザを作成します。

最後にアクセスキーとシークレットキーが表示されますので、間違えなくエディター等に保存してください。

そうしたらCloud9に戻ります。
エンターキーを押して、今作成したIAMユーザのアクセスキーとシークレットキーを入力します。
そしてプロファイル名を入れます。通常、このまま default でよいでしょう。

これで認証情報が設定できました。

適当なAWS CLIコマンドを発行して、正常なレスポンスを得られるか確認しておきましょう。

$ aws s3 ls

クレデンシャルファイルの内容も間違えないか確認しておきましょう。

$ cat ~/.aws/credentials 
[default]
aws_access_key_id=AKIXXXXXXXXXXXXXX
aws_secret_access_key=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Vue.jsのインストール

Vue.jsをインストールします。

$ npm install -g @vue/cli

vueコマンドが使えるようになりました。

$ vue --version
@vue/cli 5.0.8

プロジェクトの作成

いよいよVue.jsアプリケーションのプロジェクト(作業用ディレクトリ)を作ります。プロジェクト名を決めておきましょう。今後、このプロジェクト名をAmplifyなどに設定していきます。そしてリソースなどのキーワードとなっていくので、一貫したプロジェクト名を命名しておくのはとても大事です。

どのVueバージョンを使うか聞かれますので、プロジェクトに合わせます。
ここではVue3を選んでいます。

$ vue create PROJECT-NAME

プロジェクト名のディレクトリが作られたので、そのディレクトリの下にcdコマンドで移動します。

次に npm run serve コマンドでアプリを確認できるというメッセージが出ますが、Cloud9ではまだできません。 ローカルWebサーバへのアクセス制御を外す必要があります。

vue.config.js ファイルを以下の内容に書き換えます。

const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  devServer: {
      client: {
          webSocketURL: 'ws://0.0.0.0:8080/ws',
      },
       allowedHosts: 'all',
  },
  transpileDependencies: true
})

ファイルを保存して以下のコマンドを入れると、内部でWebサーバが起動し、ブラウザでVueアプリを確認できるようになります。

$ npm run serve

正常に起動したら、Cloud9の「Preview」から「Preview Running Application」を選びます。

すると、以下のようにミニブラウザが表示され、アプリケーションを確認できます。

右上の「Browser」をクリックすると、別タブのブラウザで全体を表示することができます。

Amplifyの初期化

このプロジェクトディレクトリの中で、Amplifyの初期設定を行います。

$ amplify init

まずプロジェクト名を聞かれるので入力します。プロジェクト名はアルファベットと数値のみでハイフン等の記号は使えないことに注意してください。 今後、バックエンド側のAWSリソースはこの名前が全てに付いていきますので、プロジェクト名と連動したわかりやすい名前をつけましょう。

次にプロジェクト情報として以下の状態が提示されます。

Project information
| Name: yteratech
| Environment: dev  ←環境名
| Default editor: Visual Studio Code ←利用エディタ
| App type: javascript  ←フロントエンドの利用言語
| Javascript framework: vue  ←フロントエンドのフレームワーク
| Source Directory Path: src  ←フロントエンドのサブディレクトリ名
| Distribution Directory Path: dist ←フロントエンドの生成物の保存ディレクトリ
| Build Command: npm run-script build
| Start Command: npm run-script serve

このままで変更の必要はないので、y を入力します。(もしVueではなくReactを使うなどの変更の際は n を入力して、対話メニュー形式で変更します)

次に、Amplifyで使う認証の種類を聞かれます。 AWS Profile を選択し、 default を選びます。
これで初期化が始まり、基本的なIAMロールやS3バケットが作成されます。 またAWS Management ConsoleのAmplifyコンソールが使えるようになります。

リポジトリの準備

AWS CodeCommitを使ってgitリポジトリを作成します。これは後ほどAmplifyのhosting機能と接続し、 git push による自動デプロイを実現します。

リポジトリの作成

CodeCommitサービスのダッシュボードで「リポジトリの作成」ボタンを押下します。 プロジェクト名に応じたリポジトリ名を入力し、「作成」ボタを押下します。
単純に認証なしのHTTPS接続で利用することとします。

IAMユーザにCodeCommit権限の追加

上記で作成したAmplify用のIAMユーザには、CodeCommitのアクセス権限が付いていません。IAMユーザにCodeCommitのアクセス権限追加を行います。
IAMの管理画面で「ユーザ」を選択し、先程作成したIAMユーザを検索します。
アクセス権限には AdministratorAccess-Amplify のみが付いています。
「アクセス権限の追加」ボタンを押し、「既存のポリシーを直接アタッチ」を選びます。
その上で、 AWSCodeCommitPowerUser 権限を検索し、追加します。

gitコマンドでリモートリポジトリの登録

「ステップ 3: リポジトリのクローンを作成する」からhttps://から始まるリポジトリのURLをコピーします。

現在のカレントディレクトリがプロジェクトディレクトリの直下にいることを確認した後、以下のコマンドでgitコマンドにリモートリポジトリを登録します。

$ git remote add origin <https://から始まるリポジトリのURL>

以下のコマンドで確認します。

$ git remote show origin

初めてのpush

では今できているVueのサンプルプログラムをリモートリポジトリにpushしましょう。 以下のコマンドでpushします。

$ git add .
$ git commit -m "first commit"
$ git push --set-upstream origin master

CodeCommitのコンソール画面で内容を確認してみてください。 次回以降、以下のコマンドでpushできます。

$ git push origin

Amplify hostingの構築

Amplifyにhostingの機能を追加します。これができるとフロントエンドの配信がS3から行えるようになります。

機能の追加

Amplifyの現在の概略は以下のコマンドで確認できます。

$ amplify status

    Current Environment: dev
    
┌──────────┬───────────────┬───────────┬─────────────────┐
│ Category │ Resource name │ Operation │ Provider plugin │
└──────────┴───────────────┴───────────┴─────────────────┘

まだ何も機能が追加されていないことがわかります。
まず以下のコマンドでhosting機能を追加します。

$ amplify add hosting

はじめにプラグインモジュールを選択します。ここではこれから作るホスティング機能をAmplify Consoleで使う(AWSの管理下にあるホスティングとする)か、自分のアカウント内のS3とCloudFrontで行うか、を選択します。 ここではAWSおまかせの Hosting with Amplify Console を選択します。

次にデプロイタイプを聞かれます。ここではgitコマンドと連携する Continuous deployment (Git-based deployments) を選びます。

リポジトリとの接続

するとAmplify Consoleでリポジトリと接続しろ、と言われます。
AWS Management ConsoleでAmplify Consoleを表示します。
いま作ったアプリケーションができているので、そのアプリケーションに入ります。
「Hosting Environments」を見ると、下記のようになっています。

「AWS CodeCommit」を選択し、「ブランチを接続」を押下します。

先程作ったCodeCommitのリポジトリを選択し、ブランチは master にしたまま「次へ」を押下します。
バックエンド環境として、アプリケーションの名前と環境( dev )を入力します。
その下にある「フルスタックCI/CD」のスイッチをONにします。これをONにすると、バックエンド側のファイルを更新して git push することで、自動的にバックエンド側も構築されます。( amplify push を実行する必要がなくなります)

次に、「新しいロールを作成」ボタンを押して、IAMロールを作成します。 IAMロールには、 AdministratorAccess-Amplify の権限を割り当てます。 その作ったロールを記載して、「次へ」ボタンを押下します。

確認画面が出ますので、「確認して保存」を押します。 すると、プロビジョンからビルド、デプロイと自動的に進んでいきます。 問題なければ、Cloud9に戻りエンターキーを押します。

配信の確認

hostingのURLが表示されますので、それを保管しておきます。

Amplify hosting urls: 
┌──────────────┬──────────────────────────────────────────────┐
│ FrontEnd Env │ Domain                                       │
├──────────────┼──────────────────────────────────────────────┤
│ master       │ <https://master.XXXXXXXXXXXXXX.amplifyapp.com> │
└──────────────┴──────────────────────────────────────────────┘

Amplify Consoleの自動デプロイが「検証」までグリーンになるまで待ちます。

そしてhostingのURLにアクセスしてみてください。Vueのサンプルアプリケーションが表示されれば成功です。

フロントエンドの更新手順

フロントエンドの開発は以下のように進めていきます。

まず src/components/HelloWorld.vue ファイルを編集してみましょう。
3行目の <h1>{{ msg }}</h1> の下の行に with Amplify という行を追加し保存してください。

続けてCloud9内のローカルのブラウザで確認します。
ターミナルでカレントディレクトリがプロジェクトディレクトリ直下にいることを確認し、以下のコマンドを入れてCloud9内でwebサーバを起動します。

$ npm run serve

エラーが出なかったらビルド成功です。
Cloud9の「Preview」から「Preview Running Application」を選ぶとミニブラウザが起動しアプリ画面が確認できます。

追記した with Amplify が表示されていて問題なければ、ターミナルで以下のコマンドを入力しgitにcommitし、リモートリポジトリにpushします。

$ git add .
$ git commit -m "First Commit."
$ git push

Amplify Consoleをみると、全てグリーンだったアイコンがグレイに変わり、プロビジョン、デプロイと順番にブルーになり、処理が進んでいきます。

全てがグリーンになったら、再度hostingのURLにアクセスしてください。

入力した 「with Amplify」が反映されています。

バックエンド環境の準備

これからAmazon API GatewayとAWS Lambdaの準備をしていきます。

API構造の設計

まずはフロントエンドがアクセスするAPIの構造をしっかり設計しましょう。ちゃんとやるのであれば、swagger といったAPI設計ツールを活用することも検討してください。

ここでは、 /items というAPIパスを1つ作ることとします。

API機能の追加

まずAmplifyの現状を確認しておきましょう。

$ amplify status

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

このようにhostingのみ追加されている状態です。
以下のコマンドでAmplifyにAPI機能を追加します。同時にAPI Gatewayから呼ばれるLambda関数も作成されます。

$ amplify add api

最初にRESTかGraphQLを使うかを聞かれます。ここではカーソルキーでRESTを選択します。

次にプロジェクト名を聞かれます。Vueでcreate projectしたときと同じような、わかりやすい名前を入力してください。バックエンド環境のリソースに付与されていきます。なおアルファベットと数字しか使えません。

次がAPIパスです。先に考えたAPIパス /items を入力します。

次がLambda関数名を入力します。プロジェクト名に合わせた名前が提案されるので、そのままエンターキーを押します。

Lambda関数のランタイムを選択します。ここでは Python を選択します。もしエラーが出た場合は、先の項でPython 3.8をインストールしましたが、それが失敗しているか、Pythonの仮想環境のシェルを起動( pipenv shell )した上でamplifyコマンドを実行していないかです。Pythonのバージョンを確認してください。

アドバンスド設定をするか聞かれます。ここでは n を入れます。

Lambda関数のコードを編集するかを聞かれますので n を入れます。

APIアクセス制御をするか聞かれますので、ここも n を入れます。

さらにAPIを追加するかを聞かれますので n を入れます。

これでコマンドは終了します。

バックエンドのデプロイ

正常に amplify add コマンドが終了すると、以下のような状態になっています。

$ amplify status

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

この状態はまだamplifyがローカルで変更申請を受け付けただけです。
以下のコマンドで、実際にAWSへ変更をデプロイします。

$ amplify push

するとCloudFormationが生成され、AWS上に実際のリソースが作成されていきます。

デプロイの確認

デプロイが終了したら、以下のようにAPI GatewayのエンドポイントURLが出力されます。

REST API endpoint: <https://XXXXXXXXXXX.execute-api.ap-northeast-1.amazonaws.com/dev>

上記で表示されたURLに、先程入力したAPIパスを付与してブラウザに入力してください。上記の例では以下のようになります。

https://XXXXXXXXXXX.execute-api.ap-northeast-1.amazonaws.com/dev/items

するとブラウザに以下のように表示されます。これはAPI Gatewayを経由してLambdaが応答している確認となります。

"Hello from your new Amplify Python lambda!"

AWS Management ConsoleでAPI GatewayとLambdaが指定したプロジェクト名で作られているかを確認してください。
設定内容も見ておくとよいでしょう。
ただ残念ながら、Lambda関数のPythonコードはAmplifyでデプロイすると、Management Consoleから直接見たり編集したりすることはできません。 Lambda関数のPythonコードは、プロジェクトディレクトリ以下の以下のファイルに記載されています。

<プロジェクトディレクトリ>/amplify/backend/function/<Lambda関数名>/src/index.py

以下のような内容になっています。

import json

def handler(event, context):
  print('received event:')
  print(event)
  
  return {
      'statusCode': 200,
      'headers': {
          'Access-Control-Allow-Headers': '*',
          'Access-Control-Allow-Origin': '*',
          'Access-Control-Allow-Methods': 'OPTIONS,POST,GET'
      },
      'body': json.dumps('Hello from your new Amplify Python lambda!')
  }

'Hello from your new Amplify Python lambda!' の内容を修正して、ファイルを保存したら、再度 amplify push をしてみてください。
そして同じくブラウザからAPI Gatewayにリクエストを送ると、修正された文字列が返ってきます。
これでAWS上のLambda関数が更新されていることが確認できます。

開発の開始

以上で、フロントエンドとバックエンドが全てCloud9のプロジェクトディレクトリ配下に収められました。

まとめると以下のようになります。

対象 ソースファイル
フロントエンド(Vue.js) <プロジェクトディレクトリ>/src/main.js
バックエンドのLambda(Python) <プロジェクトディレクトリ>/amplify/backend/function/<Lambda関数名>/src/index.py
バックエンドのAPI GW <プロジェクトディレクトリ>/amplify/backend/api/

上記のファイルを編集していくことで開発を進めることとなります。

LambdaやAPI Gatewayの細かな設定変更は、上記ディレクトリにパラメータファイルがあり、それを編集することで調整できます。AWS Management Consoleから手作業で変更を行わないことを徹底してください。全ての変更は amplifyコマンドで行います。

フロントエンドの編集をした後、 npm run serve でローカルで確認し、問題なければ git commit をし、 git push すると自動的にCodeCommitリポジトリからビルドが走り、hostingのS3に反映されます。

バックエンドの編集をした後、 git commit をし、 amplify push をするとCloudFormationが動きAWSをリソースが変更されます。

こうして、フロントエンドとバックエンドを交互に開発しながら、アプリケーションを育てていってください。

チームで開発する場合は、デプロイのパイプラインがメンバー間で混じらないように、ブランチの切り方を分け、バックエンドを複数設定し別々のパイプラインが走るようにしたほうが良いでしょう。

では、よいデベロッパー生活を。

タイトルとURLをコピーしました