はじめに
※本記事は続き物の最終回的な位置づけとなっており、単体で Static Web Apps + Functions + MySQL のすべてに言及しているものではありません
前回までの記事で、Azure Functions + MySQLを使用してバックエンド部分を作成しました。
今回はそこにAzure Static Web Appsを使用したフロント部分を追加して、シンプルなWebアプリケーションとして動かすことを目指します。
フロント部分はReactを使うことにしました。
※"最低限動くもの"を目指すので、認証などのセキュリティ関連の実装は含みません
ついでに、Azure FunctionsアプリをGithubと連携して自動デプロイさせるようにします。
構成イメージ
赤くなっている部分が今回の範囲。
Azure Static Web Appsでは、
マネージドなFunctionsアプリ
と独自の(自前の)Functionsアプリ
の2通りの構成にできますが、既に作成済みなのと、前者はJavaに対応していないという理由で、今回は後者の構成で進めます。
→Azure Functions による Azure Static Web Apps での API のサポート
前回までの記事
動作環境
作業時の環境は以下の通りです。
- OS
- Windows 11 Pro (21H2)
- React 18.2.0
フロント側のアプリを作成
- Reactを使用してフロント側のアプリを普通に作る。
※作成方法はここでは扱いません - 作成したアプリをGithubにpushする。
ソースはこちら
実装時のポイント
APIのエンドポイント
、APIキー
は環境(開発環境・運用環境等)によって変化する可能性があるので、環境変数に持たせます。
※環境変数の設定方法は後述
プログラム内で環境変数は以下のように取得できます。
// Reactの場合、変数名が"REACT_APP_"で始まる必要がある
const VARIABLE: string = process.env.REACT_APP_VARIABLE;
フロント側のアプリをAzureにデプロイ
Azure Portalで「静的Webアプリ」で検索し、作成
内容入力して、確認および作成
今回はGithubと連携させるので デプロイの詳細
> ソース
で Github
を選択。
ログインを求められたらログインする。
設定名 | 設定内容 |
---|---|
組織 | 組織を選択(個人アカウントの場合はアカウント名と同じ) |
リポジトリ | デプロイ対象のリポジトリを選択 |
分岐 | デプロイ対象のブランチを選択 |
ビルドのプリセット | フレームワークを選択。今回はReact |
アプリの場所 | リポジトリルートから見たアプリのルードディレクトリを指定。 |
APIの場所 | マネージドFunctionsを使用する場合は指定。今回は使用しないので空 |
出力先 | ビルドされたファイルの出力先 |
作成が完了すると、GithubのリポジトリにWorkflowの設定ファイルが追加され、ビルド&デプロイが開始されます。
この設定ファイルを編集することで、ビルド設定などを調整できます。
ここでは特に変更はありません。
name: Azure Static Web Apps CI/CD
on:
push:
branches:
- main
pull_request:
types: [opened, synchronize, reopened, closed]
branches:
- main
jobs:
build_and_deploy_job:
if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.action != 'closed')
runs-on: ubuntu-latest
name: Build and Deploy Job
steps:
- uses: actions/checkout@v2
with:
submodules: true
- name: Build And Deploy
id: builddeploy
uses: Azure/static-web-apps-deploy@v1
with:
azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_XXXXXXXX }}
repo_token: ${{ secrets.GITHUB_TOKEN }} # Used for Github integrations (i.e. PR comments)
action: 'upload'
###### Repository/Build Configurations - These values can be configured to match your app requirements. ######
# For more information regarding Static Web App workflow configurations, please visit: https://aka.ms/swaworkflowconfig
app_location: '/' # App source code path
api_location: '' # Api source code path - optional
output_location: 'build' # Built app content directory - optional
###### End of Repository/Build Configurations ######
close_pull_request_job:
if: github.event_name == 'pull_request' && github.event.action == 'closed'
runs-on: ubuntu-latest
name: Close Pull Request Job
steps:
- name: Close Pull Request
id: closepullrequest
uses: Azure/static-web-apps-deploy@v1
with:
azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_XXXXXXXX }}
action: 'close'
環境変数の設定
ローカル実行時
ローカル環境で実行する場合は .env.local
に環境変数を設定します。
REACT_APP_API_ORIGIN=<APIのオリジン>
REACT_APP_API_KEY=<Azure Functionsアプリのアプリキー>
Azureデプロイ時
ここで注意したいのが、環境変数はビルド時に解決されるという点です。
ビルドプロセスが動くのはAzure側ではなくGithub側なので、Github側にSecretsとして環境変数を登録し、Workflow設定ファイルから参照するようにします。
最初この流れが理解できていなくて、Functionsの時と同様にAzure側のアプリケーション設定で何とかしようと悪戦苦闘してました・・・
(フロントエンドやってる人には鼻で笑われるでしょう・・・)
Static Web Appsの「アプリケーション設定」は、マネージドFunctionsのための設定なんですね。
GithubのSecrets登録
Githubにログインして <リポジトリ>
> Settings
> Secrets
> Actions
> New repository secret
から登録します。
設定名 | 設定値 |
---|---|
API_ORIGIN | Azure Functionsアプリのホスト |
API_KEY | Azure Functionsアプリのアプリキー |
※設定名はWorkflow設定ファイルの方と合っていれば何でも良い
Workflow設定ファイルの修正
登録したSecretsを参照して環境変数を設定するよう修正します。
pushすると自動的にビルド&デプロイが実行されます。楽。
name: Azure Static Web Apps CI/CD
# ・・・
jobs:
build_and_deploy_job:
# ・・・
steps:
- name: Build And Deploy
# ・・・
# ↓追加↓
env: # ビルド時に参照する環境変数
REACT_APP_API_ORIGIN: ${{ secrets.API_ORIGIN }} # APIのホスト
REACT_APP_API_KEY: ${{ secrets.API_KEY }} # APIキー
# ↑追加↑
# ・・・
FunctionsのCORS設定
2023/02/23 追記
記事執筆時点では筆者の知識不足のため、面倒な方法になっていますが、Static Web Apps と 独自関数は簡単にリンクさせることができ、CORSなどの設定も不要です。
更にこの方法だとAPI側の認証もStatic Web Apps の設定で一括でできたりと何かと便利なので、オススメです!
https://learn.microsoft.com/ja-jp/azure/static-web-apps/functions-bring-your-own
ここまででフロント側としては構築完了なのですが、このままではAPIにアクセスすることができません。
というのも、フロント側のオリジンとAPI側のオリジンが一致しておらず、CORSエラーとなってしまうためです。
そこで、Azure Functions側でCORSの設定を行う必要があります。
Azure Portalで 関数アプリ
> <関数アプリ名>
> CORS
で、フロント側のURLを追加します。
フロント側のURLは、静的Webアプリ
> <アプリ名>
> 概要
> URL
で確認できます。
これで画面からAPIにアクセスできるようになりました。
(APIへのリクエストが正常に返ってきているのが確認できます)
Functionsの自動デプロイ設定
最後に、現状Functionsアプリは手動でデプロイする必要があるため、ブランチへのpushをトリガーに自動でデプロイされるようにします。
Azure Portalで 関数アプリ
> <関数アプリ名>
> デプロイセンター
から設定します。
ソース
で Github
を選択。
もしログインを求められたらログインする。
保存
ボタンで確定する。
設定名 | 設定内容 |
---|---|
組織 | 組織を選択(個人アカウントの場合はアカウント名と同じ) |
リポジトリ | デプロイ対象のリポジトリを選択 |
ブランチ | デプロイ対象のブランチを選択 |
保存すると、Static Web Appsと同様、GithubのリポジトリにWorkflowの設定ファイルが追加され、ビルド&デプロイが開始されます。
以上
おわりに
フロントエンドからバックエンドまでの一通りを、面倒なミドルウェアの設定も不要で、サクッと(?)構築できました。
環境面をあまり意識せずコードに集中できるのは、やはりありがたいですね。
最後までお付き合いくださり、ありがとうございました!