Azure DevOpsパイプラインをCI/CDパイプラインとして使用している場合、ビルドやリリースで動的に設定値を管理する必要がある状況に遭遇することでしょう。PowerShellスクリプトにビルドバージョンを提供したり、ビルドタスクに動的なパラメータを渡したり、ビルドとリリース全般で文字列を使用する際には、変数が必要です。
次のような疑問を抱いたことがあるかもしれません:
- Azure DevOpsビルドパイプラインの変数をPowerShellスクリプトでどのように使用するのか?
- ビルドとリリースで変数を共有する方法は?
- 事前定義、ユーザー定義、シークレット変数の違いは?
- 変数グループはどのように機能するのか?
…そんな疑問にお答えします!この記事では、これらの疑問について詳しく説明します。
この記事の最後には、Azure DevOpsビルド変数がAzureパイプラインでどのように機能するかが理解できるようになるでしょう!
Azure DevOpsパイプライン変数とは何ですか?
変数の具体的な内容に入る前に、変数とは何であり、どのようにビルドとリリースパイプラインの効率的な構築と自動化に役立つのでしょうか?
変数を使用することで、パイプラインのさまざまな部分にデータを渡すことができます。変数は、パイプラインのワークフロー全体で変更される可能性のあるテキストや数字を保存するのに適しています。パイプラインでは、スクリプトやYAML定義に値をハードコーディングする代わりに、ほぼすべての場所で変数を設定および読み取ることができます。
注意:この記事では、YAMLパイプラインのみに焦点を当てます。旧来のクラシックパイプラインに関する情報はカバーしません。また、いくつかの例外を除いて、ウェブUIを介して変数を操作する方法については学びません。厳密にYAMLに限定します。
変数は実行時に参照され、一部は定義されます(ユーザー定義変数を参照)。パイプラインがジョブを開始すると、さまざまなプロセスがこれらの変数を管理し、その値をシステムの他の部分に渡します。このシステムにより、ビルド定義やスクリプトを変更する必要なく、パイプラインジョブを動的に実行する方法が提供されます。
この時点で変数の概念が理解できなくても心配ありません。この記事の残りの部分で必要なすべてを学ぶことができます。
変数の環境
変数自体に入る前に、Azureパイプラインの変数環境について説明します。この用語は記事全体でさまざまな参照があります。
パイプライン内には、変数を操作できる2つの場所があります。YAMLビルド定義内のパイプライン環境またはタスクを介して実行されるスクリプト内のスクリプト環境です。
パイプラインの環境
YAMLビルド定義内でビルド変数を定義または読み取る場合、これはパイプラインの環境と呼ばれます。例えば、以下ではYAMLビルド定義でvariables
セクションが定義されており、変数foo
をbar
に設定しています。このコンテキストでは、変数はパイプラインの環境内で定義されています。
スクリプトの環境
YAML定義自体またはスクリプト内でコードから変数を扱うこともできます。既存のスクリプトがまだ作成されていない場合は、以下に示すようにYAML定義内で変数を定義および読み取ることができます。このコンテキストでこれらの変数を扱うための構文については、後ほど学びます。
同じ構文をBashスクリプトに追加して実行することで、スクリプトの環境内にとどまることもできます。これは同じ一般的な概念です。
環境変数
スクリプトの環境内で、パイプライン変数が使用可能になると、環境変数が作成されます。これらの環境変数は、選択した言語の通常の方法でアクセスできます。
パイプライン変数は常に大文字で表示され、ドットはアンダースコアに置換されます。例えば、以下のように各スクリプト言語でfoo
パイプライン変数にアクセスできます。
- バッチ–
%FOO%
- PowerShell–
$env:FOO
- Bashスクリプト
パイプラインの「実行フェーズ」
パイプラインが「実行」される際には、単に「実行」するだけではありません。パイプラインに含まれるステージと同様に、パイプラインも実行時にさまざまなフェーズを経ます。Microsoftのドキュメントに公式の用語がないため、これを「実行フェーズ」と呼んでいます。
パイプラインがトリガーされると、3つの大まかなフェーズであるキュー、コンパイル、およびランタイムを経ます。これらの文脈を理解することは重要です。なぜなら、Microsoftのドキュメントを参照する場合に、これらの用語が出てくるからです。
キュータイム
パイプラインがキューに追加されるときにパイプラインが経る最初のフェーズです。このフェーズでは、まだパイプラインは開始していませんが、エージェントが利用可能になるとすぐに実行されるようにキューに追加されます。変数を定義する際に、YAMLファイルで定義しないようにすることで、キュータイムで利用できるようにすることができます。
以下に示すように、パイプラインが最初にキューに追加されるときに変数を定義することができます。この変数が追加されると、パイプラインのグローバル変数として利用可能になり、YAMLファイルで同じ変数名で上書きすることができます。

