0
2

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 3 years have passed since last update.

Azure Functionsを用いたサーバーレスなTwitter botを開発してみた(その1、環境構築でPowerShellの実行ポリシーではまったお話)

Last updated at Posted at 2021-06-13

このページの目的

Azure Functionsの開発をするための開発環境をWindows 10PC上に構築します。このページで構築した後にTwitter botサービスを作る予定です。

簡単に環境構築できると思ったのですが、PowerShellスクリプトのポリシーですごくはまったので記事を書きました。

開発環境

開発PCの環境

  • Windows ホストPC
    • エディション:Windows 10 Home
    • バージョン:20H2
    • OS ビルド:19042.867
    • エクスペリエンス:Windows Feature Experience Pack 120.2212.551.0

Azure Functions開発のための環境

初めてAzure Functionsの開発をする場合はこちらのページを参考に環境を構築します。

必要なのは次の通りです。(上記のリンクから抜粋)

  • アクティブなサブスクリプションが含まれる Azure アカウント。
  • Azure Functions Core Tools バージョン 3.x。
  • Azure Functions でサポートされているバージョンの Python
  • サポートされているプラットフォームのいずれかにインストールされた Visual Studio Code。
  • Visual Studio Code 用の Python 拡張機能。
  • Visual Studio Code 用 Azure Functions 拡張機能。

Azure Functionプロジェクトの作成

テンプレート・プロジェクトの作成

前節で紹介した公式ページの「ローカル プロジェクトを作成する」節を参考にしてテンプレートのプロジェクトを作成します。

上記のページではHTTPトリガーのAzure Functionsプロジェクトを作る例が書かれていますが、今回はTimerTriggerのプロジェクトを作成します。cornの設定はこちらのページを参照してください。

関数名は「TimerTriggerTweet」にしました。

プロジェクトの中身

テンプレートから作成したAzure Functionsプロジェクトのフォルダ・ファイルを抜粋します。(venvのincludeやLibは多くのフォルダ・ファイルがあるため省略しています。)

SIMPLE-TWITTER-BOT
│  .funcignore
│  .gitignore
│  host.json
│  local.settings.json
│  proxies.json
│  requirements.txt
│  
├─.venv
│  ├─Include
│  ├─Lib
│  │  └─site-packages
│  │      ├─azure
│  │      ├─azure_functions-1.7.0.dist-info
│  │      └─pip
│  └─Scripts
│          activate
│          activate.bat
│          Activate.ps1
│          deactivate.bat
│          easy_install-3.7.exe
│          easy_install.exe
│          pip.exe
│          pip3.7.exe
│          pip3.exe
│          python.exe
│          pythonw.exe
├─.vscode
│      extensions.json
│      launch.json
│      settings.json
│      tasks.json
│      
└─TimerTriggerTweet
       function.json
       readme.md
       sample.dat
       __init__.py
       

プロジェクトのルート

Azure Functions全体の設定ファイルが保存されています。簡単にファイルの意味をまとめます。

ファイル名 概要
.funcignore
.gitignore Gitリポジトリにコミットしないファイルを記述
host.json Azure Functionsの設定
local.settings.json ローカル実行するときの設定
proxies.json プロキシサーバー(L7 ファイヤーフォール)の設定
requirements.txt 動作させるのに必要なPythonパッケージを記述

.venv

Pythonの仮想環境venvフォルダ。ホストにpipコマンドでモジュールをインストールするとすべてのPythonスクリプトで共用することになりますが、プロジェクトごとにvenvで仮想的な実行環境を構築すると、プロジェクトごとに必要なモジュールが明確になります。また、モジュールのバージョンも指定できるので他の環境にPythonスクリプトをデプロイするのが楽になります。

Azure Functionsではローカルの開発環境とAzureの実行環境をそろえるためにデフォルトでvenvを使っているのだと思います。

.vscode

Visual Studio Codeプロジェクトの設定ファイルの保存場所。

ローカルでデバッグ実行

公式ページの「関数をローカルで実行する」を試します。

セキュリティーエラー発生

当方の環境では次のエラーが発生して実行できませんでした。

> Executing task: .venv\Scripts\python -m pip install -r requirements.txt <

