📝

Static Web Apps+Azure DevOpsでのサーバレス開発

2021/11/06に公開

はじめに

Static Web AppとAzure DevOps(Repos, Pipeline)を使ったサーバレス開発を紹介したいと思います。今回はフロントもバックエンドも言語はTypescriptに統一し、Vue3(vite)で「Hello World」が表示されるまでを流れを整理しています。

今後、ADとの認証・認可、CosmosDBやAzure Artifacts、Testの使い方なども随時公開していきます。

Static Web Appsについて

Static Web Appsとは2021年5月に発表されたサーバレス開発に特化したWebサービスです。
他のWebサービスに比べて、静的ファイル(JavascriptやHTMLなど)のストレージに特化し、認証/認可やSSLが標準装備され、Azure Functionも同環境にデプロイできます。
AWSでは、AWS Amplify+Amazon Cognito+Amazon API Gateweyが1つになった感じです。

価格は、FreeとStandardの2種類がありますが、認証・認可やIP制限を行わないのであれば、Freeプランでも十分だと思います。Standardでも約36円/日なので、AWSと比較してもかなり安いと思います。詳細はこちらを参照。

Freeプラン Standardプラン
料金 無料 $9/月
転送できるデータ容量 100G 100G+$0.2/G
カスタムドメイン 2/アプリ 5/アプリ
カスタム認証・IP制限 なし あり
ストレージ 0.5GB 2GB
Azure Function マネージド マネージドor独自
SLA なし あり
実稼働前の環境数 3 10

Azure DevOpsについて

Azure DevOpsとは2018年から提供しているAzureのCI/CDサービスです。MicrosoftがGitHubを2018年に買収し、その翌年にGitHub Actionsを発表され、AzureではGitHub ActionsとAzure DevOpsでのCI/CD連携が推奨されています。個人的にAzure DevOpsのほうが、Pipelineの記述がシンプルで使いやすいですが、GitHub Actionsに比べて、サポート外の機能(VSCode、ステージング環境の構築など)があります。

価格は、余ったサーバ1台を使って、5人以下の開発であれば、無料でCI/CDを無制限に利用できます。詳細はこちらを参照。料金計算ツールもあります。

  • 個別ライセンス(使用料によって課金)

    • Microsoft上のホストを利用する場合は、30時間/月まで無料。毎回、仮想ホストが生成される。無制限に利用したい場合、1台あたり$40/月。
    • 社内のサーバ(オンプレも可)を利用する場合は、1台まで無料。2台目以降は、1台あたり$15/月。
    • Artifacts(パッケージ管理)は、2GiBまで無料。それ以降は、1GiBあたり$2/月。
  • ユーザライセンス(組織の人数によって課金)

    • 5人までは無料。6人以上は、1人$6/月。開発者以外は無料。
    • Visual Studio Professionalサブスプリクション(1人$45/月)の保有者は無料。
    • Test Plans(1人$52/月)は手動テストのサポートツール。

Azure Function版Hello world

まずは、ローカル環境でフロントもバックエンドも言語はTypescriptで動くHello worldを作ってみたいと思います。今回は、サンプルなのでVue3を高速ビルドできるviteを使ってみます。

  1. Vueプロジェクトのテンプレートを作成する。ものすごい早いです...
> npm init vite@latest
√ Project name: ... hello-world
√ Select a framework: » vue
√ Select a variant: » vue-ts
> cd hello-world
> npm install
> npm run dev
→ 起動確認。http://localhost:3000/
  1. VS Codeを起動し、作成したフォルダを選択する。ソース整形する場合は、ここを参照。
    (拡張機能でVuturはviteに対応していないので無効にし、Volarに切り替えてください。)
  2. 拡張機能で「Azure Static Web Apps」をインストールする。
  3. [F1]で「Azure Static Web Apps: Create HTTP Function」を選択し、バックエンドを作成する。
    ・Select a language ... TypeScript
    ・Function name ... HelloWorld
  4. index.tsを以下のように書き換える。
api/HelloWorld/index.ts
import { AzureFunction, Context, HttpRequest } from "@azure/functions";

const httpTrigger: AzureFunction = async function (context: Context, req: HttpRequest): Promise<void> {
  context.res = {
    headers: {
      "Content-Type": "application/json",
    },
    body: {
      name: "Hello, " + req.query.name + ".",
    },
  };
};

export default httpTrigger;
  1. ターミナルを起動し、Azure Functionで「Hello, world.」を表示してみる。
> cd api
> npm install
> npm start
→ 起動確認。http://localhost:7071/api/HelloWorld?name=world
  1. Vue.jsとapiを連携するために、以下のように修正する。
.env.local
// VueはVUE_APPが接頭語で、process.env.VUE_APP_XXXで参照可能だったが、
// ViteはVITEが接頭語で、import.mata.env.VITE_XXXとなる。
VITE_API_URL="http://localhost:7071"
.env
// この設定がないと、デプロイ後にapiに接続できない。
VITE_API_URL=""
src/components/HelloWorld.vue
<script setup lang="ts">
// Vue3.2(2021/8リリース)で追加されたscript setup構文
// export default defineComponetやretrunが不要になり、scriptが上部に移動した。
const props = defineProps<{ name: string }>();

