10
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

[Azure] Static Web Apps + Functions + MySQLでWebアプリをつくる

Last updated at Posted at 2022-10-24

はじめに

※本記事は続き物の最終回的な位置づけとなっており、単体で Static Web Apps + Functions + MySQL のすべてに言及しているものではありません

前回までの記事で、Azure Functions + MySQLを使用してバックエンド部分を作成しました。
今回はそこにAzure Static Web Appsを使用したフロント部分を追加して、シンプルなWebアプリケーションとして動かすことを目指します。
フロント部分はReactを使うことにしました。
※"最低限動くもの"を目指すので、認証などのセキュリティ関連の実装は含みません

ついでに、Azure FunctionsアプリをGithubと連携して自動デプロイさせるようにします。

構成イメージ

赤くなっている部分が今回の範囲。

AzureCLI.drawio (6).png

Azure Static Web Appsでは、マネージドなFunctionsアプリ独自の(自前の)Functionsアプリの2通りの構成にできますが、既に作成済みなのと、前者はJavaに対応していないという理由で、今回は後者の構成で進めます。
Azure Functions による Azure Static Web Apps での API のサポート

前回までの記事

動作環境

作業時の環境は以下の通りです。

  • OS
    • Windows 11 Pro (21H2)
  • React 18.2.0

フロント側のアプリを作成

  1. Reactを使用してフロント側のアプリを普通に作る。
    ※作成方法はここでは扱いません
  2. 作成したアプリをGithubにpushする。
    ソースはこちら

実装時のポイント

APIのエンドポイントAPIキーは環境(開発環境・運用環境等)によって変化する可能性があるので、環境変数に持たせます。
環境変数の設定方法は後述

プログラム内で環境変数は以下のように取得できます。

// Reactの場合、変数名が"REACT_APP_"で始まる必要がある
const VARIABLE: string = process.env.REACT_APP_VARIABLE;

フロント側のアプリをAzureにデプロイ

Azure Portalで「静的Webアプリ」で検索し、作成
内容入力して、確認および作成

image.png

今回はGithubと連携させるので デプロイの詳細 > ソースGithub を選択。
ログインを求められたらログインする。

設定名 設定内容
組織 組織を選択(個人アカウントの場合はアカウント名と同じ)
リポジトリ デプロイ対象のリポジトリを選択
分岐 デプロイ対象のブランチを選択
ビルドのプリセット フレームワークを選択。今回はReact
アプリの場所 リポジトリルートから見たアプリのルードディレクトリを指定。
APIの場所 マネージドFunctionsを使用する場合は指定。今回は使用しないので空
出力先 ビルドされたファイルの出力先

作成が完了すると、GithubのリポジトリにWorkflowの設定ファイルが追加され、ビルド&デプロイが開始されます。
この設定ファイルを編集することで、ビルド設定などを調整できます。
ここでは特に変更はありません。

.github/workflows/azure-static-web-apps-xxxxxxxxxxx.yml (xxxxxxxxxxxの部分は毎回違う)
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 に環境変数を設定します。

.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 から登録します。

image.png

設定名 設定値
API_ORIGIN Azure Functionsアプリのホスト
API_KEY Azure Functionsアプリのアプリキー

※設定名はWorkflow設定ファイルの方と合っていれば何でも良い

Workflow設定ファイルの修正

登録したSecretsを参照して環境変数を設定するよう修正します。
pushすると自動的にビルド&デプロイが実行されます。楽。

.github/workflows/azure-static-web-apps-xxxxxxxxxxx.yml
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を追加します。

image.png

フロント側のURLは、静的Webアプリ > <アプリ名> > 概要 > URL で確認できます。

image.png

これで画面からAPIにアクセスできるようになりました。
(APIへのリクエストが正常に返ってきているのが確認できます)

Create-React-App-Sample-Azure-Static-Web-Apps-Demo-2022-10-29-17-55-44.gif

Functionsの自動デプロイ設定

最後に、現状Functionsアプリは手動でデプロイする必要があるため、ブランチへのpushをトリガーに自動でデプロイされるようにします。

Azure Portalで 関数アプリ > <関数アプリ名> > デプロイセンター から設定します。

image.png

ソースGithub を選択。
もしログインを求められたらログインする。
保存 ボタンで確定する。

設定名 設定内容
組織 組織を選択(個人アカウントの場合はアカウント名と同じ)
リポジトリ デプロイ対象のリポジトリを選択
ブランチ デプロイ対象のブランチを選択

保存すると、Static Web Appsと同様、GithubのリポジトリにWorkflowの設定ファイルが追加され、ビルド&デプロイが開始されます。

以上

おわりに

フロントエンドからバックエンドまでの一通りを、面倒なミドルウェアの設定も不要で、サクッと(?)構築できました。
環境面をあまり意識せずコードに集中できるのは、やはりありがたいですね。

最後までお付き合いくださり、ありがとうございました!

参考文献

10
3
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
10
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?