コンパイル
最終的に、パイプラインがYAMLファイルを処理し、スクリプトの実行を必要とするステップに進んだ時、パイプラインは「コンパイル」フェーズにあります。このコンテキストでは、エージェントはスクリプトステップで定義されたコードを実行しています。
ランタイム
次のフェーズはランタイムです。これはYAMLファイルが処理されているフェーズです。このフェーズでは、各ステージ、ジョブ、およびステップが処理されますが、スクリプトは実行されません。
変数の展開
理解するためにもう一つ重要なトピックは、変数の展開です。変数の展開とは、変数が保持している静的な値を返すことです。変数はその値を示すために展開されます。変数を読む際には努力なく展開されますが、展開はパイプラインの実行中に異なるタイミングで行われる場合があり、それにつまずく可能性があります。
変数の展開とコンパイル対ランタイムの概念は、変数の構文を理解する際に頻繁に取り上げられます。
前述のように、パイプラインは実行時に異なる「フェーズ」をカバーしています。変数の展開のトラブルシューティング時には、これらのフェーズに注意する必要があります。
以下に例を示します。これらの「フェーズ」の概念は、変数の環境と密接に関連しています。
パイプラインの実行が開始されると、変数は一度展開され、各ステップの開始時に再度展開されます。以下に、この動作の簡単な例を示します。
変数の構文
学んだように、変数はパイプライン環境とスクリプト環境の2つの「環境」で設定または読み取ることができます。各環境では、変数の参照方法が少し異なります。注意が必要な微妙な点がいくつかあります。
パイプライン変数
パイプライン変数はYAMLビルド定義で参照され、マクロ構文、テンプレート式、ランタイム式の3つの異なる構文方法を介して参照することができます。
マクロ構文
最も一般的な構文は、マクロ構文です。マクロ構文は、変数の値を$(foo)
の形式で参照します。括弧は、実行時に評価される式を表します。
Azure Pipelinesがマクロ式として定義された変数を処理すると、式を変数の内容で置き換えます。マクロ構文で変数を定義する場合、次のパターンに従います。<変数名>: $(<変数値>)
例:foo: $(bar)
。
マクロ構文で変数を参照しようとした場合、値が存在しない場合は変数自体も存在しないことになります。この動作は、構文タイプによって若干異なります。
テンプレート式の構文
別の種類の変数構文は、テンプレート式と呼ばれます。この構文を使用してパイプライン変数を定義する場合、次のようになります:${{ variables.foo }} : ${{ variables.bar }}
。マクロ構文よりもやや長い形式です。
テンプレート式構文には、追加の機能もあります。この構文を使用すると、テンプレートパラメーターを展開することもできます。テンプレート式構文で定義された変数が参照される場合、パイプラインはマクロ構文とは異なり、空の文字列を返します。
テンプレート式変数は、コンパイル時に処理され、実行時に上書きされます(定義されている場合)。
実行時の式構文
構文タイプとして、推奨される実行時の式変数は、実行時にのみ展開されます。この種類の変数は、$[variables.foo]
という形式で表されます。テンプレート式構文変数と同様に、これらの変数は置換されない場合には空の文字列を返します。
マクロ構文のように、実行時の式構文では、定義の左側に変数名が必要です。例えば、foo: $[variables.bar]
です。
スクリプト変数
スクリプト内で変数を扱う方法は、パイプライン変数とは異なります。タスクスクリプトで公開されるパイプライン変数の定義と参照は、ログコマンド構文または環境変数を使用して行うことができます。
ログコマンド
スクリプトでパイプライン変数を定義し、参照する方法の一つは、ログコマンドの構文を使用することです。この構文は少し複雑ですが、特定の状況では必要になることがあります。変数はスクリプト内で文字列として定義する必要があります。
ログコマンドの構文を使用して、値がbar
のfoo
という名前の変数を設定する場合、以下のようになります。
I could not find a way to get the value of variables using logging commands. If this exists, let me know!
環境変数
パイプライン変数がスクリプト内の環境変数に変換されると、変数名が若干変更されます。変数名は大文字になり、ピリオドはアンダースコアに変わります。多くの事前定義されたまたはシステム変数にはピリオドが含まれています。
例えば、[foo.bar](<http://foo.bar>)
という名前のパイプライン変数が定義されている場合、PowerShellでは$env:FOO_BAR
、Bashでは$FOO_BAR
など、スクリプトのネイティブな環境変数の参照方法を使用してその変数を参照します。
環境変数については、上記のスクリプト環境セクションで詳しく説明しました。
変数のスコープ
A pipeline has various stages, tasks and jobs running. Many areas have predefined variable scopes. A scope is namespace where when a variable is defined, its value can be referenced.
階層には基本的に3つの異なる変数のスコープがあります。それらは次の場所で定義されます:
- ルートレベルで定義されることにより、パイプライン内のすべてのジョブで変数が利用可能になります。
- ステージレベルで定義されることにより、特定のステージで変数が利用可能になります。
- ジョブレベルで定義されることにより、特定のジョブで変数が利用可能になります。
「下位」レベルで定義された変数(例:ジョブ)は、ステージおよびルートレベルで定義された同じ変数を上書きします。ステージレベルで定義された変数は、ジョブレベルで定義された変数によって上書きされますが、ジョブレベルで定義された変数によって上書きされます。
以下に、各スコープが使用されている例としてYAMLビルド定義が示されています。
変数の優先度
同じ名前の変数がさまざまなスコープで設定されている場合、その変数の値は特定のシーケンスに従って上書きされます。最も優先度が高いのは、最も近い「アクション」です。
以下に、ジョブ内で設定された変数から上書きされる変数の順序が示されます。これが最も優先度が高いとなります。
- YAMLファイルで設定されたジョブレベルでの変数の設定
- YAMLファイルで設定されたステージレベルでの変数の設定
- YAMLファイルで設定されたパイプラインレベル(グローバル)での変数の設定
- キュー時に設定された変数の設定
- パイプライン設定UIで設定されたパイプライン変数
以下は、YAMLの定義例です。この例では、同じ変数がさまざまな箇所で設定されていますが、最終的にはジョブで定義された値になります。各アクションでは、変数の値は上書きされ、パイプラインがジョブまで進むと値が確定します。
変数の種類
これまでの記事では、変数とは何か、どのような形式で表現されるか、実行されるコンテキストなどについて学びました。しかし、すべての変数が同じではないことについては触れていませんでした。パイプラインの開始時に既に存在して変更できない変数もあれば、自由に作成、変更、削除できる変数もあります。
変数には、予め定義された変数、ユーザー定義の変数、出力変数、シークレット変数の4つの一般的なタイプがあります。それぞれのタイプについて説明しましょう。
予め定義された変数
すべてのビルドとリリースには、デフォルトで存在するさまざまな変数があります。これらの変数は予め定義された変数またはシステム変数と呼ばれます。予め定義された変数は読み取り専用であり、他のタイプの変数と同様に、単純な文字列や数値を表します。
Azureパイプラインは、ビルドを実行するソフトウェアエージェント、デプロイメントが実行されたときに起動されるジョブなど、多くのコンポーネントから構成されています。これらの領域を表すために、予め定義されたまたはシステム変数は非公式に5つの異なるカテゴリに分類されます:
- エージェント
- ビルド
- パイプライン
- デプロイメントジョブ
- システム
これらの5つのカテゴリーには、数十の変数が散らばっています。この記事ではすべての変数について説明することはできません。すべての定義済み変数のリストが必要な場合は、Microsoftのドキュメントを参照してください。
ユーザー定義変数
YAML定義またはスクリプトを使用して変数を作成すると、ユーザー定義変数が作成されます。 ユーザー定義変数は、パイプラインで定義して使用するすべての変数です。これらの変数には、いくつかの例外を除いてほとんど任意の名前を使用できます。
ただし、endpoint、input、secret、またはsecurefileから始まる変数を定義することはできません。これらのラベルはシステムの使用のために予約されており、大文字と小文字を区別しません。
また、定義する変数は、文字、数字、ドット、またはアンダースコアのみで構成されている必要があります。この形式に従わない変数を定義しようとすると、YAMLビルド定義は機能しません。
出力変数
A build definition contains one or more tasks. Sometimes a task sends a variable out to be made available to downstream steps and jobs within the same stage. These types of variables are called output variables.
出力変数は、パイプラインのコンポーネント間で情報を共有するために使用されます。たとえば、あるタスクがデータベースから値をクエリし、後続のタスクで結果を使用する必要がある場合、出力変数を使用できます。そのため、毎回データベースをクエリする必要はありません。代わりに、変数を参照するだけです。
注意:出力変数は特定のステージにスコープが限定されます。例えば、ビルドステージとテストステージの両方で出力変数が利用可能になることは期待しないでください。
秘密変数
最後の変数のタイプは秘密変数です。厳密に言えば、これは独立したタイプではありませんが、システムまたはユーザー定義の変数になります。ただし、秘密変数は他の変数とは異なる扱いを受けるため、独自のカテゴリに分類されます。
A secret variable is a standard variable that’s encrypted. Secret variables typically contain sensitive information like API keys, passwords, etc. These variables are encrypted at rest with a 2048-bit RSA key and are available on the agent for all tasks and scripts to use.
– YAMLファイル内での秘密変数の定義は行わないでください
– 秘密を出力変数やログ情報として返さないでください
秘密変数はパイプラインエディタで定義する必要があります。これにより、パイプライン内のタスクで秘密変数が利用可能になります。
秘密の値はログでマスクされますが、完全に隠されるわけではありません。そのため、YAMLファイルに含めないようにすることが重要です。また、「構造化」データも秘密として含めないようにする必要があります。たとえば、{ "foo": "bar" }
が秘密として設定されている場合、bar
はログからマスクされません。
秘密は自動的に復号化され、環境変数にマッピングされるわけではありません。秘密変数を定義した場合、たとえばPowerShellスクリプト内で
$env:FOO
として利用可能になることはありません。
変数グループ
最後に、変数グループについて説明します。変数グループは、1つのグループとして参照できる変数の「グループ」です。変数グループの主な目的は、複数のパイプラインで利用可能な値を保存することです。
変数とは異なり、変数グループはYAMLファイルで定義されません。代わりに、UIのPipelinesの下のLibraryページで定義されます。
変数グループを使用して、複数のパイプラインで制御可能な値を保存し、利用できるようにすることができます。また、変数グループを使用して、YAMLパイプラインに渡す必要があるシークレットやその他の値を保存することもできます。変数グループは、以下に示すようにLibraryページのPipelinesで定義および管理されます。

パイプラインライブラリで定義した後、以下の構文を使用してYAMLファイルでその変数グループにアクセスできます。
変数グループは、デフォルトではすべてのパイプラインで利用できるわけではありません。この設定は、グループを作成する際に利用可能になります。パイプラインは変数グループの使用を承認する必要があります。
変数グループがYAMLファイルでアクセス可能になったら、グループ内の変数には他の変数と同様にアクセスできます。変数グループの名前は、グループ内の変数を参照する際には使用されません。
例えば、group1という名前の変数グループがあり、内部にfooという変数が定義されている場合、foo変数は他の変数と同様に$(foo)
として参照されます。
変数グループで定義されたシークレット変数は、スクリプトから直接アクセスすることはできません。代わりに、タスクへの引数として渡す必要があります。
変数グループ内の変数を変更した場合、その変更はそのグループを使用できるすべてのパイプラインに自動的に反映されます。
要約
あなたは今、Azure Pipelinesの変数についてしっかりとした知識を持つはずです。この記事では、変数に関するほとんどの概念を学びました!さあ、この知識を活用してAzure DevOps Pipelinesに適用し、すべてを自動化しましょう!
Source:
https://adamtheautomator.com/azure-devops-variables/