Azure Container Apps で最初のコンテナ化された関数を作成する
この記事では、Linux コンテナーで実行されている関数アプリを作成し、コンテナー レジストリから Azure Container Apps 環境にデプロイします。 Container Apps にデプロイすると、関数アプリをクラウドネイティブなマイクロサービスに統合できます。 詳細については、「Azure Functions の Azure Container Apps ホスティング」を参照してください。
この記事では、Linux コンテナーで実行されている関数を作成し、コンテナーを Container Apps 環境にデプロイする方法について説明します。
このクイックスタートを完了すると、お使いの Azure アカウントで数米国ドル以下の少量のコストが発生します。このコストは、完了時にリソースをクリーンアップすることによって最小限に抑えることができます。
開発言語を選択する
まず、Azure Functions ツールで、言語固有の Linux 基本イメージを使用して、Docker コンテナーに関数アプリとしてプロジェクト コードを作成します。 記事の冒頭で言語を必ず選択してください。
Core Tools では、お使いの関数言語の正しい基本イメージの最新バージョンを使用するプロジェクトの Dockerfile が自動的に生成されます。 最新の基本イメージからコンテナーを定期的に更新し、コンテナーの更新されたバージョンから再デプロイする必要があります。 詳細については、「コンテナー化された関数アプリの作成」を参照してください。
前提条件
操作を始める前に、以下の要件を満たしておく必要があります。
.NET 8.0 SDK をインストールします。
Azure Functions Core Tools バージョン 4.0.5198 以降をインストールします。
- Azure Functions Core Tools バージョン 4.x をインストールします。
- Azure Functions でサポートされているNode.js のバージョンをインストールします。
- Azure Functions でサポートされている Python のバージョンをインストールします。
- .NET 6 SDK をインストールします。
Azure Functions でサポートされているJava Developer Kit のバージョンをインストールします。
Apache Maven バージョン 3.0 以降をインストールします。
- Azure CLI バージョン 2.4 以降のバージョン。
Azure サブスクリプションをお持ちでない場合は、開始する前に Azure 無料アカウントを作成してください。
作成したコンテナー化された関数アプリ イメージをコンテナー レジストリにを発行するには、Docker ID とローカル コンピューターで実行されている Docker が必要です。 Docker ID がない場合は、Docker アカウントを作成することができます。
また、レジストリ インスタンスを作成するには、Container Registry のクイックスタートに記載の「コンテナー レジストリの作成」セクションを完了する必要があります。 完全修飾ログイン サーバー名を書き留めます。
仮想環境を作成してアクティブにする
適切なフォルダーで次のコマンドを実行し、.venv
という名前の仮想環境を作成してアクティブにします。 Azure Functions でサポートされているいずれかの Python バージョンを必ず使用してください。
python -m venv .venv
source .venv/bin/activate
お使いの Linux ディストリビューションに Python の venv パッケージがインストールされていなかった場合は、次のコマンドを実行します。
sudo apt-get install python3-venv
以降のコマンドはすべて、このアクティブ化された仮想環境で実行します
ローカル関数プロジェクトを作成してテストする
ターミナルまたはコマンド プロンプトで、自分が選択した言語に合わせて次のコマンドを実行し、現在のフォルダーに関数アプリ プロジェクトを作成します。
func init --worker-runtime dotnet-isolated --docker
func init --worker-runtime node --language javascript --docker
func init --worker-runtime powershell --docker
func init --worker-runtime python --docker
func init --worker-runtime node --language typescript --docker
空のフォルダーで次のコマンドを実行して、Maven アーキタイプから Functions プロジェクトを生成します。
mvn archetype:generate -DarchetypeGroupId=com.microsoft.azure -DarchetypeArtifactId=azure-functions-archetype -DjavaVersion=8 -Ddocker
-DjavaVersion
パラメーターは、使用する Java のバージョンを Functions Runtime に指示します。 Java 11 で関数を実行する場合は、-DjavaVersion=11
を使用します。
-DjavaVersion
を指定しない場合、Maven の既定値は Java 8 になります。 詳細については、「Java のバージョン」を参照してください。
重要
この記事の作業を行うには、JAVA_HOME
環境変数を、適切なバージョンの JDK のインストール場所に設定する必要があります。
Maven により、デプロイ時にプロジェクトの生成を終了するための値の入力が求められます。 プロンプトに従って、次の情報を指定します。
Prompt | 値 | 説明 |
---|---|---|
groupId | com.fabrikam |
Java のパッケージ命名規則に従って、すべてのプロジェクトにわたって対象のプロジェクトを一意に識別する値。 |
artifactId | fabrikam-functions |
バージョン番号のない、jar の名前である値。 |
version | 1.0-SNAPSHOT |
既定値を選択します。 |
package | com.fabrikam.functions |
生成された関数コードの Java パッケージである値。 既定値を使用します。 |
「Y
」と入力するか、Enter キーを押して確認します。
Maven により、artifactId という名前の新しいフォルダーにプロジェクト ファイルが作成されます (この例では fabrikam-functions
)。
--docker
オプションによって、プロジェクトの Dockerfile が生成されます。これにより、Azure Functions および選択されたランタイムで使用するための適切なコンテナーが定義されます。
プロジェクト フォルダーに移動します。
cd fabrikam-functions
次のコマンドを使用して、関数を自分のプロジェクトに追加します。ここで、--name
引数は関数の一意の名前で、--template
引数は関数のトリガーを指定するものです。
func new
により、お使いのプロジェクトに C# コード ファイルが作成されます。
func new --name HttpExample --template "HTTP trigger"
次のコマンドを使用して、関数を自分のプロジェクトに追加します。ここで、--name
引数は関数の一意の名前で、--template
引数は関数のトリガーを指定するものです。
func new
によって、関数と同じ名前のサブフォルダーが作成されます。このサブフォルダーには、func new
という名前の構成ファイルが含まれます。
func new --name HttpExample --template "HTTP trigger"
関数をローカルでテストするために、プロジェクト フォルダーのルートでローカルの Azure Functions ランタイム ホストを起動します。
func start
func start
npm install
npm start
mvn clean package
mvn azure-functions:run
HttpExample
エンドポイントが出力に書き込まれたのを確認したら、そのエンドポイントに移動します。 応答出力にウェルカム メッセージが表示されます。
HttpExample
エンドポイントが出力に書き込まれたのを確認した後で、http://localhost:7071/api/HttpExample?name=Functions
に移動します。
name
クエリ パラメーターに指定された値、Functions
をエコーバックする "hello" メッセージがブラウザーに表示されるはずです。
Ctrl+C (macOS の場合は Command+C) キーを押してホストを停止します。
コンテナー イメージを作成してローカルで検証する
(省略可) プロジェクト フォルダーのルートにある Dockerfile を確認します。 Dockerfile には、Linux 上で関数アプリを実行するために必要な環境が記述されています。 Azure Functions でサポートされている基本イメージの詳細な一覧については、Azure Functions 基本イメージ ページを参照してください。
ルート プロジェクト フォルダーで、docker build コマンドを実行し、名前に azurefunctionsimage
、タグに v1.0.0
を指定します。
<DOCKER_ID>
を Docker Hub アカウント ID で置換します。 このコマンドでは、コンテナーの Docker イメージがビルドされます。
docker build --tag <DOCKER_ID>/azurefunctionsimage:v1.0.0 .
コマンドが完了すると、新しいコンテナーをローカルで実行できます。
ビルドを検証するために、ローカル コンテナーで docker run コマンドを使用してイメージを実行します。この場合も、<DOCKER_ID>
は実際の Docker Hub アカウント ID に置き換え、ポート引数として -p 8080:80
を追加してください。
docker run -p 8080:80 -it <DOCKER_ID>/azurefunctionsimage:v1.0.0
イメージがローカル コンテナーで開始したら、http://localhost:8080/api/HttpExample
に移動します。そこに、前と同じ挨拶メッセージが表示されている必要があります。 作成した HTTP トリガー関数は匿名承認を使用するため、コンテナーで実行されている関数は、アクセス キーを取得しなくても呼び出すことができます。 詳細については、承認キーに関するセクションを参照してください。
イメージがローカル コンテナーで開始したら、http://localhost:8080/api/HttpExample?name=Functions
に移動します。そこに、前と同じ "hello" メッセージが表示されている必要があります。 作成した HTTP トリガー関数は匿名承認を使用するため、コンテナーで実行されている関数は、アクセス キーを取得しなくても呼び出すことができます。 詳細については、承認キーに関するセクションを参照してください。
コンテナーで関数アプリを検証したら、Ctrl+C (macOS の場合は Command+C) キーを押して実行を停止します。
コンテナー イメージをレジストリに発行する
コンテナー イメージをホスティング環境にデプロイできるようにするには、コンテナー レジストリにプッシュする必要があります。 セキュリティのベスト プラクティスとして、Azure Container Registry インスタンスを使用して、マネージド ID ベースの接続を使用することをお勧めします。 Docker Hub では共有シークレットを使って認証を行う必要があり、デプロイがより脆弱になります。
Azure Container Registry は、コンテナー イメージおよび関連アーティクルのビルド、保管、管理をするための、プライベート レジストリ サービスです。 コンテナーを Azure サービスに発行するには、プライベート レジストリ サービスを使用する必要があります。
次のコマンドを使用して、現在の Azure 資格情報でレジストリ インスタンスにサインインします。
az acr login --name <REGISTRY_NAME>
前のコマンドで、
<REGISTRY_NAME>
をご自身の Container Registry インスタンスの名前に置き換えます。次のコマンドを使用して、レジストリ ログイン サーバーの完全修飾名でイメージにタグ付けします。
docker tag <DOCKER_ID>/azurefunctionsimage:v1.0.0 <LOGIN_SERVER>/azurefunctionsimage:v1.0.0
<LOGIN_SERVER>
をレジストリ ログイン サーバーの完全修飾名に、<DOCKER_ID>
を Docker ID に置き換えます。次のコマンドを使用して、コンテナーをレジストリ インスタンスにプッシュします。
docker push <LOGIN_SERVER>/azurefunctionsimage:v1.0.0
関数用の関連 Azure リソースを作成する
コンテナーを Azure にデプロイする前に、3 つのリソースを作成する必要があります。
- リソース グループ。関連リソースの論理コンテナーです。
- ストレージ アカウント。関数についての情報 (状態など) を維持する目的で使用されます。
- Azure Container Apps 環境と Log Analytics ワークスペース。
- ユーザー割り当てマネージド ID。これにより、関数アプリが共有シークレットを使用せずに Azure リソースに安全に接続できます。 代わりに、Azure Storage アカウントと Azure Container Registry インスタンスの両方への接続は、ID を使用して Microsoft Entra 認証で行われ、このシナリオではこの方法が推奨されています。
Note
Docker Hub はマネージド ID をサポートしていません。
必要な Azure リソースを作成するには、次のコマンドを使用します:
必要に応じて、Azure にサインインします:
az login
コマンドで Azure アカウントにサインインします。 アカウントに複数のサブスクリプションが関連付けられている場合はaz account set
を使用します。次のコマンドを実行して、Azure CLI を最新バージョンに更新します。
az upgrade
Azure CLI のバージョンが最新でない場合はインストールが開始されます。 アップグレードの方法は、お使いのオペレーティング システムによって異なります。 アップグレードの完了後に続行できます。
次のコマンドを実行して、Azure Container Apps 拡張機能をアップグレードし、Container Apps に必要な名前空間を登録します。
az extension add --name containerapp --upgrade -y az provider register --namespace Microsoft.Web az provider register --namespace Microsoft.App az provider register --namespace Microsoft.OperationalInsights
AzureFunctionsContainers-rg
という名前のリソース グループを作成します。az group create --name AzureFunctionsContainers-rg --location eastus
この
az group create
コマンドは、リソース グループを米国東部リージョンに作成します。 代わりに自分の近くのリージョンを使用する場合は、az account list-locations コマンドから返された使用可能なリージョン コードを使用します。eastus
の代わりにカスタム リージョンを使用するように、後続のコマンドを変更する必要があります。ワークロード プロファイルを有効にして Azure Container App 環境を作成します。
az containerapp env create --name MyContainerappEnvironment --enable-workload-profiles --resource-group AzureFunctionsContainers-rg --location eastus
このコマンドが完了するまで数分かかることがあります。
共有キー アクセスなしで、リソース グループとリージョンに汎用ストレージ アカウントを作成します。
az storage account create --name <STORAGE_NAME> --location eastus --resource-group AzureFunctionsContainers-rg --sku Standard_LRS --allow-blob-public-access false --allow-shared-key-access false
az storage account create
コマンドは、特定のリソースへのアクセス許可が付与されている、Microsoft Entra で認証された ID を使用してのみアクセスできるストレージ アカウントを作成します。前の例の
<STORAGE_NAME>
は、適宜、Azure Storage 内で一意の名前に置き換えてください。 ストレージ名は 3 文字から 24 文字とし、小文字のみを使用する必要があります。Standard_LRS
は汎用アカウントを指定します。これは Functions でサポートされています。マネージド ID を作成し、返された
principalId
を使用して、ストレージ アカウントへのアクセス権とレジストリ インスタンスのプル アクセス許可の両方を付与します。principalId=$(az identity create --name <USER_IDENTITY_NAME> --resource-group AzureFunctionsContainers-rg --location eastus --query principalId -o tsv) acrId=$(az acr show --name <REGISTRY_NAME> --query id --output tsv) az role assignment create --assignee-object-id $principalId --assignee-principal-type ServicePrincipal --role acrpull --scope $acrId storageId=$(az storage account show --resource-group AzureFunctionsContainers-rg --name glengatestaca2 --query 'id' -o tsv) az role assignment create --assignee-object-id $principalId --assignee-principal-type ServicePrincipal --role "Storage Blob Data Owner" --scope $storageId
az identity create
コマンドはユーザー割り当てマネージド ID を作成し、az role assignment create
コマンドは必要なロールに ID を追加します。<REGISTRY_NAME>
、<USER_IDENTITY_NAME>
、<STORAGE_NAME>
を、それぞれ既存のコンテナー レジストリの名前、マネージド ID の名前、ストレージ アカウント名に置き換えます。 これで、アプリがマネージド ID を使用して、共有シークレットを使用せずにストレージ アカウントと Azure Container Registry の両方にアクセスできるようになります。
イメージを使用して Azure 上の関数アプリを作成、構成する
Azure 上の関数アプリでは、Azure Container Apps 環境で関数の実行を管理します。 このセクションでは、前のセクションの Azure リソースを使用して、Container Apps 環境のコンテナー レジストリ内のイメージから関数アプリを作成します。 また、必要な Azure Storage アカウントに、接続文字列を使用して新しい環境を構成します。
az functionapp create
コマンドを使用して、Azure Container Apps でサポートされる新しいマネージド環境に関数アプリを作成します。
az functionapp create
では、--environment
パラメーターが Container Apps 環境を指定します。
ヒント
関数アプリがレジストリ インスタンスへのマネージド ID ベースの接続を使用するように、az functionapp create
で --image
パラメーターを設定しません。
--image
をリポジトリ内のイメージの完全修飾名に設定すると、共有シークレットの資格情報がレジストリから取得され、アプリ設定に保存されます。
まず、レジストリへのプル アクセスを使用してユーザー割り当てマネージド ID の完全修飾 ID 値を取得し、次に az functionapp create
コマンドを使用して、既定のイメージを使用し、この ID を割り当てた関数アプリを作成する必要があります。
UAMI_RESOURCE_ID=$(az identity show --name $uami_name --resource-group $group --query id -o tsv)
az functionapp create --name <APP_NAME> --storage-account <STORAGE_NAME> --environment MyContainerappEnvironment --workload-profile-name "Consumption" --resource-group AzureFunctionsContainers-rg --functions-version 4 --assign-identity $UAMI_RESOURCE_ID
az functionapp create
では、--assign-identity
によってマネージド ID が新しいアプリに割り当てられます。
az functionapp create
で --image
パラメーターを設定していないため、アプリケーションはプレースホルダー イメージを使用して作成されます。
この例では、<APP_NAME>
、<STORAGE_NAME>
、<USER_IDENTITY_NAME>
を、新しい関数アプリ、ストレージ アカウント、ID の名前に置き換えます。
最後に、linuxFxVersion
のサイト設定をリポジトリ内のイメージの完全修飾名に更新する必要があります。 また、レジストリからイメージを取得するときにマネージド ID が使用されるように、acrUseManagedIdentityCreds
および acrUserManagedIdentityID
のサイト設定を更新する必要があります。
UAMI_RESOURCE_ID=$(az identity show --name <USER_IDENTITY_NAME> --resource-group AzureFunctionsContainers-rg --query id -o tsv)
az resource patch --resource-group AzureFunctionsContainers-rg --name <APP_NAME> --resource-type "Microsoft.Web/sites" --properties "{ \"siteConfig\": { \"linuxFxVersion\": \"DOCKER|<REGISTRY_NAME>.azurecr.io/azurefunctionsimage:v1.0.0\", \"acrUseManagedIdentityCreds\": true, \"acrUserManagedIdentityID\":\"$UAMI_RESOURCE_ID\", \"appSettings\": [{\"name\": \"DOCKER_REGISTRY_SERVER_URL\", \"value\": \"<REGISTRY_NAME>.azurecr.io\"}]}}"
az resource patch
コマンドは、必要なサイト設定に加えて、DOCKER_REGISTRY_SERVER_URL
のアプリ設定をレジストリ サーバーの URL に更新します。
この例では、<APP_NAME>
、<REGISTRY_NAME>
、<USER_IDENTITY_NAME>
をそれぞれ関数アプリ、コンテナー レジストリ、ID の名前に置き換えます。
--workload-profile-name "Consumption"
を指定すると、既定の Consumption
ワークロード プロファイルを使う環境にアプリが作成されます。これには、Container Apps 従量課金プランで実行する場合と同じコストがかかります。 関数アプリを初めて作成すると、レジストリから最初のイメージがプルされます。
アプリケーション設定の更新
Functions ホストが共有シークレットを使用して既定のストレージ アカウントに接続できるようにするには、AzureWebJobsStorage
接続文字列の設定を、ユーザー割り当てマネージド ID を使用してストレージ アカウントに接続する同等の設定に置き換える必要があります。
既存の
AzureWebJobsStorage
接続文字列の設定を削除します:az functionapp config appsettings delete --name <APP_NAME> --resource-group AzureFunctionsContainers-rg --setting-names AzureWebJobsStorage
az functionapp config appsettings delete コマンドは、この設定をアプリから削除します。
<APP_NAME>
をお使いの関数アプリの名前に置き換えます。既定のストレージ アカウントへのユーザー割り当てマネージド ID 接続を定義する、
AzureWebJobsStorage__
プレフィックスを持つ同等の設定を追加します:clientId=$(az identity show --name <USER_IDENTITY_NAME> --resource-group AzureFunctionsContainers-rg --query 'clientId' -o tsv) az functionapp config appsettings set --name <APP_NAME> --resource-group AzureFunctionsContainers-rg --settings AzureWebJobsStorage__accountName=<STORAGE_NAME> AzureWebJobsStorage__credential=managedidentity AzureWebJobsStorage__clientId=$clientId
この例では、
<APP_NAME>
、<USER_IDENTITY_NAME>
、<STORAGE_NAME>
をそれぞれ関数アプリ名、ID の名前、ストレージ アカウント名に置き換えます。
この時点で、関数は Container Apps 環境で実行されており、必要なアプリケーション設定が既に追加されています。 必要に応じて、Azure Functions の標準の方法で関数アプリに他の設定を追加できます。 詳細については、アプリケーション設定の使用に関する記事を参照してください。
ヒント
関数コードに続けて変更を加える場合は、コンテナーを再構築し、イメージをレジストリに再発行し、関数アプリを新しいイメージ バージョンで更新する必要があります。 詳細については、レジストリ内のイメージ更新に関するページを参照してください。
Azure 上で関数を確認する
イメージを Azure の関数アプリにデプロイしたら、HTTP 要求を通じて関数を呼び出すことができます。
次の
az functionapp function show
コマンドを実行し、新しい関数の URL を取得します。az functionapp function show --resource-group AzureFunctionsContainers-rg --name <APP_NAME> --function-name HttpExample --query invokeUrlTemplate
<APP_NAME>
をお使いの関数アプリの名前に置き換えます。
- 先ほど取得した URL を使用して
HttpExample
関数エンドポイントを呼び出し、クエリ文字列?name=Functions
を追加します。
- 先ほど取得した URL を使用して、
HttpExample
関数エンドポイントを呼び出します。
この URL にアクセスすると、この関数をローカルで実行したときと同様の出力がブラウザーに表示されるはずです。
要求の URL は次のようになります。
https://myacafunctionapp.kindtree-796af82b.eastus.azurecontainerapps.io/api/httpexample?name=functions
https://myacafunctionapp.kindtree-796af82b.eastus.azurecontainerapps.io/api/httpexample
リソースをクリーンアップする
この記事で作成したリソースを使用して、引き続き Azure 関数に取り組む場合は、それらのリソースをすべてそのままにしてかまいません。
この関数アプリのデプロイの作業が完了したら、AzureFunctionsContainers-rg
リソース グループを削除して、そのグループ内のすべてのリソースをクリーンアップします。
az group delete --name AzureFunctionsContainers-rg