Requirement already satisfied: azure-functions in \simple-twitter-bot\.venv\lib\site-packages (from -r requirements.txt (line 5)) (1.7.0)
WARNING: You are using pip version 20.1.1; however, version 21.1.1 is available.
You should consider upgrading via the 'simple-twitter-bot\.venv\Scripts\python.exe -m pip install --upgrade pip' command.

Terminal will be reused by tasks, press any key to close it.

> Executing task: .venv\Scripts\activate ; func host start <

.venv\Scripts\activate : このシステムではスクリプトの実行が無効になっているため、ファイル simple-twitter-bot\.venv\Scripts\Activate.ps1 を読み込むことができません。
詳細については、「about_Execution_Policies」(https://go.microsoft.com/fwlink/?LinkID=135170) を参照してください。
発生場所 行:1 文字:1
+ .venv\Scripts\activate ; func host start
+ ~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : セキュリティ エラー: (: ) []、PSSecurityException
    + FullyQualifiedErrorId : UnauthorizedAccess
Found Python version 3.7.9 (python3).

Azure Functions Core Tools
Core Tools Version:       3.0.3477 Commit hash: 5fbb9a76fc00e4168f2cc90d6ff0afe5373afc6d  (64-bit)
Function Runtime Version: 3.0.15584.0

[2021-05-16T06:15:46.376Z] File 'C:\Program Files\dotnet\dotnet.exe' is not found, 'dotnet' invocation will rely on the PATH environment variable.
[2021-05-16T06:16:00.802Z] File 'C:\Program Files\dotnet\dotnet.exe' is not found, 'dotnet' invocation will rely on the PATH environment variable.
[2021-05-16T06:16:01.231Z] File 'C:\Program Files\dotnet\dotnet.exe' is not found, 'dotnet' invocation will rely on the PATH environment variable.

Functions:

        TimerTriggerTweet: timerTrigger

For detailed output, run func with --verbose flag.
[2021-05-16T06:16:06.376Z] Worker process started and initialized.

PSSecurityExceptionエラーの原因

Visual Studio CodeのTerminalはWindows版ではPower Shellが使われています。Azure Functionsのデバッグ環境を立ち上げるとまず、venvが起動します。venvの起動は.venv/Scripts/Activate.ps1というPower Shellスクリプトを実行することで行われますが、Power Shellのスクリプト実行ポリシーがスクリプトの実行を許可していないためエラーになっているようです。

私の環境のPower Shellスクリプトの実行ポリシーをGet-ExecutionPolicyコマンド(-Listオプション付き)で調べたところすべてのポリシーがUndifinedになっていました。

PS > Get-ExecutionPolicy -List

        Scope ExecutionPolicy
        ----- ---------------
MachinePolicy       Undefined
   UserPolicy       Undefined
      Process       Undefined
  CurrentUser       Undefined
 LocalMachine       Undefined


PS >

UndefinedはMicrosoftのドキュメントによると現在のスコープには実行ポリシーが設定されていません。すべてのスコープの実行ポリシーがの場合 Undefined 、有効な実行ポリシーは windows クライアントの場合は、 Restricted windows Server の場合は RemoteSigned です。とのことです。

実行ポリシーには優先度があり、先ほどのリンクによると次の順番とのことです。上のほうが優先度が高いようです。

Group Policy: MachinePolicy
Group Policy: UserPolicy
Execution Policy: Process (or pwsh.exe -ExecutionPolicy)
Execution Policy: CurrentUser
Execution Policy: LocalMachine

Get-ExecutionPolicyコマンドを-Listオプションなしで実行すると現在適用されるポリシーを表示してくれます。試したところ、Restrictedになっていました。

PS > Get-ExecutionPolicy      
Restricted
PS >

私のホストはWindows 10なのでRestrictedと同様の実行ポリシーになっているようです。上記のページから抜粋するとWindows クライアントコンピューターの既定の実行ポリシー。個々のコマンドを許可しますが、スクリプトは許可しません。書式設定ファイル、構成ファイル () .ps1xml 、モジュールスクリプトファイル ()、PowerShell プロファイル () など、すべてのスクリプトファイルの実行を禁止 .psm1 .ps1 します。のようです。エラーになるわけです。

PSSecurityExceptionエラーの解決

Set-ExecutionPolicyコマンドでポリシーを変えればいいのですが、それは最後の手段だと思います。アクセス権は必要最低限のスコープに対して設定すべきです。この場合の必要最低限はVisual Studio Codeが実行するAzure Functionsプロジェクトのデバッグ実行ができること、なので実行ポリシーのスコープはProcessにすることが望ましいです。設定するポリシーはRemoteSignedにします。これはWindows serverの規定なので今回はこれにしましたが、読者さんの環境に応じたポリシーを設定してください。

実行ポリシーのスコープProcessに対してRemoteSignedポリシーを設定するには次のコマンドを実行するとよいようです。

PS > Set-ExecutionPolicy -Scope Process -ExecutionPolicy RemoteSigned

今回はVSCodeからの実行でVisual Studio Code 用 Azure Functions 拡張機能が起動し、機能拡張がvenvのactivate psスクリプトをキックしていると考えられます。ですのでこのコマンドをVSCodeのターミナルからたたいてもスコープがそのターミナルに閉じられてしまします。

先ほどのMicrosoftの公式ページによると、スコープは、 Process 現在の PowerShell セッションにのみ影響します。 実行ポリシーは、レジストリではなく、環境変数に保存され $env:PSExecutionPolicyPreference ます。とあります。日本語がおかしいのでわかりにくいですがProcessスコープのポリシーは環境変数PSExecutionPolicyPreferenceに書き込まれるようです。そのため、今回はVSCodeのsettings.jsonに次の設定を記述することにしました。(settings.json.vscode/settings.jsonに保存されています。)

  "terminal.integrated.env.windows": {
    "PSExecutionPolicyPreference": "RemoteSigned"
  }

これはVSCodeでvenvを使うときによくある設定のようです。このsettings.jsonはVSCodeが起動するときに読み込まれるので、この記述をした場合は一度VSCodeを終了してから再度起動してください。(僕はこれにめちゃくちゃはまりました(´・ω・`))

ローカルでデバッグ実行成功

VSCodeを再起動したら無事起動できました。

> Executing task: .venv\Scripts\python -m pip install -r requirements.txt <

Requirement already satisfied: azure-functions in simple-twitter-bot\.venv\lib\site-packages (from -r requirements.txt (line 5)) (1.7.0)
WARNING: You are using pip version 20.1.1; however, version 21.1.2 is available.
You should consider upgrading via the 'simple-twitter-bot\.venv\Scripts\python.exe -m pip install --upgrade pip' command.

Terminal will be reused by tasks, press any key to close it.

> Executing task: .venv\Scripts\activate ; func host start <

Found Python version 3.7.9 (python3).

Azure Functions Core Tools
Core Tools Version:       3.0.3477 Commit hash: 5fbb9a76fc00e4168f2cc90d6ff0afe5373afc6d  (64-bit)
Function Runtime Version: 3.0.15584.0

[2021-06-13T15:25:45.582Z] File 'C:\Program Files\dotnet\dotnet.exe' is not found, 'dotnet' invocation will rely on the PATH environment variable.
[2021-06-13T15:25:46.423Z] File 'C:\Program Files\dotnet\dotnet.exe' is not found, 'dotnet' invocation will rely on the PATH environment variable.
[2021-06-13T15:25:46.632Z] File 'C:\Program Files\dotnet\dotnet.exe' is not found, 'dotnet' invocation will rely on the PATH environment variable.

Functions:

        TimerTriggerTweet: timerTrigger

For detailed output, run func with --verbose flag.
[2021-06-13T15:25:48.910Z] Worker process started and initialized.

ローカル実行のシーケンスを想像する

最初に、.vscode/tasks.jsonが実行されます。pythonのpipコマンドを使って仮想環境venvに対して必要なライブラリをインストールするようです。必要なライブラリはプロジェクトルートにあるrequirements.txtに記述するようです。デフォルトではazure-functionsをインストールするようです。

まとめ

もともとはTwitter botサービスを作る、という趣旨で記事を書いていたのを無理やりタイトル変えたのでおかしいところがあればご指摘ください。次回からいよいよサーバレスアーキテクチャによるサービス開始を開始します。

0
2
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
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?