1. はじめに
1-1 ご挨拶
初めまして、井村と申します。
普段はインフラを担当していますが、開発の知識も必要だと感じる場面が増えてきました。
本記事は、前回の「ローカル環境構築編」の続きです。
今回は、Azure Functionsの基本構造の理解とAzureへのデプロイを、Copilotの支援を受けながら進めました。
作業手順を備忘録として残しておきます。
1-2 本記事の要約
1 . 本記事は以下テーブルの内容を記事にしました。
| ステップ | 状況 |
|---|---|
| Function App の構造理解 | ✅ 完了 |
| トリガー・バインディングの理解 | ✅ 完了 |
| Azure Functions の定義確認 | ✅ 完了 |
| Azure 上へのデプロイ(Bicep + CLI) | ✅ 完了 |
| Function Key の理解とアクセス確認 | ✅ 完了 |
2 . Azure Functions の構造理解(What / Why)
| 項目 | What(何か) | Why(なぜ必要か) |
|---|---|---|
| Function App | 複数の関数を含むアプリ単位 | ローカルとAzureで構造が共通 |
| トリガー | 関数を起動するイベント | イベントドリブンな処理が可能 |
| バインディング | 外部サービスとの連携設定 | コードを簡潔に保てる |
__init__.py |
関数ロジックを記述 | Pythonで処理を定義 |
function.json |
トリガー・バインディング設定 | Azureランタイムが認識するため |
3 . Azureへのデプロイ(Bicep + CLI)
Azureリソースデプロイ用Bicepテンプレート
クリック展開
@description('作成するシステム名を指定します。')
param systemName string = 'demo'
@description('リソースグループのロケーション。今回は東日本リージョン (Japan East) を指定します。')
param location string = 'japaneast'
@description('環境を指定します。dev, stg, pro のいずれかを選択してください。')
@allowed([
'dev'
'stg'
'pro'
])
param env string = 'dev'
@description('ランダムなサフィックスを生成します。')
param random string = newGuid()
var randomSuffix = toLower(substring(random, 0, 5)) // GUIDの先頭5文字を小文字で取得
@description('Functionsの名前。')
var funcName = 'func-${systemName}-${env}-${randomSuffix}'
@description('ストレージアカウントの名前。')
var stName = toLower('st${systemName}${env}${randomSuffix}')
@description('App Serviceプランの名前。')
var appServicePlanName = 'asp-${systemName}-${env}-${randomSuffix}'
@description('ストレージアカウントの接続文字列。')
var storageConnectionString = 'DefaultEndpointsProtocol=https;AccountName=${storageAccount.name};AccountKey=${listKeys(storageAccount.id, storageAccount.apiVersion).keys[0].value};EndpointSuffix=core.windows.net'
@description('ストレージアカウントを作成します。')
resource storageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' = {
name: stName
location: location
sku: {
name: 'Standard_LRS'
}
kind: 'StorageV2'
properties: {
accessTier: 'Hot'
supportsHttpsTrafficOnly: true
}
}
@description('App Serviceプランを作成します。')
resource appServicePlan 'Microsoft.Web/serverfarms@2022-03-01' = {
name: appServicePlanName
location: location
sku: {
name: 'B1'
tier: 'Basic'
}
properties: {
reserved: true // Windowsの場合はfalse、Linuxの場合はtrue
}
}
@description('Azure Functionsを作成します。')
resource functionApp 'Microsoft.Web/sites@2022-03-01' = {
name: funcName
location: location
kind: 'functionapp,linux'
properties: {
serverFarmId: appServicePlan.id
siteConfig: {
linuxFxVersion: 'PYTHON|3.12' // 使用するランタイムに応じて変更(例:NODE|14, DOTNET|6など)
appSettings: [
{
name: 'AzureWebJobsStorage'
value: storageConnectionString
}
{
name: 'FUNCTIONS_EXTENSION_VERSION'
value: '~4'
}
{
name: 'FUNCTIONS_WORKER_RUNTIME'
value: 'python' // 使用するランタイムに応じて変更(例:node, python, dotnetなど)
}
{
name: 'WEBSITE_RUN_FROM_PACKAGE'
value: '1'
}
]
}
httpsOnly: true
}
}
実行コマンド
az login
az group create --name rg-demo-dev --location japaneast
az deployment group create --template-file main.bicep --resource-group rg-demo-dev
az resource list --resource-group rg-demo-dev --output table
4 . ローカル関数のデプロイと確認
func azure functionapp publish <AzureにデプロイされたFunctions名>
Azure Portalでの確認
- 関数
HttpExampleが表示されている - 関数のURLにアクセスしてレスポンス確認
https://func-demo-dev-503d5.azurewebsites.net/api/HttpExample?code=<your-function-key>&name=井村
Hello, 井村. This HTTP triggered function executed successfully.
5 . Function Key の理解と注意点
| キー種別 | 用途 |
|---|---|
| Function Key | 特定関数へのアクセス |
| Host Key | Function App 全体へのアクセス |
| Master Key | 管理APIへのアクセス |
authLevel: "function" の場合はキーが必要。
"anonymous" に変更すると誰でもアクセス可能ですが、セキュリティには注意!
2. Coplotとのやりとり
ここからはCopilotとのやりとりになります。
2.1 井村からCopilotへの質問
ステップ1開発環境の準備は終了しました。
次は以下について教えてください。
ステップ 2: Azure Functions の基本理解
Function App の構造
トリガー(HTTP, Timer, Blob, Queue など)
入出力バインディング(Storage, Cosmos DB, Service Bus など)
Python での関数定義
__init__.py に関数ロジック
function.json にトリガー・バインディング定義
2.2 Copilotから井村への回答
素晴らしい進め方です、井村さん!
ここでは「ステップ 2: Azure Functions の基本理解」について、以下の 5 つの観点から丁寧に解説します。
---
🧱 1. Function App の構造(全体像)
🔹 What(何か)
Azure Functions のプロジェクトは、1つの Function App に複数の関数(Function)を含む構成です。
azure-functions-python/
├── HttpExample/ ← 関数ごとのフォルダ
│ ├── __init__.py ← 関数のロジック
│ └── function.json ← トリガーやバインディングの定義
├── host.json ← Function App 全体の設定
├── local.settings.json ← ローカル実行用の環境変数
├── requirements.txt ← Python ライブラリの依存関係
└── .vscode/ ← VS Code の設定(自動生成)
🔹 Why(なぜ必要か)
- 関数ごとに独立した設定とロジックを持てるため、拡張性が高い
- Azure 上でもこの構造がそのまま使われるため、ローカルと本番の差異が少ない
⚡ 2. トリガー(Trigger)
🔹 What(何か)
関数をいつ・どのように実行するかを決める仕組みです。代表的なトリガー:
| トリガー種別 | 説明 |
|--------------|------|
| HTTP Trigger | HTTP リクエストで関数を実行(APIとして使える) |
| Timer Trigger | cron 式で定期実行(バッチ処理など) |
| Blob Trigger | Blob Storage にファイルが追加されたとき |
| Queue Trigger | Queue Storage にメッセージが追加されたとき |
🔹 Why(なぜ必要か)
- イベントドリブンな処理を簡単に実装できる
- サーバレスの利点(必要なときだけ実行)を最大限活かせる
🔄 3. 入出力バインディング(Bindings)
🔹 What(何か)
関数が外部サービスとやり取りするための仕組みです。コード内で明示的に書かなくても、設定ファイルで連携できます。
| バインディング種別 | 説明 |
|--------------------|------|
| Input Binding | 関数が読み取るデータ(例:Blob, Cosmos DB) |
| Output Binding | 関数が書き込むデータ(例:Queue, Table, Blob) |
🔹 Why(なぜ必要か)
- コードをシンプルに保ちつつ、Azure サービスと連携できる
- 例えば「HTTP リクエスト → Cosmos DB に保存」などが簡単に実現可能
🐍 4. Python での関数定義
🔹 What(何か)
関数のロジックは `__init__.py` に Python で記述します。以下は HTTP トリガーの例:
## python
import azure.functions as func
def main(req: func.HttpRequest) -> func.HttpResponse:
name = req.params.get('name')
return func.HttpResponse(f"Hello, {name}!")
##
🔹 Why(なぜ必要か)
- Python の標準的な構文で記述できるため、学習コストが低い
- Azure Functions SDK(`azure-functions`)が提供する型を使って、トリガーやレスポンスを扱える
🧾 5. function.json の役割
🔹 What(何か)
関数のトリガーやバインディングの設定を記述する JSON ファイルです。例:
##json
{
"bindings": [
{
"authLevel": "function",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": ["get", "post"]
},
{
"type": "http",
"direction": "out",
"name": "$return"
}
]
}
🔹 Why(なぜ必要か)
- Azure Functions ランタイムが関数の入出力を認識するために必要
- Python コードとは独立して設定できるため、柔軟性が高い
📌 まとめ図(構成イメージ)
Function App
├── Function A (HTTP Trigger)
│ ├── __init__.py
│ └── function.json
├── Function B (Timer Trigger)
│ ├── __init__.py
│ └── function.json
├── host.json
├── local.settings.json
└── requirements.txt
Functions の構造と仕組みがしっかり理解できたと思います。
次は「Timer Trigger を追加してみる」や「Blob Storage と連携してみる」など、
実践的なトリガーやバインディングを試してみるのもおすすめです。
どの方向に進めてみたいですか?それとも、ここまでの内容を図解付きで
まとめてみましょうか?
2.3 井村からCopilotへの質問
図解まとめてほしい。
2.4 Copilotから井村への回答
📝 図のポイント解説
🔹 Function App 全体構成
- Function App:Azure 上での実行単位(1つのアプリに複数の関数を含む)
- host.json:アプリ全体の設定
- local.settings.json:ローカル実行用の環境変数(Azure にはデプロイされない)
🔹 各関数の構成
- __init__.py:関数のロジック(Python)
- function.json:トリガーやバインディングの設定(JSON)
🔹 トリガーとバインディング
- Trigger:関数を起動するイベント(HTTP, Timer, Blob など)
- Input Binding:外部データの読み取り(例:Blob, Cosmos DB)
- Output Binding:外部サービスへの出力(例:Queue, Table)
ここからは前回ローカル端末で作成したアプリケーションをAzure上にデプロイします。Azure上には先にAzureFunctionsおよび必須サービスをBicepテンプレートを使いデプロイします。
main.bicep
@description('作成するシステム名を指定します。')
param systemName string = 'demo'
@description('リソースグループのロケーション。今回は東日本リージョン (Japan East) を指定します。')
param location string = 'japaneast'
@description('環境を指定します。dev, stg, pro のいずれかを選択してください。')
@allowed([
'dev'
'stg'
'pro'
])
param env string = 'dev'
@description('ランダムなサフィックスを生成します。')
param random string = newGuid()
var randomSuffix = toLower(substring(random, 0, 5)) // GUIDの先頭5文字を小文字で取得
@description('Functionsの名前。')
var funcName = 'func-${systemName}-${env}-${randomSuffix}'
@description('ストレージアカウントの名前。')
var stName = toLower('st${systemName}${env}${randomSuffix}')
@description('App Serviceプランの名前。')
var appServicePlanName = 'asp-${systemName}-${env}-${randomSuffix}'
@description('ストレージアカウントの接続文字列。')
var storageConnectionString = 'DefaultEndpointsProtocol=https;AccountName=${storageAccount.name};AccountKey=${listKeys(storageAccount.id, storageAccount.apiVersion).keys[0].value};EndpointSuffix=core.windows.net'
@description('ストレージアカウントを作成します。')
resource storageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' = {
name: stName
location: location
sku: {
name: 'Standard_LRS'
}
kind: 'StorageV2'
properties: {
accessTier: 'Hot'
supportsHttpsTrafficOnly: true
}
}
@description('App Serviceプランを作成します。')
resource appServicePlan 'Microsoft.Web/serverfarms@2022-03-01' = {
name: appServicePlanName
location: location
sku: {
name: 'B1'
tier: 'Basic'
}
properties: {
reserved: true // Windowsの場合はfalse、Linuxの場合はtrue
}
}
@description('Azure Functionsを作成します。')
resource functionApp 'Microsoft.Web/sites@2022-03-01' = {
name: funcName
location: location
kind: 'functionapp,linux'
properties: {
serverFarmId: appServicePlan.id
siteConfig: {
linuxFxVersion: 'PYTHON|3.12' // 使用するランタイムに応じて変更(例:NODE|14, DOTNET|6など)
appSettings: [
{
name: 'AzureWebJobsStorage'
value: storageConnectionString
}
{
name: 'FUNCTIONS_EXTENSION_VERSION'
value: '~4'
}
{
name: 'FUNCTIONS_WORKER_RUNTIME'
value: 'python' // 使用するランタイムに応じて変更(例:node, python, dotnetなど)
}
{
name: 'WEBSITE_RUN_FROM_PACKAGE'
value: '1'
}
]
}
httpsOnly: true
}
}
# Azureへログイン
az login
# リソースグループの作成
az group create --name rg-demo-dev --location japaneast
# リソースのデプロイ
az deployment group create --template-file main.bicep --resource-group rg-demo-dev
# リソースの確認
az resource list --resource-group rg-demo-dev --output table
2.5 井村からCopilotへの質問
ローカルで作成したAzure FunctionsをAzure上にデプロイしたい。
PS C:\Users\user\Desktop\functions_work> dir .\azure-functions-python\
Directory: C:\Users\user\Desktop\functions_work\azure-functions-python
Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 2025/08/29 15:53 __pycache__
d---- 2025/08/29 15:53 .venv
d---- 2025/08/29 15:53 .vscode
-a--- 2025/08/29 10:30 2 .funcignore
-a--- 2025/08/29 10:30 517 .gitignore
-a--- 2025/08/29 10:47 879 function_app.py
-a--- 2025/08/29 10:30 302 host.json
-a--- 2025/08/29 10:30 149 local.settings.json
-a--- 2025/08/29 10:30 147 requirements.txt
PS C:\Users\user\Desktop\functions_work>
PS C:\Users\user\Desktop\functions_work> az resource list --resource-group rg-demo-dev --output table
Name ResourceGroup Location Type Status
------------------- --------------- ---------- --------------------------------- --------
asp-demo-dev-503d5 rg-demo-dev japaneast Microsoft.Web/serverFarms
stdemodev503d5 rg-demo-dev japaneast Microsoft.Storage/storageAccounts
func-demo-dev-503d5 rg-demo-dev japaneast Microsoft.Web/sites
PS C:\Users\user\Desktop\functions_work>
2.6 Copilotから井村への回答
ありがとうございます!Azure 上にすでに Function App(`func-demo-dev-503d5`)と
ストレージアカウント(`stdemodev503d5`)があるので、ローカルの Azure Functions プロジェクト
をこの Function App にデプロイする準備は整っています。
---
🚀 デプロイ手順(既存の Function App に対して)
✅ ステップ 1: Azure CLI でログイン(未ログインの場合)
## bash
az login
##
---
✅ ステップ 2: デプロイ実行
以下のコマンドを、ローカルのプロジェクトフォルダ(`azure-functions-python`)内で実行してください:
## bash
func azure functionapp publish func-demo-dev-503d5
##
> 🔹 `func-demo-dev-503d5` は既存の Function App 名です。
> 🔹 `requirements.txt` に記載されたライブラリが Azure 上にインストールされます。
---
✅ ステップ 3: デプロイ後の確認
1. Azure Portal にアクセス
2. `func-demo-dev-503d5` の Function App を開く
3. 「関数」メニューから `HttpExample` が表示されているか確認
4. 「コード + テスト」で関数の内容を確認
5. 「関数の URL」をコピーして、ブラウザや curl でアクセス
---
🧾 補足
- `local.settings.json` はデプロイされません。Azure 上の「アプリケーション設定」に環境変数を手動で追加する必要があります。
- `.venv` フォルダもアップロードされません。代わりに `requirements.txt` が使われます。
---
上記を試してみます。
# ディレクトリ移動(host.json)
S C:\Users\user\Desktop\functions_work> cd .\azure-functions-python\
PS C:\Users\user\Desktop\functions_work\azure-functions-python> ls
Directory: C:\Users\user\Desktop\functions_work\azure-functions-python
Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 2025/08/29 15:53 __pycache__
d---- 2025/08/29 15:53 .venv
d---- 2025/08/29 15:53 .vscode
-a--- 2025/08/29 10:30 2 .funcignore
-a--- 2025/08/29 10:30 517 .gitignore
-a--- 2025/08/29 10:47 879 function_app.py
-a--- 2025/08/29 10:30 302 host.json
-a--- 2025/08/29 10:30 149 local.settings.json
-a--- 2025/08/29 10:30 147 requirements.txt
PS C:\Users\user\Desktop\functions_work\azure-functions-python> func azure functionapp publish func-demo-dev-503d5
Getting site publishing info...
~省略~
Deployment successful. deployer = Push-Deployer deploymentPath = Functions App ZipDeploy. Extract zip. Remote build.
Remote build succeeded!
PS C:\Users\user\Desktop\functions_work\azure-functions-python>
上記の URL をブラウザに貼り付けてアクセスします。
https://func-demo-dev-503d5.azurewebsites.net/api/HttpExample?code=<your-function-key>&name=井村
無事にアクセスすることができました。
以下は、調査を通じて得た知識のまとめです。
Azure Functions では、関数のセキュリティを保つために 「キー(Keys)」
を使ってアクセス制御を行います。主に以下の3種類があります:
---
🔐 Azure Functions のキーの種類
| 種類 | 説明 | 用途 |
|------|------|------|
| Function Key | 特定の関数にアクセスするためのキー | 個別の関数を呼び出すときに使用 |
| Host Key | Function App 全体の関数にアクセスできるキー | 複数の関数をまとめて管理したいとき |
| Master Key | 管理者レベルのアクセス権限を持つキー | 管理 API(ログ取得など)にアクセスする際に使用 |
---
🧭 どのキーがいつ必要?
- HTTP Trigger 関数の `authLevel` が `function` の場合、Function Key または Host Key が必要です。
- `authLevel` が `anonymous` の場合、キーは不要で誰でもアクセスできます。
- Azure Portal の「テスト/実行」機能では、Function Key を自動で付与してリクエストを送っています。
---
🔍 キーの確認方法(Azure Portal)
1. Azure Portal で Function App を開く
2. 左メニューの「関数」→ 対象の関数(例:`HttpExample`)を選択
3. 上部の「関数の URL を取得」をクリック
4. 表示された URL に `?code=xxxxxxxx` が付いていれば、それが Function Key です
---
✅ 例:Function Key 付きの URL
## text
https://func-demo-dev-503d5.azurewebsites.net/api/HttpExample?code=XXXXXXXXXXXXXXXXXXXX
##
この URL にアクセスすれば、認証レベルが `function` の関数にもアクセスできます。
---
✍️ 補足:authLevel の変更
関数の `function.json` を編集すれば、認証レベルを変更できます:
## json
{
"bindings": [
{
"authLevel": "anonymous", // ← ここを変更
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": ["get", "post"]
},
{
"type": "http",
"direction": "out",
"name": "$return"
}
]
}
##
> `anonymous` にすると誰でもアクセスできるようになりますが、セキュリティには注意が必要です。
🔒 Function Key や Master Key は公開しない方が安全です。
---
❗ なぜキーを公開してはいけないのか?
🔐 Function Key の役割
- `authLevel: "function"` の関数にアクセスするための「パスワード」のようなものです。
- このキーを知っていれば、誰でも関数を実行できてしまいます。
🛡️ 公開するとどうなる?
- 意図しない第三者が関数を実行し、不正アクセスやリソース消費の原因になります。
- 特にTimer Trigger や Blob Trigger などと連携している場合、外部からの操作で予期せぬ動作が起こる可能性もあります。
---
🧼 もし誤って公開してしまったら?
1. Azure Portal で Function App を開く
2. 「関数」→ 対象関数 → 「関数キー」タブを開く
3. キーを削除 or 再生成する
3. 終わりに
ここまで読んでくださって、ありがとうございました。
Copilotとのやりとりを通じて、Azure Functions の構造理解からデプロイまで一通り学ぶことができました。
次は、Timer Trigger や Blob Trigger の実装、CI/CDの構築にも挑戦してみたいと思います。




