外部システムとの連携に使用する情報や、ダッシュボードやボットの実行ユーザ名など、Salesforce のメタデータに環境固有の値を設定しないといけないケースは珍しくありません。これらを適切に扱わないと他環境へのデプロイ時にエラーとなったり、誤った値を設定してしまったり等、トラブルになりがちです。環境変数をスプレッドシート等で管理し、デプロイ後に手動で設定を行うこともできますが、可能な限り自動化することでミスやデプロイエラーを防ぐことができます。この記事では、sfdx-project.json に含めることのできる replacements 機能を使ってメタデータで環境依存値を扱う方法を紹介します。
基本的な使い方
環境変数を外から設定する
以下のようなメタデータを考えます。Einstein ボットの実行ユーザをデプロイ前に変更したいとします。<botUser> の値を retrieve したどこかの環境の値のままにしておくのではなく、外から値を設定できるようにしてみましょう。
<?xml version="1.0" encoding="UTF-8"?>
<Bot xmlns="http://soap.sforce.com/2006/04/metadata">
<botMlDomain>
<label>Example Bot</label>
<name>Example_Bot</name>
</botMlDomain>
<botSource>None</botSource>
<botUser>BOTUSER_PLACEHOLDER</botUser> <!--ここの値を可変にしたい-->
<contextVariables>
(以下略)
次のような sfdx-project.json を設定します。
{
"packageDirectories": [
{
"path": "force-app",
"default": true
}
],
"name": "myproj",
"replacements": [
{
"filename": "force-app/main/default/bots/Example_Bot.bot-meta.xml",
"stringToReplace": "BOTUSER_PLACEHOLDER",
"replaceWithEnv": "BOT_USER"
}
]
}
replacements の値に注目してください。これは、force-app/main/default/bots/Example_Bot.bot-meta.xml ファイルの、BOTUSER_PLACEHOLDER という文字列を、環境変数 BOT_USER の値に置換する。という意味になります。
stringToReplace で使用するプレースホルダのフォーマットに制限はありません。例のように他と重複しない大文字の文字列としても良いでしょうし、{{ VariableName }} のように指定してもよいでしょう。プロジェクト内でルールを定めておくことが大切です。
他にも特定の場合に限り文字列を置換したり、正規表現で複数ファイルを一度に置換したり(ApexクラスのAPIバージョンを一括置換するなど)、置換文字列が大きい場合は別ファイルから読み込んだり等の設定があります。詳細は公式ガイドを参照してください。
変更をテストする
実際に組織にメタデータをリリースせずに変換を試すには、Saleforce CLI の環境変数 SF_APPLY_REPLACEMENTS_ON_CONVERT を true にします。その上で、sf project convert source コマンドを実行します。
export SF_APPLY_REPLACEMENTS_ON_CONVERT=true
export BOT_USER=test@example.com
sf project convert source --source-dir force-app
set SF_APPLY_REPLACEMENTS_ON_CONVERT=true
set BOT_USER=test@example.com
sf project convert source --source-dir force-app
文字列置換されたメタデータを含む新しいパッケージが作成されます。
?xml version="1.0" encoding="UTF-8"?>
<Bot xmlns="http://soap.sforce.com/2006/04/metadata">
<botMlDomain>
<label>Example Bot</label>
<name>Example_Bot</name>
</botMlDomain>
<botSource>None</botSource>
<botUser>test@example.com</botUser>
<contextVariables>
(以下略)
変換してデプロイする
環境変数を事前に設定してから通常のデプロイコマンドを実行します。
BOT_USER="stg@example.com" sf project deploy start
set BOT_USER=stg@example.com
sf project deploy start
環境変数ファイルと合わせて使用する
これまでのステップで環境変数を動的に設定できるようになりましたが、環境毎に置換文字列が複数ある場合は、環境変数を独立したファイルで扱うのが一般的です。例えば、dev/stg/本番で指定ログイン情報のエンドポイントが異なるとし、以下のようなファイルを設けるとします。以下は .env ファイルの例ですが、yaml などプロジェクトのルールや使用している CI/CD ツールに応じて必要なフォーマットで設定してください。
<?xml version="1.0" encoding="UTF-8"?>
<NamedCredential xmlns="http://soap.sforce.com/2006/04/metadata">
<allowMergeFieldsInBody>true</allowMergeFieldsInBody>
<allowMergeFieldsInHeader>true</allowMergeFieldsInHeader>
<calloutStatus>Enabled</calloutStatus>
<generateAuthorizationHeader>true</generateAuthorizationHeader>
<label>Example API</label>
<namedCredentialParameters>
<parameterName>Url</parameterName>
<parameterType>Url</parameterType>
<parameterValue>EXAMPLE_ENDPOINT_URL</parameterValue>
</namedCredentialParameters>
(中略)
<namedCredentialType>SecuredEndpoint</namedCredentialType>
</NamedCredential>
{
"packageDirectories": [
{
"path": "force-app",
"default": true
}
],
"name": "myproj",
"replacements": [
{
"filename": "force-app/main/default/bots/Example_Bot.bot-meta.xml",
"stringToReplace": "BOTUSER_PLACEHOLDER",
"replaceWithEnv": "BOT_USER"
}
]
}
EXAMPLE_ENDPOINT_URL=https://dev.example.com/api
EXAMPLE_ENDPOINT_URL=https://stg.example.com/api
EXAMPLE_ENDPOINT_URL=https://www.example.com/api
Windows の場合は set を使用してください。
set EXAMPLE_ENDPOINT_URL=https://dev.example.com/api
ファイルを読み込んでからデプロイコマンドを実行します。npm-scripts に定義しておいてもよいでしょう。dev環境へのデプロイの際は以下のようになります。
set -a
source .env.dev
sf project deploy start
call .env.dev.bat
sf project deploy start
機密情報を含む環境変数ファイルはリポジトリにpushしないように注意しましょう。
また、クロスプラットフォームで環境変数を扱いやすくするために dotenv-cli や cross-env 等様々な仕組みがありますが、この記事では Salesforce CLI の機能にフォーカスするために考慮していません。必要に応じて導入してください。
おわりに
replacements 自体は文字列置換のためのシンプルな仕組みですが、デプロイから手動作業を取り除くためのSalesforce CLI 標準機能として有用な選択肢の 1 つになると思います。この作業に手間をかけている場合はぜひ使用を検討してみてください。