Azure Functions V4(Node.js)がプレビューになったので試してみた(その2)

先週、Azure Functions V4(Node.js)がプレビューになったので試してみたが、うまく動きませんでした。

miyohide.hatenablog.com

そのまま放置しておくのもなんなので、再度試してみました。環境はUbuntu 22.04。

必要なツールを整えておきます。まずはAzure Functions Core Toolsをインストールします。

learn.microsoft.com

Node.jsもインストール。

www.digitalocean.com

JavaScriptで作成してみます。

azureuser@myVM0423:~/work$ func init LocalFunctionProj --model V4
Select a number for worker runtime:
1. dotnet
2. dotnet (isolated process)
3. node
4. python
5. powershell
6. custom
Choose option: 3
node
Select a number for language:
1. javascript
2. typescript
Choose option: 1
javascript
The new Node.js programming model is in public preview. Learn more at https://aka.ms/AzFuncNodeV4
Writing package.json
Writing .funcignore
Writing .gitignore
Writing host.json
Writing local.settings.json
Writing /home/azureuser/work/LocalFunctionProj/.vscode/extensions.json
Running 'npm install'...azureuser@myVM0423:~/work$

関数としてHttpTriggerを作成してみます。

azureuser@myVM0423:~/work$ cd LocalFunctionProj/
azureuser@myVM0423:~/work/LocalFunctionProj$ ls
host.json            node_modules       package.json
local.settings.json  package-lock.json  src
azureuser@myVM0423:~/work/LocalFunctionProj$ func new
Select a number for template:
1. Azure Blob Storage trigger
2. Azure Cosmos DB trigger
3. Durable Functions entity
4. Durable Functions orchestrator
5. Azure Event Grid trigger
6. Azure Event Hub trigger
7. HTTP trigger
8. Azure Queue Storage trigger
9. Azure Service Bus Queue trigger
10. Azure Service Bus Topic trigger
11. Timer trigger
Choose option: 7
HTTP trigger
Function name: [httpTrigger]
Creating a new file /home/azureuser/work/LocalFunctionProj/src/functions/httpTrigger.js
The function "httpTrigger" was created successfully from the "HTTP trigger" template.
azureuser@myVM0423:~/work/LocalFunctionProj$

作成されたコードは以下のようなもの。

const { app } = require('@azure/functions');

app.http('httpTrigger', {
    methods: ['GET', 'POST'],
    authLevel: 'anonymous',
    handler: async (request, context) => {
        context.log(`Http function processed request for url "${request.url}"`);

        const name = request.query.get('name') || await request.text() || 'world';

        return { body: `Hello, ${name}!` };
    }
});

準備ができたのでfunc startで起動します。無事起動して、リクエストも処理できました。

azureuser@myVM0423:~/work/LocalFunctionProj$ func start

Azure Functions Core Tools
Core Tools Version:       4.0.5095 Commit hash: N/A  (64-bit)
Function Runtime Version: 4.16.5.20396

[2023-04-23T04:17:35.246Z] Worker process started and initialized.

Functions:

    httpTrigger: [GET,POST] http://localhost:7071/api/httpTrigger

For detailed output, run func with --verbose flag.
[2023-04-23T04:17:40.151Z] Host lock lease acquired by instance ID '00000000000000000000000024EC883F'.
[2023-04-23T04:19:14.803Z] Executing 'Functions.httpTrigger' (Reason='This function was programmatically called via the host APIs.', Id=f3aa151b-c814-42af-ba3a-e13d6b2eb04c)

ただ、npm run startだと起動に失敗しました。

azureuser@myVM0423:~/work/LocalFunctionProj$ npm run start

> start
> func start

/home/azureuser/work/LocalFunctionProj/node_modules/azure-functions-core-tools/bin/func: 2: Syntax error: Unterminated quoted string
azureuser@myVM0423:~/work/LocalFunctionProj$

どうもnode_modules/azure-functions-core-tools/bin/funcが壊れているっぽいです。

azureuser@myVM0423:~/work/LocalFunctionProj$ file node_modules/azure-functions-core-tools/bin/func
node_modules/azure-functions-core-tools/bin/func: data
azureuser@myVM0423:~/work/LocalFunctionProj$

インストールしたAzure Functions Core Tools自身は正しいバイナリなのでfunc startコマンドを実行した場合はうまく動いたっぽい。

azureuser@myVM0423:~/work/LocalFunctionProj$ file /usr/lib/azure-functions-core-tools-4/func
/usr/lib/azure-functions-core-tools-4/func: ELF 64-bit LSB pie executable, x86-64, version 1 (GNU/Linux), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=3704f93fd58f42cdb7317ebaf2230e1364b356ef, for GNU/Linux 2.6.32, stripped
azureuser@myVM0423:~/work/LocalFunctionProj$

このため、package.jsonにてfuncコマンドをフルパスに設定してあげるとよさそうです。

{
  "name": "",
  "version": "1.0.0",
  "description": "",
  "main": "src/functions/*.js",
  "scripts": {
    "start": "/usr/bin/func start",
    "test": "echo \"No tests yet...\""
  },
  "dependencies": {
    "@azure/functions": "^4.0.0-alpha.1"
  },
  "devDependencies": {
    "azure-functions-core-tools": "^4.x"
  }
}

実行すると、無事動きました。

azureuser@myVM0423:~/work/LocalFunctionProj$ npm run start

> start
> /usr/bin/func start


Azure Functions Core Tools
Core Tools Version:       4.0.5095 Commit hash: N/A  (64-bit)
Function Runtime Version: 4.16.5.20396

[2023-04-23T06:00:04.702Z] Worker process started and initialized.

Functions:

    httpTrigger: [GET,POST] http://localhost:7071/api/httpTrigger

For detailed output, run func with --verbose flag.
[2023-04-23T06:00:09.581Z] Host lock lease acquired by instance ID '00000000000000000000000024EC883F'.

TypeScriptで作成した時も同様で、package.json内にてstartスクリプトで実行するfuncコマンドをフルパス指定してあげるとよさそうです。

{
  "name": "",
  "version": "1.0.0",
  "description": "",
  "main": "dist/src/functions/*.js",
  "scripts": {
    "build": "tsc",
    "watch": "tsc -w",
    "prestart": "npm run build",
    "start": "/usr/bin/func start",
    "test": "echo \"No tests yet...\""
  },
  "dependencies": {
    "@azure/functions": "^4.0.0-alpha.1"
  },
  "devDependencies": {
    "azure-functions-core-tools": "^4.x",
    "@types/node": "18.x",
    "typescript": "^4.0.0"
  }
}

実行すると、TypeScriptのコンパイルが行われた後、無事起動しました。

azureuser@myVM0423:~/work/LocalFunctionProj2$ npm run start

> prestart
> npm run build


> build
> tsc


> start
> /usr/bin/func start


Azure Functions Core Tools
Core Tools Version:       4.0.5095 Commit hash: N/A  (64-bit)
Function Runtime Version: 4.16.5.20396

[2023-04-23T06:06:30.078Z] Worker process started and initialized.

Functions:

    httpTrigger: [GET,POST] http://localhost:7071/api/httpTrigger

For detailed output, run func with --verbose flag.
[2023-04-23T06:06:34.962Z] Host lock lease acquired by instance ID '00000000000000000000000024EC883F'.

その後、ちょっと調べてみると以下のIssueが該当するっぽい。

github.com

Pull RequestがMergeされているので将来的に解決されるっぽい。