import { ref } from "vue";

const msg = ref();

fetch(import.meta.env.VITE_API_URL + "/api/HelloWorld?name=" + props.name)
  .then(async (response) => response.json())
  .then((data) => msg.value);
</script>

<template>
  <h1>{{ msg }}</h1>
</template>
src/components/HelloWorld.vue
<script setup lang="ts">
import HelloWorld from "./components/HelloWorld.vue";
</script>

<template>
  <HelloWorld name="Hello" />
</template>
  1. ターミナルをもう1つ開き、以下のコマンドを実行で、「Hello, world.」が表示されるか確認する。
> npm run dev
→ 起動確認。http://localhost:3000/

Webサイト構築

公式サイトに載っているVS Codeの拡張機能は、まだAzure DevOpsに対応していないため、
Azureのポータルサイトから作成していきます。アカウントを持っていない人は、無料なので作りましょう。

  1. ポータルサイトで、「静的 Web アプリ」を検索し、[作成]ボタンを押す。
  2. 以下の内容を設定し、[確認および作成]ボタンを押した後、[作成]ボタンを押す。
    ・リソースグループ ... 新規作成で、Training(作ったほうが管理しやすい)
    ・静的Webアプリの名前 ... HelloWorld
    ・ホスティングプラン ... Free
    ・ステージング環境のリージョン ... East Asia
    ・ソース ... その他
  3. 作成後、[リソースに移動]ボタンを押し、概要のURLが参照できることを確認する。
  4. [デプロイトークンの管理]から、デプロイトークンを取得する。

Azure Repos

gitでのバージョン管理サービス。まずは、作成したソースをリポジトリに登録します。Azure DevOpsにAzureのアカウントでログインして、以下の作業をしてください。

  1. [+ New Project]ボタンを押し、新規プロジェクトを作成する。
    ・Project name ... training(リポジトリのURLになるため、大文字は非推奨)
    ・Visibility ... Private
  2. 以下の手順で、HelloWorld用のリポジトリを作成する。
    (1) Reposを選択
    (2) 画面上部にあるtrainingプルダウンから、+New Repositoryを選択
    (3) Repository nameに「hello-world」を入力し、Add a READMEのチェックを外して、[Create]ボタンを押す。
    (4) [Clone in VS Code]ボタンを押し、VSCodeを起動し、出力先フォルダを選択すると、リポジトリのCloneが作成される。
  3. 先ほど作成したAzure Function版Hello worldをリポジトリに登録する。
    (1) Azure Function版Hello worldのソースを、作成したフォルダにすべてコピーする。
    (2) ソース管理で、メッセージを追加し、コミットする。
    (3) 右上の...からプッシュすると、リポジトリへの登録が完了する。

Azure Pipeline

リポジトリに保存したソースを元にビルド、デプロイを行うサービス。AWSではAWS CodePipeline。

  1. Reposのhello-worldの右上にある[Set up Build]ボタンを押す。
  2. Configure your pipelineは、Static Web Appsのテンプレートがないため、Starter pipelineを選択する。
  3. pipeline YAMLを以下のように編集する。
azure-pipelines.yml
# masterが更新されたら、実行される。
trigger:
  - master

pool:
  vmImage: ubuntu-latest

steps:
# Tasksでstaticと検索し、Deploy Azure Static Web Appsを選択し、以下を入力。
  - task: AzureStaticWebApp@0
    inputs:
      app_location: '/'
      app_build_command: 'npm run build'
      api_location: '/api'
      api_build_command: 'npm run build'
      output_location: 'dist'
      azure_static_web_apps_api_token: $(deployment_token)
  1. 右上にある[Variables]ボタンを選択し、以下の内容を登録する。
    ・Name ... deployment_token
    ・Value ... 静的 Web アプリで取得したデプロイトークンを張り付け
    ・Keep this value secret ... トークンが非表示になる。
  2. 右上にある[Save and run]ボタンを押すと、Azure Pipelineでビルド・デプロイが実行される。約1分半ほどかかる。
  3. 静的Webアプリに表示されているURLで、「Hello, world」が表示されるか確認する。
  4. ymlを修正したいときは、Pipelinesの一覧の右側にあるプルダウンメニューからEditを選択すると、編集可能。

おわりに

Static Web Appsは、AWSと比べても、利用料金も安く、Azure Fuctionとの連携もスムーズだったと思います。実は、Azureの公式サイトにも手順は公開されているのですが、Javascript版しかなく、DevOpsとの一連の流れがわかりずらかったので、今回作成してみました。

サーバレスには、今回紹介したファンクション方式とは別に、コンテナ方式もあり、2021/11に発表されたAzure Container Appsというサービスあるので、そちらとの違いも検証してみたいなと思います。

Discussion