diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..c92beea --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @bishal-pdmsft @kanika1894 @pulkitaggarwl \ No newline at end of file diff --git a/.github/workflows/ci-workflow.yml b/.github/workflows/ci-workflow.yml index d11b5bd..108c11e 100644 --- a/.github/workflows/ci-workflow.yml +++ b/.github/workflows/ci-workflow.yml @@ -18,13 +18,44 @@ jobs: - run: sudo npm i -g ts-node - - name: Test + - name: Resource group scope test env: INPUT_SCOPE: resourcegroup INPUT_SUBSCRIPTIONID: ${{ secrets.SUBSCRIPTION_ID }} - INPUT_RESOURCEGROUPNAME: azurearmaction + INPUT_RESOURCEGROUPNAME: E2eTestResourceGroupForArmAction + INPUT_TEMPLATE: https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/101-webapp-basic-linux/azuredeploy.json + INPUT_PARAMETERS: https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/101-webapp-basic-linux/azuredeploy.parameters.json + INPUT_DEPLOYMENTNAME: github-test-rg + INPUT_DEPLOYMENTMODE: Complete + run: ts-node test/main.tests.ts + + - name: Management group scope test + env: + INPUT_SCOPE: managementgroup + INPUT_MANAGEMENTGROUPID: E2eTestGroupForArmAction + INPUT_REGION: WestUS INPUT_TEMPLATE: ./test/template.json INPUT_PARAMETERS: ./test/parameters.json - INPUT_DEPLOYMENTNAME: github-test - INPUT_DEPLOYMENTMODE: Incremental + INPUT_DEPLOYMENTNAME: github-test-mg + run: ts-node test/main.tests.ts + + - name: Subscription scope test + env: + INPUT_SCOPE: subscription + INPUT_SUBSCRIPTIONID: ${{ secrets.SUBSCRIPTION_ID }} + INPUT_REGION: centralus + INPUT_TEMPLATE: https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/azure-resource-manager/emptyRG.json + INPUT_PARAMETERS: rgName=demoResourceGroup rgLocation=centralus + INPUT_DEPLOYMENTNAME: github-test-subs + run: ts-node test/main.tests.ts + + - name: Validate mode test + env: + INPUT_SCOPE: resourcegroup + INPUT_SUBSCRIPTIONID: ${{ secrets.SUBSCRIPTION_ID }} + INPUT_RESOURCEGROUPNAME: E2eTestResourceGroupForArmAction + INPUT_TEMPLATE: https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/101-webapp-basic-linux/azuredeploy.json + INPUT_PARAMETERS: https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/101-webapp-basic-linux/azuredeploy.parameters.json + INPUT_DEPLOYMENTNAME: github-test-rg + INPUT_DEPLOYMENTMODE: Validate run: ts-node test/main.tests.ts diff --git a/.github/workflows/defaultLabel.yml b/.github/workflows/defaultLabel.yml new file mode 100644 index 0000000..525627d --- /dev/null +++ b/.github/workflows/defaultLabel.yml @@ -0,0 +1,20 @@ +name: Mark issues "default" + +on: + schedule: + - cron: "0 0/3 * * *" + +jobs: + stale: + + runs-on: ubuntu-latest + + steps: + - uses: actions/stale@v3 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + stale-issue-message: 'This issue is marked default for generating issues report.' + stale-issue-label: 'default' + days-before-stale: 0 + days-before-close: -1 + operations-per-run: 100 diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml new file mode 100644 index 0000000..98dcbf1 --- /dev/null +++ b/.github/workflows/stale.yml @@ -0,0 +1,20 @@ +name: Mark stale issues + +on: + schedule: + - cron: "0 0/3 * * *" + +jobs: + stale: + runs-on: ubuntu-latest + + steps: + - uses: actions/stale@v3 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + stale-issue-message: "This issue is stale because it has been open for 7 days with no activity." + stale-issue-label: "stale" + days-before-stale: 7 + days-before-close: -1 + operations-per-run: 100 + exempt-issue-labels: "backlog" diff --git a/.gitignore b/.gitignore index dfcfd56..03044ab 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,9 @@ ## ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore +# local built files +_build + # User-specific files *.rsuser *.suo diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..6abdd58 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,29 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "node", + "request": "launch", + "name": "Launch Program", + "skipFiles": [ + "/**" + ], + "program": "${workspaceFolder}/src/entrypoint.ts", + "outFiles": [ + "${workspaceFolder}/_build/*.js" + ], + "env": { + "INPUT_SCOPE": "resourcegroup", + "INPUT_SUBSCRIPTIONID": "c00d16c7-6c1f-4c03-9be1-6934a4c49682", + "INPUT_RESOURCEGROUPNAME": "kptest", + "INPUT_TEMPLATE": "./test/template.json", + "INPUT_PARAMETERS": "./test/parameters.json", + "INPUT_DEPLOYMENTNAME": "github-test", + "INPUT_DEPLOYMENTMODE": "Incremental" + } + } + ] +} \ No newline at end of file diff --git a/HowToDebug.md b/HowToDebug.md new file mode 100644 index 0000000..196b8ff --- /dev/null +++ b/HowToDebug.md @@ -0,0 +1,16 @@ +**Debugging the ARM action in local machine** + +Open PowerShell, go to the directory where the repo is stored (.../arm-deploy/) and execute the following commands. + +**1.npm install** \ +npm install downloads dependencies defined in a package. json file and generates a node_modules folder with the installed modules. \ +**2.npm install -g @vercel/ncc** \ +**3.ncc build src/entrypoint.ts -s -o _build** \ +ncc is a simple CLI for compiling a Node.js module into a single file, together with all its dependencies, gcc-style. \ +**4. az login** \ +This will open the browser, where you can do the Azure login which gives you proper access required for the action. + +Open the arm-deploy repository in VSCode, attach debugging points at required places _(flow begins from entrypoint.ts)_ and press F5. The debugger gets attached. + +Also, for various input values required while testing, you can specify those as environment variables in launch.json that gets created. \ +_Happy debugging!_ diff --git a/README.md b/README.md index 5553946..49a07ea 100644 --- a/README.md +++ b/README.md @@ -13,12 +13,12 @@ This action can be used to deploy Azure Resource Manager templates at different * `scope`: Provide the scope of the deployment. Valid values are: `resourcegroup`(default) , `subscription`, `managementgroup`. * `resourceGroupName`: **Conditional** Provide the name of a resource group. Only required for Resource Group Scope -* `subscriptionId`: **Conditional** Provide the subscription ID which should be used. Only required for scope `resourcegroup` & `subscription`. +* `subscriptionId`: **Conditional** Provide a value to override the subscription ID set by [Azure Login](https://github.com/Azure/login). * `managementGroupId`: **Conditional** Specify the Management Group ID, only required for Management Group Deployments. * `region`: **Conditional** Provide the target region, only required for Management Group or Subscription deployments. * `template`: **Required** Specify the path or URL to the Azure Resource Manager template. * `parameters`: Specify the path or URL to the Azure Resource Manager deployment parameter values. Or local / remote value file. -* `deploymentMode`: `Incremental`(default) (only add resources to resource group) or `Complete` (remove extra resources from resource group). +* `deploymentMode`: `Incremental`(default) (only add resources to resource group) or `Complete` (remove extra resources from resource group) or `Validate` (only validates the template). * `deploymentName`: Specifies the name of the resource group deployment to create. @@ -52,7 +52,6 @@ jobs: creds: ${{ secrets.AZURE_CREDENTIALS }} - uses: azure/arm-deploy@v1 with: - subscriptionId: e1046c08-7072-****-****-************ resourceGroupName: github-action-arm-rg template: ./azuredeploy.json parameters: storageAccountType=Standard_LRS @@ -66,7 +65,6 @@ In this exmaple, our template outputs `containerName`. - uses: azure/arm-deploy@v1 id: deploy with: - subscriptionId: e1046c08-7072-****-****-************ resourceGroupName: azurearmaction template: examples/template/template.json parameters: examples/template/parameters.json @@ -93,6 +91,10 @@ If we now add a Shell script with a simple echo from that value, we can see that - run: echo ${{ steps.deploy.outputs.containerName }} ``` +ARM Deploy Actions is supported for the Azure public cloud as well as Azure government clouds ('AzureUSGovernment' or 'AzureChinaCloud') and Azure Stack ('AzureStack') Hub. Before running this action, login to the respective Azure Cloud using [Azure Login](https://github.com/Azure/login) by setting appropriate value for the `environment` parameter. + +For more examples, refer : [Example Guide](https://github.com/Azure/arm-deploy/blob/main/examples/exampleGuide.md) + # Contributing This project welcomes contributions and suggestions. Most contributions require you to agree to a diff --git a/ReleaseProcess.md b/ReleaseProcess.md new file mode 100644 index 0000000..e8cfc19 --- /dev/null +++ b/ReleaseProcess.md @@ -0,0 +1,16 @@ +**Releasing a new version** + +Semanting versioning is used to release different versions of the action. Following steps are to be followed : + +1. Create a new branch for every major version. \ +Example, releases/v1, releases/v2. +2. For every minor and patch release for a major version, update the corresponding release branch. \ +Example, for releasing v1.1.1, update releases/v1. +3. Create tags for every new release (major/minor/patch). \ +Example,v1.0.0. , v1.0.1, v2.0.1, etc. and also have tags like v1, v2 for every major version release. +4. On releasing minor and patch versions, update the tag of the corresponding major version. \ +Example, for releasing v1.0.1, update the v1 tag to point to the ref of the current release. \ +The following commands are to be run on the release\v1 branch so that it picks the latest commit and updates the v1 tag accordingly : +(Ensure that you are on same commit locally as you want to release.) +* `git tag -fa v1 -m "Update v1 tag"` +* `git push origin v1 --force` diff --git a/action.yml b/action.yml index d8baf6b..a63488c 100644 --- a/action.yml +++ b/action.yml @@ -2,10 +2,10 @@ name: "Deploy Azure Resource Manager (ARM) Template" description: "Use this GitHub Action task to deploy Azure Resource Manager (ARM) template" inputs: scope: - description: "Provide the scope of the deployment. alid values are: 'resourcegroup', 'managementgroup', 'subscription'" + description: "Provide the scope of the deployment. Valid values are: 'resourcegroup', 'managementgroup', 'subscription'" required: true subscriptionId: - description: "Provide the Id of the subscription which should be used." + description: "Override the Subscription Id set by Azure Login." required: false managementGroupId: description: "Specify the Id for the Management Group, only required for Management Group Deployments." @@ -14,15 +14,14 @@ inputs: description: "Provide the target region, only required for management Group or Subscription deployments." required: false resourceGroupName: - description: "Provide the name of a resource group." + description: "Provide the name of a resource group, only required for resource Group deployments." required: false template: description: "Specify the path or URL to the Azure Resource Manager template." required: true deploymentMode: - description: "Incremental (only add resources to resource group) or Complete (remove extra resources from resource group)." + description: "Incremental (only add resources to resource group) or Complete (remove extra resources from resource group) or Validate (only validates the template)." required: false - default: Incremental deploymentName: description: "Specifies the name of the resource group deployment to create." required: false diff --git a/dist/index.js b/dist/index.js index 7700a26..de263aa 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1 +1 @@ -module.exports=function(e,t){"use strict";var n={};function __webpack_require__(t){if(n[t]){return n[t].exports}var i=n[t]={i:t,l:false,exports:{}};var r=true;try{e[t].call(i.exports,i,i.exports,__webpack_require__);r=false}finally{if(r)delete n[t]}i.l=true;return i.exports}__webpack_require__.ab=__dirname+"/";function startup(){return __webpack_require__(464)}return startup()}({32:function(e,t,n){"use strict";var i=this&&this.__awaiter||function(e,t,n,i){function adopt(e){return e instanceof n?e:new n(function(t){t(e)})}return new(n||(n=Promise))(function(n,r){function fulfilled(e){try{step(i.next(e))}catch(e){r(e)}}function rejected(e){try{step(i["throw"](e))}catch(e){r(e)}}function step(e){e.done?n(e.value):adopt(e.value).then(fulfilled,rejected)}step((i=i.apply(e,t||[])).next())})};var r;Object.defineProperty(t,"__esModule",{value:true});const o=n(357);const s=n(747);const u=n(622);r=s.promises,t.chmod=r.chmod,t.copyFile=r.copyFile,t.lstat=r.lstat,t.mkdir=r.mkdir,t.readdir=r.readdir,t.readlink=r.readlink,t.rename=r.rename,t.rmdir=r.rmdir,t.stat=r.stat,t.symlink=r.symlink,t.unlink=r.unlink;t.IS_WINDOWS=process.platform==="win32";function exists(e){return i(this,void 0,void 0,function*(){try{yield t.stat(e)}catch(e){if(e.code==="ENOENT"){return false}throw e}return true})}t.exists=exists;function isDirectory(e,n=false){return i(this,void 0,void 0,function*(){const i=n?yield t.stat(e):yield t.lstat(e);return i.isDirectory()})}t.isDirectory=isDirectory;function isRooted(e){e=normalizeSeparators(e);if(!e){throw new Error('isRooted() parameter "p" cannot be empty')}if(t.IS_WINDOWS){return e.startsWith("\\")||/^[A-Z]:/i.test(e)}return e.startsWith("/")}t.isRooted=isRooted;function mkdirP(e,n=1e3,r=1){return i(this,void 0,void 0,function*(){o.ok(e,"a path argument must be provided");e=u.resolve(e);if(r>=n)return t.mkdir(e);try{yield t.mkdir(e);return}catch(i){switch(i.code){case"ENOENT":{yield mkdirP(u.dirname(e),n,r+1);yield t.mkdir(e);return}default:{let n;try{n=yield t.stat(e)}catch(e){throw i}if(!n.isDirectory())throw i}}}})}t.mkdirP=mkdirP;function tryGetExecutablePath(e,n){return i(this,void 0,void 0,function*(){let i=undefined;try{i=yield t.stat(e)}catch(t){if(t.code!=="ENOENT"){console.log(`Unexpected error attempting to determine if executable file exists '${e}': ${t}`)}}if(i&&i.isFile()){if(t.IS_WINDOWS){const t=u.extname(e).toUpperCase();if(n.some(e=>e.toUpperCase()===t)){return e}}else{if(isUnixExecutable(i)){return e}}}const r=e;for(const o of n){e=r+o;i=undefined;try{i=yield t.stat(e)}catch(t){if(t.code!=="ENOENT"){console.log(`Unexpected error attempting to determine if executable file exists '${e}': ${t}`)}}if(i&&i.isFile()){if(t.IS_WINDOWS){try{const n=u.dirname(e);const i=u.basename(e).toUpperCase();for(const r of yield t.readdir(n)){if(i===r.toUpperCase()){e=u.join(n,r);break}}}catch(t){console.log(`Unexpected error attempting to determine the actual case of the file '${e}': ${t}`)}return e}else{if(isUnixExecutable(i)){return e}}}}return""})}t.tryGetExecutablePath=tryGetExecutablePath;function normalizeSeparators(e){e=e||"";if(t.IS_WINDOWS){e=e.replace(/\//g,"\\");return e.replace(/\\\\+/g,"\\")}return e.replace(/\/\/+/g,"/")}function isUnixExecutable(e){return(e.mode&1)>0||(e.mode&8)>0&&e.gid===process.getgid()||(e.mode&64)>0&&e.uid===process.getuid()}},51:function(e,t,n){"use strict";var i=this&&this.__awaiter||function(e,t,n,i){function adopt(e){return e instanceof n?e:new n(function(t){t(e)})}return new(n||(n=Promise))(function(n,r){function fulfilled(e){try{step(i.next(e))}catch(e){r(e)}}function rejected(e){try{step(i["throw"](e))}catch(e){r(e)}}function step(e){e.done?n(e.value):adopt(e.value).then(fulfilled,rejected)}step((i=i.apply(e,t||[])).next())})};Object.defineProperty(t,"__esModule",{value:true});const r=n(129);const o=n(622);const s=n(669);const u=n(32);const c=s.promisify(r.exec);function cp(e,t,n={}){return i(this,void 0,void 0,function*(){const{force:i,recursive:r}=readCopyOptions(n);const s=(yield u.exists(t))?yield u.stat(t):null;if(s&&s.isFile()&&!i){return}const c=s&&s.isDirectory()?o.join(t,o.basename(e)):t;if(!(yield u.exists(e))){throw new Error(`no such file or directory: ${e}`)}const l=yield u.stat(e);if(l.isDirectory()){if(!r){throw new Error(`Failed to copy. ${e} is a directory, but tried to copy without recursive flag.`)}else{yield cpDirRecursive(e,c,0,i)}}else{if(o.relative(e,c)===""){throw new Error(`'${c}' and '${e}' are the same file`)}yield copyFile(e,c,i)}})}t.cp=cp;function mv(e,t,n={}){return i(this,void 0,void 0,function*(){if(yield u.exists(t)){let i=true;if(yield u.isDirectory(t)){t=o.join(t,o.basename(e));i=yield u.exists(t)}if(i){if(n.force==null||n.force){yield rmRF(t)}else{throw new Error("Destination already exists")}}}yield mkdirP(o.dirname(t));yield u.rename(e,t)})}t.mv=mv;function rmRF(e){return i(this,void 0,void 0,function*(){if(u.IS_WINDOWS){try{if(yield u.isDirectory(e,true)){yield c(`rd /s /q "${e}"`)}else{yield c(`del /f /a "${e}"`)}}catch(e){if(e.code!=="ENOENT")throw e}try{yield u.unlink(e)}catch(e){if(e.code!=="ENOENT")throw e}}else{let t=false;try{t=yield u.isDirectory(e)}catch(e){if(e.code!=="ENOENT")throw e;return}if(t){yield c(`rm -rf "${e}"`)}else{yield u.unlink(e)}}})}t.rmRF=rmRF;function mkdirP(e){return i(this,void 0,void 0,function*(){yield u.mkdirP(e)})}t.mkdirP=mkdirP;function which(e,t){return i(this,void 0,void 0,function*(){if(!e){throw new Error("parameter 'tool' is required")}if(t){const t=yield which(e,false);if(!t){if(u.IS_WINDOWS){throw new Error(`Unable to locate executable file: ${e}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also verify the file has a valid extension for an executable file.`)}else{throw new Error(`Unable to locate executable file: ${e}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also check the file mode to verify the file is executable.`)}}}try{const t=[];if(u.IS_WINDOWS&&process.env.PATHEXT){for(const e of process.env.PATHEXT.split(o.delimiter)){if(e){t.push(e)}}}if(u.isRooted(e)){const n=yield u.tryGetExecutablePath(e,t);if(n){return n}return""}if(e.includes("/")||u.IS_WINDOWS&&e.includes("\\")){return""}const n=[];if(process.env.PATH){for(const e of process.env.PATH.split(o.delimiter)){if(e){n.push(e)}}}for(const i of n){const n=yield u.tryGetExecutablePath(i+o.sep+e,t);if(n){return n}}return""}catch(e){throw new Error(`which failed with message ${e.message}`)}})}t.which=which;function readCopyOptions(e){const t=e.force==null?true:e.force;const n=Boolean(e.recursive);return{force:t,recursive:n}}function cpDirRecursive(e,t,n,r){return i(this,void 0,void 0,function*(){if(n>=255)return;n++;yield mkdirP(t);const i=yield u.readdir(e);for(const o of i){const i=`${e}/${o}`;const s=`${t}/${o}`;const c=yield u.lstat(i);if(c.isDirectory()){yield cpDirRecursive(i,s,n,r)}else{yield copyFile(i,s,r)}}yield u.chmod(t,(yield u.stat(e)).mode)})}function copyFile(e,t,n){return i(this,void 0,void 0,function*(){if((yield u.lstat(e)).isSymbolicLink()){try{yield u.lstat(t);yield u.unlink(t)}catch(e){if(e.code==="EPERM"){yield u.chmod(t,"0666");yield u.unlink(t)}}const n=yield u.readlink(e);yield u.symlink(n,t,u.IS_WINDOWS?"junction":null)}else if(!(yield u.exists(t))||n){yield u.copyFile(e,t)}})}},87:function(e){e.exports=require("os")},93:function(e,t,n){"use strict";var i=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var n in e)if(Object.hasOwnProperty.call(e,n))t[n]=e[n];t["default"]=e;return t};Object.defineProperty(t,"__esModule",{value:true});const r=i(n(827));function ParseOutputs(e){var t=JSON.parse(e);var n=t.properties.outputs;for(const e in n){if(n.hasOwnProperty(e)){r.setOutput(e,n[e].value)}}return n}t.ParseOutputs=ParseOutputs},120:function(e,t,n){"use strict";var i=this&&this.__awaiter||function(e,t,n,i){function adopt(e){return e instanceof n?e:new n(function(t){t(e)})}return new(n||(n=Promise))(function(n,r){function fulfilled(e){try{step(i.next(e))}catch(e){r(e)}}function rejected(e){try{step(i["throw"](e))}catch(e){r(e)}}function step(e){e.done?n(e.value):adopt(e.value).then(fulfilled,rejected)}step((i=i.apply(e,t||[])).next())})};Object.defineProperty(t,"__esModule",{value:true});const r=n(860);function exec(e,t,n){return i(this,void 0,void 0,function*(){const i=r.argStringToArray(e);if(i.length===0){throw new Error(`Parameter 'commandLine' cannot be null or empty.`)}const o=i[0];t=i.slice(1).concat(t||[]);const s=new r.ToolRunner(o,t,n);return s.exec()})}t.exec=exec},129:function(e){e.exports=require("child_process")},191:function(e,t,n){"use strict";var i=this&&this.__awaiter||function(e,t,n,i){return new(n||(n=Promise))(function(r,o){function fulfilled(e){try{step(i.next(e))}catch(e){o(e)}}function rejected(e){try{step(i["throw"](e))}catch(e){o(e)}}function step(e){e.done?r(e.value):new n(function(t){t(e.value)}).then(fulfilled,rejected)}step((i=i.apply(e,t||[])).next())})};var r=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var n in e)if(Object.hasOwnProperty.call(e,n))t[n]=e[n];t["default"]=e;return t};Object.defineProperty(t,"__esModule",{value:true});const o=r(n(827));const s=n(120);const u=n(93);function DeployResourceGroupScope(e,t,n,r,c,l,a){return i(this,void 0,void 0,function*(){if(!n){throw Error("ResourceGroup name must be set.")}var i=yield s.exec(`"${e}" group show --resource-group ${n}`,[],{silent:true,ignoreReturnCode:true});if(i!=0){throw Error(`Resource Group ${n} could not be found.`)}const d=[n?`--resource-group ${n}`:undefined,r?r.startsWith("http")?`--template-uri ${r}`:`--template-file ${r}`:undefined,c?`--mode ${c}`:undefined,l?`--name ${l}`:undefined,a?`--parameters ${a}`:undefined].filter(Boolean).join(" ");let f="";const p={silent:true,failOnStdErr:true,listeners:{stderr:e=>{o.warning(e.toString())},stdline:e=>{if(!e.startsWith("[command]"))f+=e}}};const h={silent:true,ignoreReturnCode:true,listeners:{stderr:e=>{o.warning(e.toString())}}};o.info("Validating template...");var m=yield s.exec(`"${e}" deployment group validate ${d} -o json`,[],h);if(t&&m!=0){throw new Error("Template validation failed")}else if(m!=0){o.warning("Template validation failed.")}o.info("Creating deployment...");yield s.exec(`"${e}" deployment group create ${d} -o json`,[],p);o.debug(f);o.info("Parsing outputs...");return u.ParseOutputs(f)})}t.DeployResourceGroupScope=DeployResourceGroupScope},215:function(e,t,n){"use strict";var i=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var n in e)if(Object.hasOwnProperty.call(e,n))t[n]=e[n];t["default"]=e;return t};Object.defineProperty(t,"__esModule",{value:true});const r=i(n(87));function issueCommand(e,t,n){const i=new Command(e,t,n);process.stdout.write(i.toString()+r.EOL)}t.issueCommand=issueCommand;function issue(e,t=""){issueCommand(e,{},t)}t.issue=issue;const o="::";class Command{constructor(e,t,n){if(!e){e="missing.command"}this.command=e;this.properties=t;this.message=n}toString(){let e=o+this.command;if(this.properties&&Object.keys(this.properties).length>0){e+=" ";let t=true;for(const n in this.properties){if(this.properties.hasOwnProperty(n)){const i=this.properties[n];if(i){if(t){t=false}else{e+=","}e+=`${n}=${escapeProperty(i)}`}}}}e+=`${o}${escapeData(this.message)}`;return e}}function escapeData(e){return(e||"").replace(/%/g,"%25").replace(/\r/g,"%0D").replace(/\n/g,"%0A")}function escapeProperty(e){return(e||"").replace(/%/g,"%25").replace(/\r/g,"%0D").replace(/\n/g,"%0A").replace(/:/g,"%3A").replace(/,/g,"%2C")}},357:function(e){e.exports=require("assert")},464:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:true});const i=n(827);const r=n(982);r.main().then(()=>{process.exit(0)}).catch(e=>{i.setFailed(e.message);process.exit(1)})},614:function(e){e.exports=require("events")},622:function(e){e.exports=require("path")},669:function(e){e.exports=require("util")},718:function(e,t,n){"use strict";var i=this&&this.__awaiter||function(e,t,n,i){return new(n||(n=Promise))(function(r,o){function fulfilled(e){try{step(i.next(e))}catch(e){o(e)}}function rejected(e){try{step(i["throw"](e))}catch(e){o(e)}}function step(e){e.done?r(e.value):new n(function(t){t(e.value)}).then(fulfilled,rejected)}step((i=i.apply(e,t||[])).next())})};var r=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var n in e)if(Object.hasOwnProperty.call(e,n))t[n]=e[n];t["default"]=e;return t};Object.defineProperty(t,"__esModule",{value:true});const o=n(120);const s=n(93);const u=r(n(827));function DeploySubscriptionScope(e,t,n,r,c,l,a){return i(this,void 0,void 0,function*(){if(!n){throw Error("Region must be set.")}if(c!=""){u.warning("Deployment Mode is not supported for subscription scoped deployments, this parameter will be ignored!")}const i=[n?`--location ${n}`:undefined,r?r.startsWith("http")?`--template-uri ${r}`:`--template-file ${r}`:undefined,l?`--name ${l}`:undefined,a?`--parameters ${a}`:undefined].filter(Boolean).join(" ");let d="";const f={silent:true,failOnStdErr:true,listeners:{stderr:e=>{u.warning(e.toString())},stdline:e=>{if(!e.startsWith("[command]"))d+=e}}};const p={silent:true,ignoreReturnCode:true,listeners:{stderr:e=>{u.warning(e.toString())}}};u.info("Validating template...");var h=yield o.exec(`"${e}" deployment sub validate ${i} -o json`,[],p);if(t&&h!=0){throw new Error("Template validation failed")}else if(h!=0){u.warning("Template validation failed.")}u.info("Creating deployment...");yield o.exec(`"${e}" deployment sub create ${i} -o json`,[],f);u.debug(d);u.info("Parsing outputs...");return s.ParseOutputs(d)})}t.DeploySubscriptionScope=DeploySubscriptionScope},723:function(e,t,n){"use strict";var i=this&&this.__awaiter||function(e,t,n,i){return new(n||(n=Promise))(function(r,o){function fulfilled(e){try{step(i.next(e))}catch(e){o(e)}}function rejected(e){try{step(i["throw"](e))}catch(e){o(e)}}function step(e){e.done?r(e.value):new n(function(t){t(e.value)}).then(fulfilled,rejected)}step((i=i.apply(e,t||[])).next())})};var r=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var n in e)if(Object.hasOwnProperty.call(e,n))t[n]=e[n];t["default"]=e;return t};Object.defineProperty(t,"__esModule",{value:true});const o=n(120);const s=n(93);const u=r(n(827));function DeployManagementGroupScope(e,t,n,r,c,l,a,d){return i(this,void 0,void 0,function*(){if(!n){throw Error("Region must be set.")}if(c!=""){u.warning("Deployment Mode is not supported for subscription scoped deployments, this parameter will be ignored!")}const i=[n?`--location ${n}`:undefined,r?r.startsWith("http")?`--template-uri ${r}`:`--template-file ${r}`:undefined,d?`--management-group-id ${d}`:undefined,l?`--name ${l}`:undefined,a?`--parameters ${a}`:undefined].filter(Boolean).join(" ");let f="";const p={silent:true,failOnStdErr:true,listeners:{stderr:e=>{u.warning(e.toString())},stdline:e=>{if(!e.startsWith("[command]"))f+=e}}};const h={silent:true,ignoreReturnCode:true,listeners:{stderr:e=>{u.warning(e.toString())}}};u.info("Validating template...");var m=yield o.exec(`"${e}" deployment mg validate ${i} -o json`,[],h);if(t&&m!=0){throw new Error("Template validation failed")}else if(m!=0){u.warning("Template validation failed.")}u.info("Creating deployment...");yield o.exec(`"${e}" deployment mg create ${i} -o json`,[],p);u.debug(f);u.info("Parsing outputs...");return s.ParseOutputs(f)})}t.DeployManagementGroupScope=DeployManagementGroupScope},747:function(e){e.exports=require("fs")},827:function(e,t,n){"use strict";var i=this&&this.__awaiter||function(e,t,n,i){function adopt(e){return e instanceof n?e:new n(function(t){t(e)})}return new(n||(n=Promise))(function(n,r){function fulfilled(e){try{step(i.next(e))}catch(e){r(e)}}function rejected(e){try{step(i["throw"](e))}catch(e){r(e)}}function step(e){e.done?n(e.value):adopt(e.value).then(fulfilled,rejected)}step((i=i.apply(e,t||[])).next())})};var r=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var n in e)if(Object.hasOwnProperty.call(e,n))t[n]=e[n];t["default"]=e;return t};Object.defineProperty(t,"__esModule",{value:true});const o=n(215);const s=r(n(87));const u=r(n(622));var c;(function(e){e[e["Success"]=0]="Success";e[e["Failure"]=1]="Failure"})(c=t.ExitCode||(t.ExitCode={}));function exportVariable(e,t){process.env[e]=t;o.issueCommand("set-env",{name:e},t)}t.exportVariable=exportVariable;function setSecret(e){o.issueCommand("add-mask",{},e)}t.setSecret=setSecret;function addPath(e){o.issueCommand("add-path",{},e);process.env["PATH"]=`${e}${u.delimiter}${process.env["PATH"]}`}t.addPath=addPath;function getInput(e,t){const n=process.env[`INPUT_${e.replace(/ /g,"_").toUpperCase()}`]||"";if(t&&t.required&&!n){throw new Error(`Input required and not supplied: ${e}`)}return n.trim()}t.getInput=getInput;function setOutput(e,t){o.issueCommand("set-output",{name:e},t)}t.setOutput=setOutput;function setFailed(e){process.exitCode=c.Failure;error(e)}t.setFailed=setFailed;function isDebug(){return process.env["RUNNER_DEBUG"]==="1"}t.isDebug=isDebug;function debug(e){o.issueCommand("debug",{},e)}t.debug=debug;function error(e){o.issue("error",e)}t.error=error;function warning(e){o.issue("warning",e)}t.warning=warning;function info(e){process.stdout.write(e+s.EOL)}t.info=info;function startGroup(e){o.issue("group",e)}t.startGroup=startGroup;function endGroup(){o.issue("endgroup")}t.endGroup=endGroup;function group(e,t){return i(this,void 0,void 0,function*(){startGroup(e);let n;try{n=yield t()}finally{endGroup()}return n})}t.group=group;function saveState(e,t){o.issueCommand("save-state",{name:e},t)}t.saveState=saveState;function getState(e){return process.env[`STATE_${e}`]||""}t.getState=getState},860:function(e,t,n){"use strict";var i=this&&this.__awaiter||function(e,t,n,i){function adopt(e){return e instanceof n?e:new n(function(t){t(e)})}return new(n||(n=Promise))(function(n,r){function fulfilled(e){try{step(i.next(e))}catch(e){r(e)}}function rejected(e){try{step(i["throw"](e))}catch(e){r(e)}}function step(e){e.done?n(e.value):adopt(e.value).then(fulfilled,rejected)}step((i=i.apply(e,t||[])).next())})};Object.defineProperty(t,"__esModule",{value:true});const r=n(87);const o=n(614);const s=n(129);const u=n(622);const c=n(51);const l=n(32);const a=process.platform==="win32";class ToolRunner extends o.EventEmitter{constructor(e,t,n){super();if(!e){throw new Error("Parameter 'toolPath' cannot be null or empty.")}this.toolPath=e;this.args=t||[];this.options=n||{}}_debug(e){if(this.options.listeners&&this.options.listeners.debug){this.options.listeners.debug(e)}}_getCommandString(e,t){const n=this._getSpawnFileName();const i=this._getSpawnArgs(e);let r=t?"":"[command]";if(a){if(this._isCmdFile()){r+=n;for(const e of i){r+=` ${e}`}}else if(e.windowsVerbatimArguments){r+=`"${n}"`;for(const e of i){r+=` ${e}`}}else{r+=this._windowsQuoteCmdArg(n);for(const e of i){r+=` ${this._windowsQuoteCmdArg(e)}`}}}else{r+=n;for(const e of i){r+=` ${e}`}}return r}_processLineBuffer(e,t,n){try{let i=t+e.toString();let o=i.indexOf(r.EOL);while(o>-1){const e=i.substring(0,o);n(e);i=i.substring(o+r.EOL.length);o=i.indexOf(r.EOL)}t=i}catch(e){this._debug(`error processing line. Failed with error ${e}`)}}_getSpawnFileName(){if(a){if(this._isCmdFile()){return process.env["COMSPEC"]||"cmd.exe"}}return this.toolPath}_getSpawnArgs(e){if(a){if(this._isCmdFile()){let t=`/D /S /C "${this._windowsQuoteCmdArg(this.toolPath)}`;for(const n of this.args){t+=" ";t+=e.windowsVerbatimArguments?n:this._windowsQuoteCmdArg(n)}t+='"';return[t]}}return this.args}_endsWith(e,t){return e.endsWith(t)}_isCmdFile(){const e=this.toolPath.toUpperCase();return this._endsWith(e,".CMD")||this._endsWith(e,".BAT")}_windowsQuoteCmdArg(e){if(!this._isCmdFile()){return this._uvQuoteCmdArg(e)}if(!e){return'""'}const t=[" ","\t","&","(",")","[","]","{","}","^","=",";","!","'","+",",","`","~","|","<",">",'"'];let n=false;for(const i of e){if(t.some(e=>e===i)){n=true;break}}if(!n){return e}let i='"';let r=true;for(let t=e.length;t>0;t--){i+=e[t-1];if(r&&e[t-1]==="\\"){i+="\\"}else if(e[t-1]==='"'){r=true;i+='"'}else{r=false}}i+='"';return i.split("").reverse().join("")}_uvQuoteCmdArg(e){if(!e){return'""'}if(!e.includes(" ")&&!e.includes("\t")&&!e.includes('"')){return e}if(!e.includes('"')&&!e.includes("\\")){return`"${e}"`}let t='"';let n=true;for(let i=e.length;i>0;i--){t+=e[i-1];if(n&&e[i-1]==="\\"){t+="\\"}else if(e[i-1]==='"'){n=true;t+="\\"}else{n=false}}t+='"';return t.split("").reverse().join("")}_cloneExecOptions(e){e=e||{};const t={cwd:e.cwd||process.cwd(),env:e.env||process.env,silent:e.silent||false,windowsVerbatimArguments:e.windowsVerbatimArguments||false,failOnStdErr:e.failOnStdErr||false,ignoreReturnCode:e.ignoreReturnCode||false,delay:e.delay||1e4};t.outStream=e.outStream||process.stdout;t.errStream=e.errStream||process.stderr;return t}_getSpawnOptions(e,t){e=e||{};const n={};n.cwd=e.cwd;n.env=e.env;n["windowsVerbatimArguments"]=e.windowsVerbatimArguments||this._isCmdFile();if(e.windowsVerbatimArguments){n.argv0=`"${t}"`}return n}exec(){return i(this,void 0,void 0,function*(){if(!l.isRooted(this.toolPath)&&(this.toolPath.includes("/")||a&&this.toolPath.includes("\\"))){this.toolPath=u.resolve(process.cwd(),this.options.cwd||process.cwd(),this.toolPath)}this.toolPath=yield c.which(this.toolPath,true);return new Promise((e,t)=>{this._debug(`exec tool: ${this.toolPath}`);this._debug("arguments:");for(const e of this.args){this._debug(` ${e}`)}const n=this._cloneExecOptions(this.options);if(!n.silent&&n.outStream){n.outStream.write(this._getCommandString(n)+r.EOL)}const i=new ExecState(n,this.toolPath);i.on("debug",e=>{this._debug(e)});const o=this._getSpawnFileName();const u=s.spawn(o,this._getSpawnArgs(n),this._getSpawnOptions(this.options,o));const c="";if(u.stdout){u.stdout.on("data",e=>{if(this.options.listeners&&this.options.listeners.stdout){this.options.listeners.stdout(e)}if(!n.silent&&n.outStream){n.outStream.write(e)}this._processLineBuffer(e,c,e=>{if(this.options.listeners&&this.options.listeners.stdline){this.options.listeners.stdline(e)}})})}const l="";if(u.stderr){u.stderr.on("data",e=>{i.processStderr=true;if(this.options.listeners&&this.options.listeners.stderr){this.options.listeners.stderr(e)}if(!n.silent&&n.errStream&&n.outStream){const t=n.failOnStdErr?n.errStream:n.outStream;t.write(e)}this._processLineBuffer(e,l,e=>{if(this.options.listeners&&this.options.listeners.errline){this.options.listeners.errline(e)}})})}u.on("error",e=>{i.processError=e.message;i.processExited=true;i.processClosed=true;i.CheckComplete()});u.on("exit",e=>{i.processExitCode=e;i.processExited=true;this._debug(`Exit code ${e} received from tool '${this.toolPath}'`);i.CheckComplete()});u.on("close",e=>{i.processExitCode=e;i.processExited=true;i.processClosed=true;this._debug(`STDIO streams have closed for tool '${this.toolPath}'`);i.CheckComplete()});i.on("done",(n,i)=>{if(c.length>0){this.emit("stdline",c)}if(l.length>0){this.emit("errline",l)}u.removeAllListeners();if(n){t(n)}else{e(i)}})})})}}t.ToolRunner=ToolRunner;function argStringToArray(e){const t=[];let n=false;let i=false;let r="";function append(e){if(i&&e!=='"'){r+="\\"}r+=e;i=false}for(let o=0;o0){t.push(r);r=""}continue}append(s)}if(r.length>0){t.push(r.trim())}return t}t.argStringToArray=argStringToArray;class ExecState extends o.EventEmitter{constructor(e,t){super();this.processClosed=false;this.processError="";this.processExitCode=0;this.processExited=false;this.processStderr=false;this.delay=1e4;this.done=false;this.timeout=null;if(!t){throw new Error("toolPath must not be empty")}this.options=e;this.toolPath=t;if(e.delay){this.delay=e.delay}}CheckComplete(){if(this.done){return}if(this.processClosed){this._setResult()}else if(this.processExited){this.timeout=setTimeout(ExecState.HandleTimeout,this.delay,this)}}_debug(e){this.emit("debug",e)}_setResult(){let e;if(this.processExited){if(this.processError){e=new Error(`There was an error when attempting to execute the process '${this.toolPath}'. This may indicate the process failed to start. Error: ${this.processError}`)}else if(this.processExitCode!==0&&!this.options.ignoreReturnCode){e=new Error(`The process '${this.toolPath}' failed with exit code ${this.processExitCode}`)}else if(this.processStderr&&this.options.failOnStdErr){e=new Error(`The process '${this.toolPath}' failed because one or more lines were written to the STDERR stream`)}}if(this.timeout){clearTimeout(this.timeout);this.timeout=null}this.done=true;this.emit("done",e,this.processExitCode)}static HandleTimeout(e){if(e.done){return}if(!e.processClosed&&e.processExited){const t=`The STDIO streams did not close within ${e.delay/1e3} seconds of the exit event from process '${e.toolPath}'. This may indicate a child process inherited the STDIO streams and has not yet exited.`;e._debug(t)}e._setResult()}}},982:function(e,t,n){"use strict";var i=this&&this.__awaiter||function(e,t,n,i){return new(n||(n=Promise))(function(r,o){function fulfilled(e){try{step(i.next(e))}catch(e){o(e)}}function rejected(e){try{step(i["throw"](e))}catch(e){o(e)}}function step(e){e.done?r(e.value):new n(function(t){t(e.value)}).then(fulfilled,rejected)}step((i=i.apply(e,t||[])).next())})};Object.defineProperty(t,"__esModule",{value:true});const r=n(827);const o=n(51);const s=n(191);const u=n(120);const c=n(723);const l=n(718);const a=n(827);function main(){return i(this,void 0,void 0,function*(){const e=yield o.which("az",true);const t=a.getInput("scope")||"resourcegroup";const n=a.getInput("subscriptionId");const i=a.getInput("region");const d=a.getInput("resourceGroupName");const f=a.getInput("template");const p=a.getInput("deploymentMode");const h=a.getInput("deploymentName");const m=a.getInput("parameters");const y=a.getInput("managementGroupId");const g=false;if(t!="managementgroup"){r.info("Changing subscription context...");yield u.exec(`"${e}" account set --subscription ${n}`,[],{silent:true})}let w={};switch(t){case"resourcegroup":w=yield s.DeployResourceGroupScope(e,g,d,f,p,h,m);break;case"managementgroup":w=yield c.DeployManagementGroupScope(e,g,i,f,p,h,m,y);break;case"subscription":w=yield l.DeploySubscriptionScope(e,g,i,f,p,h,m);break;default:throw new Error("Invalid scope. Valid values are: 'resourcegroup', 'managementgroup', 'subscription'")}return w})}t.main=main}}); \ No newline at end of file +module.exports=function(e,t){"use strict";var n={};function __webpack_require__(t){if(n[t]){return n[t].exports}var r=n[t]={i:t,l:false,exports:{}};var i=true;try{e[t].call(r.exports,r,r.exports,__webpack_require__);i=false}finally{if(i)delete n[t]}r.l=true;return r.exports}__webpack_require__.ab=__dirname+"/";function startup(){return __webpack_require__(464)}return startup()}({32:function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){function adopt(e){return e instanceof n?e:new n(function(t){t(e)})}return new(n||(n=Promise))(function(n,i){function fulfilled(e){try{step(r.next(e))}catch(e){i(e)}}function rejected(e){try{step(r["throw"](e))}catch(e){i(e)}}function step(e){e.done?n(e.value):adopt(e.value).then(fulfilled,rejected)}step((r=r.apply(e,t||[])).next())})};var i;Object.defineProperty(t,"__esModule",{value:true});const o=n(357);const s=n(747);const u=n(622);i=s.promises,t.chmod=i.chmod,t.copyFile=i.copyFile,t.lstat=i.lstat,t.mkdir=i.mkdir,t.readdir=i.readdir,t.readlink=i.readlink,t.rename=i.rename,t.rmdir=i.rmdir,t.stat=i.stat,t.symlink=i.symlink,t.unlink=i.unlink;t.IS_WINDOWS=process.platform==="win32";function exists(e){return r(this,void 0,void 0,function*(){try{yield t.stat(e)}catch(e){if(e.code==="ENOENT"){return false}throw e}return true})}t.exists=exists;function isDirectory(e,n=false){return r(this,void 0,void 0,function*(){const r=n?yield t.stat(e):yield t.lstat(e);return r.isDirectory()})}t.isDirectory=isDirectory;function isRooted(e){e=normalizeSeparators(e);if(!e){throw new Error('isRooted() parameter "p" cannot be empty')}if(t.IS_WINDOWS){return e.startsWith("\\")||/^[A-Z]:/i.test(e)}return e.startsWith("/")}t.isRooted=isRooted;function mkdirP(e,n=1e3,i=1){return r(this,void 0,void 0,function*(){o.ok(e,"a path argument must be provided");e=u.resolve(e);if(i>=n)return t.mkdir(e);try{yield t.mkdir(e);return}catch(r){switch(r.code){case"ENOENT":{yield mkdirP(u.dirname(e),n,i+1);yield t.mkdir(e);return}default:{let n;try{n=yield t.stat(e)}catch(e){throw r}if(!n.isDirectory())throw r}}}})}t.mkdirP=mkdirP;function tryGetExecutablePath(e,n){return r(this,void 0,void 0,function*(){let r=undefined;try{r=yield t.stat(e)}catch(t){if(t.code!=="ENOENT"){console.log(`Unexpected error attempting to determine if executable file exists '${e}': ${t}`)}}if(r&&r.isFile()){if(t.IS_WINDOWS){const t=u.extname(e).toUpperCase();if(n.some(e=>e.toUpperCase()===t)){return e}}else{if(isUnixExecutable(r)){return e}}}const i=e;for(const o of n){e=i+o;r=undefined;try{r=yield t.stat(e)}catch(t){if(t.code!=="ENOENT"){console.log(`Unexpected error attempting to determine if executable file exists '${e}': ${t}`)}}if(r&&r.isFile()){if(t.IS_WINDOWS){try{const n=u.dirname(e);const r=u.basename(e).toUpperCase();for(const i of yield t.readdir(n)){if(r===i.toUpperCase()){e=u.join(n,i);break}}}catch(t){console.log(`Unexpected error attempting to determine the actual case of the file '${e}': ${t}`)}return e}else{if(isUnixExecutable(r)){return e}}}}return""})}t.tryGetExecutablePath=tryGetExecutablePath;function normalizeSeparators(e){e=e||"";if(t.IS_WINDOWS){e=e.replace(/\//g,"\\");return e.replace(/\\\\+/g,"\\")}return e.replace(/\/\/+/g,"/")}function isUnixExecutable(e){return(e.mode&1)>0||(e.mode&8)>0&&e.gid===process.getgid()||(e.mode&64)>0&&e.uid===process.getuid()}},51:function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){function adopt(e){return e instanceof n?e:new n(function(t){t(e)})}return new(n||(n=Promise))(function(n,i){function fulfilled(e){try{step(r.next(e))}catch(e){i(e)}}function rejected(e){try{step(r["throw"](e))}catch(e){i(e)}}function step(e){e.done?n(e.value):adopt(e.value).then(fulfilled,rejected)}step((r=r.apply(e,t||[])).next())})};Object.defineProperty(t,"__esModule",{value:true});const i=n(129);const o=n(622);const s=n(669);const u=n(32);const c=s.promisify(i.exec);function cp(e,t,n={}){return r(this,void 0,void 0,function*(){const{force:r,recursive:i}=readCopyOptions(n);const s=(yield u.exists(t))?yield u.stat(t):null;if(s&&s.isFile()&&!r){return}const c=s&&s.isDirectory()?o.join(t,o.basename(e)):t;if(!(yield u.exists(e))){throw new Error(`no such file or directory: ${e}`)}const a=yield u.stat(e);if(a.isDirectory()){if(!i){throw new Error(`Failed to copy. ${e} is a directory, but tried to copy without recursive flag.`)}else{yield cpDirRecursive(e,c,0,r)}}else{if(o.relative(e,c)===""){throw new Error(`'${c}' and '${e}' are the same file`)}yield copyFile(e,c,r)}})}t.cp=cp;function mv(e,t,n={}){return r(this,void 0,void 0,function*(){if(yield u.exists(t)){let r=true;if(yield u.isDirectory(t)){t=o.join(t,o.basename(e));r=yield u.exists(t)}if(r){if(n.force==null||n.force){yield rmRF(t)}else{throw new Error("Destination already exists")}}}yield mkdirP(o.dirname(t));yield u.rename(e,t)})}t.mv=mv;function rmRF(e){return r(this,void 0,void 0,function*(){if(u.IS_WINDOWS){try{if(yield u.isDirectory(e,true)){yield c(`rd /s /q "${e}"`)}else{yield c(`del /f /a "${e}"`)}}catch(e){if(e.code!=="ENOENT")throw e}try{yield u.unlink(e)}catch(e){if(e.code!=="ENOENT")throw e}}else{let t=false;try{t=yield u.isDirectory(e)}catch(e){if(e.code!=="ENOENT")throw e;return}if(t){yield c(`rm -rf "${e}"`)}else{yield u.unlink(e)}}})}t.rmRF=rmRF;function mkdirP(e){return r(this,void 0,void 0,function*(){yield u.mkdirP(e)})}t.mkdirP=mkdirP;function which(e,t){return r(this,void 0,void 0,function*(){if(!e){throw new Error("parameter 'tool' is required")}if(t){const t=yield which(e,false);if(!t){if(u.IS_WINDOWS){throw new Error(`Unable to locate executable file: ${e}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also verify the file has a valid extension for an executable file.`)}else{throw new Error(`Unable to locate executable file: ${e}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also check the file mode to verify the file is executable.`)}}}try{const t=[];if(u.IS_WINDOWS&&process.env.PATHEXT){for(const e of process.env.PATHEXT.split(o.delimiter)){if(e){t.push(e)}}}if(u.isRooted(e)){const n=yield u.tryGetExecutablePath(e,t);if(n){return n}return""}if(e.includes("/")||u.IS_WINDOWS&&e.includes("\\")){return""}const n=[];if(process.env.PATH){for(const e of process.env.PATH.split(o.delimiter)){if(e){n.push(e)}}}for(const r of n){const n=yield u.tryGetExecutablePath(r+o.sep+e,t);if(n){return n}}return""}catch(e){throw new Error(`which failed with message ${e.message}`)}})}t.which=which;function readCopyOptions(e){const t=e.force==null?true:e.force;const n=Boolean(e.recursive);return{force:t,recursive:n}}function cpDirRecursive(e,t,n,i){return r(this,void 0,void 0,function*(){if(n>=255)return;n++;yield mkdirP(t);const r=yield u.readdir(e);for(const o of r){const r=`${e}/${o}`;const s=`${t}/${o}`;const c=yield u.lstat(r);if(c.isDirectory()){yield cpDirRecursive(r,s,n,i)}else{yield copyFile(r,s,i)}}yield u.chmod(t,(yield u.stat(e)).mode)})}function copyFile(e,t,n){return r(this,void 0,void 0,function*(){if((yield u.lstat(e)).isSymbolicLink()){try{yield u.lstat(t);yield u.unlink(t)}catch(e){if(e.code==="EPERM"){yield u.chmod(t,"0666");yield u.unlink(t)}}const n=yield u.readlink(e);yield u.symlink(n,t,u.IS_WINDOWS?"junction":null)}else if(!(yield u.exists(t))||n){yield u.copyFile(e,t)}})}},87:function(e){e.exports=require("os")},93:function(e,t,n){"use strict";var r=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var n in e)if(Object.hasOwnProperty.call(e,n))t[n]=e[n];t["default"]=e;return t};Object.defineProperty(t,"__esModule",{value:true});const i=r(n(827));function ParseOutputs(e){var t=JSON.parse(e);var n=t.properties.outputs;for(const e in n){if(n.hasOwnProperty(e)){i.setOutput(e,n[e].value)}}return n}t.ParseOutputs=ParseOutputs},120:function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){function adopt(e){return e instanceof n?e:new n(function(t){t(e)})}return new(n||(n=Promise))(function(n,i){function fulfilled(e){try{step(r.next(e))}catch(e){i(e)}}function rejected(e){try{step(r["throw"](e))}catch(e){i(e)}}function step(e){e.done?n(e.value):adopt(e.value).then(fulfilled,rejected)}step((r=r.apply(e,t||[])).next())})};Object.defineProperty(t,"__esModule",{value:true});const i=n(860);function exec(e,t,n){return r(this,void 0,void 0,function*(){const r=i.argStringToArray(e);if(r.length===0){throw new Error(`Parameter 'commandLine' cannot be null or empty.`)}const o=r[0];t=r.slice(1).concat(t||[]);const s=new i.ToolRunner(o,t,n);return s.exec()})}t.exec=exec},124:function(e,t,n){"use strict";var r=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var n in e)if(Object.hasOwnProperty.call(e,n))t[n]=e[n];t["default"]=e;return t};Object.defineProperty(t,"__esModule",{value:true});const i=r(n(747));const o=r(n(87));const s=n(127);function issueCommand(e,t){const n=process.env[`GITHUB_${e}`];if(!n){throw new Error(`Unable to find environment variable for file command ${e}`)}if(!i.existsSync(n)){throw new Error(`Missing file at path: ${n}`)}i.appendFileSync(n,`${s.toCommandValue(t)}${o.EOL}`,{encoding:"utf8"})}t.issueCommand=issueCommand},127:function(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:true});function toCommandValue(e){if(e===null||e===undefined){return""}else if(typeof e==="string"||e instanceof String){return e}return JSON.stringify(e)}t.toCommandValue=toCommandValue},129:function(e){e.exports=require("child_process")},191:function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))(function(i,o){function fulfilled(e){try{step(r.next(e))}catch(e){o(e)}}function rejected(e){try{step(r["throw"](e))}catch(e){o(e)}}function step(e){e.done?i(e.value):new n(function(t){t(e.value)}).then(fulfilled,rejected)}step((r=r.apply(e,t||[])).next())})};var i=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var n in e)if(Object.hasOwnProperty.call(e,n))t[n]=e[n];t["default"]=e;return t};Object.defineProperty(t,"__esModule",{value:true});const o=i(n(827));const s=n(120);const u=n(93);function DeployResourceGroupScope(e,t,n,i,c,a){return r(this,void 0,void 0,function*(){if(!t){throw Error("ResourceGroup name must be set.")}var r=yield s.exec(`"${e}" group show --resource-group ${t}`,[],{silent:true,ignoreReturnCode:true});if(r!=0){throw Error(`Resource Group ${t} could not be found.`)}const l=[t?`--resource-group ${t}`:undefined,n?n.startsWith("http")?`--template-uri ${n}`:`--template-file ${n}`:undefined,i&&i!="validate"?`--mode ${i}`:"--mode Incremental",c?`--name "${c}"`:undefined,a?`--parameters ${a}`:undefined].filter(Boolean).join(" ");let d="";const f={silent:true,ignoreReturnCode:true,failOnStdErr:true,listeners:{stderr:e=>{o.error(e.toString())},stdline:e=>{if(!e.startsWith("[command]"))d+=e}}};const p={silent:true,ignoreReturnCode:true,listeners:{stderr:e=>{o.warning(e.toString())}}};o.info("Validating template...");var h=yield s.exec(`"${e}" deployment group validate ${l} -o json`,[],p);if(i==="validate"&&h!=0){throw new Error("Template validation failed.")}else if(h!=0){o.warning("Template validation failed.")}if(i!="validate"){o.info("Creating deployment...");var m=yield s.exec(`"${e}" deployment group create ${l} -o json`,[],f);if(m!=0){o.error("Deployment failed.")}o.debug(d);o.info("Parsing outputs...");return u.ParseOutputs(d)}return{}})}t.DeployResourceGroupScope=DeployResourceGroupScope},215:function(e,t,n){"use strict";var r=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var n in e)if(Object.hasOwnProperty.call(e,n))t[n]=e[n];t["default"]=e;return t};Object.defineProperty(t,"__esModule",{value:true});const i=r(n(87));const o=n(127);function issueCommand(e,t,n){const r=new Command(e,t,n);process.stdout.write(r.toString()+i.EOL)}t.issueCommand=issueCommand;function issue(e,t=""){issueCommand(e,{},t)}t.issue=issue;const s="::";class Command{constructor(e,t,n){if(!e){e="missing.command"}this.command=e;this.properties=t;this.message=n}toString(){let e=s+this.command;if(this.properties&&Object.keys(this.properties).length>0){e+=" ";let t=true;for(const n in this.properties){if(this.properties.hasOwnProperty(n)){const r=this.properties[n];if(r){if(t){t=false}else{e+=","}e+=`${n}=${escapeProperty(r)}`}}}}e+=`${s}${escapeData(this.message)}`;return e}}function escapeData(e){return o.toCommandValue(e).replace(/%/g,"%25").replace(/\r/g,"%0D").replace(/\n/g,"%0A")}function escapeProperty(e){return o.toCommandValue(e).replace(/%/g,"%25").replace(/\r/g,"%0D").replace(/\n/g,"%0A").replace(/:/g,"%3A").replace(/,/g,"%2C")}},357:function(e){e.exports=require("assert")},464:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:true});const r=n(827);const i=n(982);i.main().then(()=>{process.exit(0)}).catch(e=>{r.setFailed(e.message);process.exit(1)})},614:function(e){e.exports=require("events")},622:function(e){e.exports=require("path")},669:function(e){e.exports=require("util")},718:function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))(function(i,o){function fulfilled(e){try{step(r.next(e))}catch(e){o(e)}}function rejected(e){try{step(r["throw"](e))}catch(e){o(e)}}function step(e){e.done?i(e.value):new n(function(t){t(e.value)}).then(fulfilled,rejected)}step((r=r.apply(e,t||[])).next())})};var i=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var n in e)if(Object.hasOwnProperty.call(e,n))t[n]=e[n];t["default"]=e;return t};Object.defineProperty(t,"__esModule",{value:true});const o=n(120);const s=n(93);const u=i(n(827));function DeploySubscriptionScope(e,t,n,i,c,a){return r(this,void 0,void 0,function*(){if(!t){throw Error("Region must be set.")}if(i&&i!="validate"){u.warning("This deployment mode is not supported for subscription scoped deployments, this parameter will be ignored!")}const r=[t?`--location "${t}"`:undefined,n?n.startsWith("http")?`--template-uri ${n}`:`--template-file ${n}`:undefined,c?`--name "${c}"`:undefined,a?`--parameters ${a}`:undefined].filter(Boolean).join(" ");let l="";const d={silent:true,ignoreReturnCode:true,failOnStdErr:true,listeners:{stderr:e=>{u.error(e.toString())},stdline:e=>{if(!e.startsWith("[command]"))l+=e}}};const f={silent:true,ignoreReturnCode:true,listeners:{stderr:e=>{u.warning(e.toString())}}};u.info("Validating template...");var p=yield o.exec(`"${e}" deployment sub validate ${r} -o json`,[],f);if(i==="validate"&&p!=0){throw new Error("Template validation failed.")}else if(p!=0){u.warning("Template validation failed.")}if(i!="validate"){u.info("Creating deployment...");var h=yield o.exec(`"${e}" deployment sub create ${r} -o json`,[],d);if(h!=0){u.error("Deployment failed.")}u.debug(l);u.info("Parsing outputs...");return s.ParseOutputs(l)}return{}})}t.DeploySubscriptionScope=DeploySubscriptionScope},723:function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))(function(i,o){function fulfilled(e){try{step(r.next(e))}catch(e){o(e)}}function rejected(e){try{step(r["throw"](e))}catch(e){o(e)}}function step(e){e.done?i(e.value):new n(function(t){t(e.value)}).then(fulfilled,rejected)}step((r=r.apply(e,t||[])).next())})};var i=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var n in e)if(Object.hasOwnProperty.call(e,n))t[n]=e[n];t["default"]=e;return t};Object.defineProperty(t,"__esModule",{value:true});const o=n(120);const s=n(93);const u=i(n(827));function DeployManagementGroupScope(e,t,n,i,c,a,l){return r(this,void 0,void 0,function*(){if(!t){throw Error("Region must be set.")}if(i&&i!="validate"){u.warning("This deployment mode is not supported for management group scoped deployments, this parameter will be ignored!")}const r=[t?`--location "${t}"`:undefined,n?n.startsWith("http")?`--template-uri ${n}`:`--template-file ${n}`:undefined,l?`--management-group-id "${l}"`:undefined,c?`--name "${c}"`:undefined,a?`--parameters ${a}`:undefined].filter(Boolean).join(" ");let d="";const f={silent:true,ignoreReturnCode:true,failOnStdErr:true,listeners:{stderr:e=>{u.error(e.toString())},stdline:e=>{if(!e.startsWith("[command]"))d+=e}}};const p={silent:true,ignoreReturnCode:true,listeners:{stderr:e=>{u.warning(e.toString())}}};u.info("Validating template...");var h=yield o.exec(`"${e}" deployment mg validate ${r} -o json`,[],p);if(i==="validate"&&h!=0){throw new Error("Template validation failed.")}else if(h!=0){u.warning("Template validation failed.")}if(i!="validate"){u.info("Creating deployment...");var m=yield o.exec(`"${e}" deployment mg create ${r} -o json`,[],f);if(m!=0){u.error("Deployment failed.")}u.debug(d);u.info("Parsing outputs...");return s.ParseOutputs(d)}return{}})}t.DeployManagementGroupScope=DeployManagementGroupScope},747:function(e){e.exports=require("fs")},827:function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){function adopt(e){return e instanceof n?e:new n(function(t){t(e)})}return new(n||(n=Promise))(function(n,i){function fulfilled(e){try{step(r.next(e))}catch(e){i(e)}}function rejected(e){try{step(r["throw"](e))}catch(e){i(e)}}function step(e){e.done?n(e.value):adopt(e.value).then(fulfilled,rejected)}step((r=r.apply(e,t||[])).next())})};var i=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var n in e)if(Object.hasOwnProperty.call(e,n))t[n]=e[n];t["default"]=e;return t};Object.defineProperty(t,"__esModule",{value:true});const o=n(215);const s=n(124);const u=n(127);const c=i(n(87));const a=i(n(622));var l;(function(e){e[e["Success"]=0]="Success";e[e["Failure"]=1]="Failure"})(l=t.ExitCode||(t.ExitCode={}));function exportVariable(e,t){const n=u.toCommandValue(t);process.env[e]=n;const r=process.env["GITHUB_ENV"]||"";if(r){const t="_GitHubActionsFileCommandDelimeter_";const r=`${e}<<${t}${c.EOL}${n}${c.EOL}${t}`;s.issueCommand("ENV",r)}else{o.issueCommand("set-env",{name:e},n)}}t.exportVariable=exportVariable;function setSecret(e){o.issueCommand("add-mask",{},e)}t.setSecret=setSecret;function addPath(e){const t=process.env["GITHUB_PATH"]||"";if(t){s.issueCommand("PATH",e)}else{o.issueCommand("add-path",{},e)}process.env["PATH"]=`${e}${a.delimiter}${process.env["PATH"]}`}t.addPath=addPath;function getInput(e,t){const n=process.env[`INPUT_${e.replace(/ /g,"_").toUpperCase()}`]||"";if(t&&t.required&&!n){throw new Error(`Input required and not supplied: ${e}`)}return n.trim()}t.getInput=getInput;function setOutput(e,t){o.issueCommand("set-output",{name:e},t)}t.setOutput=setOutput;function setCommandEcho(e){o.issue("echo",e?"on":"off")}t.setCommandEcho=setCommandEcho;function setFailed(e){process.exitCode=l.Failure;error(e)}t.setFailed=setFailed;function isDebug(){return process.env["RUNNER_DEBUG"]==="1"}t.isDebug=isDebug;function debug(e){o.issueCommand("debug",{},e)}t.debug=debug;function error(e){o.issue("error",e instanceof Error?e.toString():e)}t.error=error;function warning(e){o.issue("warning",e instanceof Error?e.toString():e)}t.warning=warning;function info(e){process.stdout.write(e+c.EOL)}t.info=info;function startGroup(e){o.issue("group",e)}t.startGroup=startGroup;function endGroup(){o.issue("endgroup")}t.endGroup=endGroup;function group(e,t){return r(this,void 0,void 0,function*(){startGroup(e);let n;try{n=yield t()}finally{endGroup()}return n})}t.group=group;function saveState(e,t){o.issueCommand("save-state",{name:e},t)}t.saveState=saveState;function getState(e){return process.env[`STATE_${e}`]||""}t.getState=getState},860:function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){function adopt(e){return e instanceof n?e:new n(function(t){t(e)})}return new(n||(n=Promise))(function(n,i){function fulfilled(e){try{step(r.next(e))}catch(e){i(e)}}function rejected(e){try{step(r["throw"](e))}catch(e){i(e)}}function step(e){e.done?n(e.value):adopt(e.value).then(fulfilled,rejected)}step((r=r.apply(e,t||[])).next())})};Object.defineProperty(t,"__esModule",{value:true});const i=n(87);const o=n(614);const s=n(129);const u=n(622);const c=n(51);const a=n(32);const l=process.platform==="win32";class ToolRunner extends o.EventEmitter{constructor(e,t,n){super();if(!e){throw new Error("Parameter 'toolPath' cannot be null or empty.")}this.toolPath=e;this.args=t||[];this.options=n||{}}_debug(e){if(this.options.listeners&&this.options.listeners.debug){this.options.listeners.debug(e)}}_getCommandString(e,t){const n=this._getSpawnFileName();const r=this._getSpawnArgs(e);let i=t?"":"[command]";if(l){if(this._isCmdFile()){i+=n;for(const e of r){i+=` ${e}`}}else if(e.windowsVerbatimArguments){i+=`"${n}"`;for(const e of r){i+=` ${e}`}}else{i+=this._windowsQuoteCmdArg(n);for(const e of r){i+=` ${this._windowsQuoteCmdArg(e)}`}}}else{i+=n;for(const e of r){i+=` ${e}`}}return i}_processLineBuffer(e,t,n){try{let r=t+e.toString();let o=r.indexOf(i.EOL);while(o>-1){const e=r.substring(0,o);n(e);r=r.substring(o+i.EOL.length);o=r.indexOf(i.EOL)}t=r}catch(e){this._debug(`error processing line. Failed with error ${e}`)}}_getSpawnFileName(){if(l){if(this._isCmdFile()){return process.env["COMSPEC"]||"cmd.exe"}}return this.toolPath}_getSpawnArgs(e){if(l){if(this._isCmdFile()){let t=`/D /S /C "${this._windowsQuoteCmdArg(this.toolPath)}`;for(const n of this.args){t+=" ";t+=e.windowsVerbatimArguments?n:this._windowsQuoteCmdArg(n)}t+='"';return[t]}}return this.args}_endsWith(e,t){return e.endsWith(t)}_isCmdFile(){const e=this.toolPath.toUpperCase();return this._endsWith(e,".CMD")||this._endsWith(e,".BAT")}_windowsQuoteCmdArg(e){if(!this._isCmdFile()){return this._uvQuoteCmdArg(e)}if(!e){return'""'}const t=[" ","\t","&","(",")","[","]","{","}","^","=",";","!","'","+",",","`","~","|","<",">",'"'];let n=false;for(const r of e){if(t.some(e=>e===r)){n=true;break}}if(!n){return e}let r='"';let i=true;for(let t=e.length;t>0;t--){r+=e[t-1];if(i&&e[t-1]==="\\"){r+="\\"}else if(e[t-1]==='"'){i=true;r+='"'}else{i=false}}r+='"';return r.split("").reverse().join("")}_uvQuoteCmdArg(e){if(!e){return'""'}if(!e.includes(" ")&&!e.includes("\t")&&!e.includes('"')){return e}if(!e.includes('"')&&!e.includes("\\")){return`"${e}"`}let t='"';let n=true;for(let r=e.length;r>0;r--){t+=e[r-1];if(n&&e[r-1]==="\\"){t+="\\"}else if(e[r-1]==='"'){n=true;t+="\\"}else{n=false}}t+='"';return t.split("").reverse().join("")}_cloneExecOptions(e){e=e||{};const t={cwd:e.cwd||process.cwd(),env:e.env||process.env,silent:e.silent||false,windowsVerbatimArguments:e.windowsVerbatimArguments||false,failOnStdErr:e.failOnStdErr||false,ignoreReturnCode:e.ignoreReturnCode||false,delay:e.delay||1e4};t.outStream=e.outStream||process.stdout;t.errStream=e.errStream||process.stderr;return t}_getSpawnOptions(e,t){e=e||{};const n={};n.cwd=e.cwd;n.env=e.env;n["windowsVerbatimArguments"]=e.windowsVerbatimArguments||this._isCmdFile();if(e.windowsVerbatimArguments){n.argv0=`"${t}"`}return n}exec(){return r(this,void 0,void 0,function*(){if(!a.isRooted(this.toolPath)&&(this.toolPath.includes("/")||l&&this.toolPath.includes("\\"))){this.toolPath=u.resolve(process.cwd(),this.options.cwd||process.cwd(),this.toolPath)}this.toolPath=yield c.which(this.toolPath,true);return new Promise((e,t)=>{this._debug(`exec tool: ${this.toolPath}`);this._debug("arguments:");for(const e of this.args){this._debug(` ${e}`)}const n=this._cloneExecOptions(this.options);if(!n.silent&&n.outStream){n.outStream.write(this._getCommandString(n)+i.EOL)}const r=new ExecState(n,this.toolPath);r.on("debug",e=>{this._debug(e)});const o=this._getSpawnFileName();const u=s.spawn(o,this._getSpawnArgs(n),this._getSpawnOptions(this.options,o));const c="";if(u.stdout){u.stdout.on("data",e=>{if(this.options.listeners&&this.options.listeners.stdout){this.options.listeners.stdout(e)}if(!n.silent&&n.outStream){n.outStream.write(e)}this._processLineBuffer(e,c,e=>{if(this.options.listeners&&this.options.listeners.stdline){this.options.listeners.stdline(e)}})})}const a="";if(u.stderr){u.stderr.on("data",e=>{r.processStderr=true;if(this.options.listeners&&this.options.listeners.stderr){this.options.listeners.stderr(e)}if(!n.silent&&n.errStream&&n.outStream){const t=n.failOnStdErr?n.errStream:n.outStream;t.write(e)}this._processLineBuffer(e,a,e=>{if(this.options.listeners&&this.options.listeners.errline){this.options.listeners.errline(e)}})})}u.on("error",e=>{r.processError=e.message;r.processExited=true;r.processClosed=true;r.CheckComplete()});u.on("exit",e=>{r.processExitCode=e;r.processExited=true;this._debug(`Exit code ${e} received from tool '${this.toolPath}'`);r.CheckComplete()});u.on("close",e=>{r.processExitCode=e;r.processExited=true;r.processClosed=true;this._debug(`STDIO streams have closed for tool '${this.toolPath}'`);r.CheckComplete()});r.on("done",(n,r)=>{if(c.length>0){this.emit("stdline",c)}if(a.length>0){this.emit("errline",a)}u.removeAllListeners();if(n){t(n)}else{e(r)}})})})}}t.ToolRunner=ToolRunner;function argStringToArray(e){const t=[];let n=false;let r=false;let i="";function append(e){if(r&&e!=='"'){i+="\\"}i+=e;r=false}for(let o=0;o0){t.push(i);i=""}continue}append(s)}if(i.length>0){t.push(i.trim())}return t}t.argStringToArray=argStringToArray;class ExecState extends o.EventEmitter{constructor(e,t){super();this.processClosed=false;this.processError="";this.processExitCode=0;this.processExited=false;this.processStderr=false;this.delay=1e4;this.done=false;this.timeout=null;if(!t){throw new Error("toolPath must not be empty")}this.options=e;this.toolPath=t;if(e.delay){this.delay=e.delay}}CheckComplete(){if(this.done){return}if(this.processClosed){this._setResult()}else if(this.processExited){this.timeout=setTimeout(ExecState.HandleTimeout,this.delay,this)}}_debug(e){this.emit("debug",e)}_setResult(){let e;if(this.processExited){if(this.processError){e=new Error(`There was an error when attempting to execute the process '${this.toolPath}'. This may indicate the process failed to start. Error: ${this.processError}`)}else if(this.processExitCode!==0&&!this.options.ignoreReturnCode){e=new Error(`The process '${this.toolPath}' failed with exit code ${this.processExitCode}`)}else if(this.processStderr&&this.options.failOnStdErr){e=new Error(`The process '${this.toolPath}' failed because one or more lines were written to the STDERR stream`)}}if(this.timeout){clearTimeout(this.timeout);this.timeout=null}this.done=true;this.emit("done",e,this.processExitCode)}static HandleTimeout(e){if(e.done){return}if(!e.processClosed&&e.processExited){const t=`The STDIO streams did not close within ${e.delay/1e3} seconds of the exit event from process '${e.toolPath}'. This may indicate a child process inherited the STDIO streams and has not yet exited.`;e._debug(t)}e._setResult()}}},982:function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))(function(i,o){function fulfilled(e){try{step(r.next(e))}catch(e){o(e)}}function rejected(e){try{step(r["throw"](e))}catch(e){o(e)}}function step(e){e.done?i(e.value):new n(function(t){t(e.value)}).then(fulfilled,rejected)}step((r=r.apply(e,t||[])).next())})};Object.defineProperty(t,"__esModule",{value:true});const i=n(827);const o=n(51);const s=n(191);const u=n(120);const c=n(723);const a=n(718);const l=n(827);function main(){return r(this,void 0,void 0,function*(){const e=yield o.which("az",true);const t=l.getInput("scope")||"resourcegroup";const n=l.getInput("subscriptionId");const r=l.getInput("region");const d=l.getInput("resourceGroupName");const f=l.getInput("template");const p=l.getInput("deploymentMode").toLowerCase();const h=l.getInput("deploymentName");const m=l.getInput("parameters");const y=l.getInput("managementGroupId");if(t!=="managementgroup"&&n!==""){i.info("Changing subscription context...");yield u.exec(`"${e}" account set --subscription ${n}`,[],{silent:true})}let g={};switch(t){case"resourcegroup":g=yield s.DeployResourceGroupScope(e,d,f,p,h,m);break;case"managementgroup":g=yield c.DeployManagementGroupScope(e,r,f,p,h,m,y);break;case"subscription":g=yield a.DeploySubscriptionScope(e,r,f,p,h,m);break;default:throw new Error("Invalid scope. Valid values are: 'resourcegroup', 'managementgroup', 'subscription'")}return g})}t.main=main}}); \ No newline at end of file diff --git a/examples/Advanced.md b/examples/Advanced.md index 39ca70d..239b5fe 100644 --- a/examples/Advanced.md +++ b/examples/Advanced.md @@ -4,11 +4,10 @@ Our template has two outputs `location` and `containerName`. But we are only int ## Steps ```yaml -- uses: whiteducksoftware/azure-arm-action-js@v3 +- uses: azure/arm-deploy@v1 id: deploy with: scope: resourcegroup - subscriptionId: e1046c08-7072-****-****-************ resourceGroupName: azurearmaction template: examples/template/template.json parameters: examples/template/parameters.json @@ -37,11 +36,10 @@ we can see that on the console will be `github-action` printed. Now we add our second deployment which relies on that value and modfies the `containerName` parameter, ```yaml -- uses: whiteducksoftware/azure-arm-action-js@v3 +- uses: azure/arm-deploy@v1 id: deploy2 with: scope: resourcegroup - subscriptionId: e1046c08-7072-****-****-************ resourceGroupName: azurearmaction template: examples/template/template.json parameters: examples/template/parameters.json containerName=${{ steps.deploy.outputs.containerName }}-overriden @@ -51,4 +49,4 @@ Look at the `parameters` section, where we plug in another `parameter.json` File ```yaml - run: echo ${{ steps.deploy2.outputs.containerName }} ``` -we can see that on the console will be `github-action-overriden` printed. \ No newline at end of file +we can see that on the console will be `github-action-overriden` printed. diff --git a/examples/advanced-example.yaml b/examples/advanced-example.yaml index 90acda6..cd2270f 100644 --- a/examples/advanced-example.yaml +++ b/examples/advanced-example.yaml @@ -15,11 +15,10 @@ jobs: with: creds: ${{ secrets.AZURE_CREDENTIALS }} - - uses: whiteducksoftware/azure-arm-action-js@v3 + - uses: azure/arm-deploy@v1 id: deploy with: scope: resourcegroup - subscriptionId: e1046c08-7072-****-****-************ resourceGroupName: azurearmaction template: examples/template/template.json parameters: examples/template/parameters.json @@ -27,14 +26,13 @@ jobs: - run: echo ${{ steps.deploy.outputs.containerName }} - - uses: whiteducksoftware/azure-arm-action-js@v3 + - uses: azure/arm-deploy@v1 id: deploy2 with: scope: resourcegroup - subscriptionId: e1046c08-7072-****-****-************ resourceGroupName: azurearmaction template: examples/template/template.json parameters: examples/template/parameters.json containerName=${{ steps.deploy.outputs.containerName }}-overriden deploymentName: github-advanced-test - - run: echo ${{ steps.deploy2.outputs.containerName }} \ No newline at end of file + - run: echo ${{ steps.deploy2.outputs.containerName }} diff --git a/examples/exampleGuide.md b/examples/exampleGuide.md index 6cfe022..02fb417 100644 --- a/examples/exampleGuide.md +++ b/examples/exampleGuide.md @@ -10,7 +10,6 @@ Different scopes: resourceGroupName**: demoGroup template: examples/template/template.json - There are a lot of [sample templates](https://github.com/Azure/azure-quickstart-templates) available which can be used for deployment. **Subscription** @@ -28,13 +27,16 @@ More [Sample templates](https://github.com/Azure/azure-quickstart-templates/tree scope: managementgroup managementGroupId: demoId region: centralus - template: https://teststorage.blob.......... /template.json - parameters: https://teststorage.blob.......... /parameters.json + template: https://teststorage.blob/template.json + parameters: https://teststorage.blob/parameters.json [Sample templates](https://github.com/Azure/azure-quickstart-templates/tree/master/managementgroup-deployments) can be found here. +**Note:** Parameter value specified in parameter file can be overridden by specifying it along with parameter file name. +Example: + parameters: https://teststorage.blob/parameters.json parameterName=parameterValue **Things to keep in mind:** * For all scenarios, you can either paste the template in your repo and provide its location or can use the URI of the template directly. Same thing applies to providing parameters. * Authorization issue can be due to lack of proper access to the secret AZURE_CREDENTIALS. So, ensure that the secret has proper rights. -* DeploymentMode is a parameter required only in case of Resource group deployments. It can either be incremental(default) or complete. \ No newline at end of file +* DeploymentMode is a parameter required only in case of Resource group deployments. It can either be incremental(default) or complete. diff --git a/package-lock.json b/package-lock.json index 50e1345..56b85a7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,9 +5,9 @@ "requires": true, "dependencies": { "@actions/core": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.2.3.tgz", - "integrity": "sha512-Wp4xnyokakM45Uuj4WLUxdsa8fJjKVl1fDTsPbTEcTcuu0Nb26IPQbOtjmnfaCPGcaoPOOqId8H9NapZ8gii4w==" + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.2.6.tgz", + "integrity": "sha512-ZQYitnqiyBc3D+k7LsgSBmMDVkOVidaagDG7j3fOym77jNunWRuYx7VSHa9GNfFZh+zh61xsCjRj4JxMZlDqTA==" }, "@actions/exec": { "version": "1.0.3", diff --git a/package.json b/package.json index 5c101c9..1411313 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "typescript": "^3.8.3" }, "dependencies": { - "@actions/core": "^1.2.3", + "@actions/core": "^1.2.6", "@actions/exec": "^1.0.3", "@actions/io": "^1.0.2", "@types/assert": "^1.4.7", diff --git a/src/deploy/scope_managementgroup.ts b/src/deploy/scope_managementgroup.ts index 7a3a467..a07fbeb 100644 --- a/src/deploy/scope_managementgroup.ts +++ b/src/deploy/scope_managementgroup.ts @@ -3,24 +3,24 @@ import { ExecOptions } from '@actions/exec/lib/interfaces'; import { ParseOutputs, Outputs } from '../utils/utils'; import * as core from '@actions/core'; -export async function DeployManagementGroupScope(azPath: string, validationOnly: boolean, region: string, template: string, deploymentMode: string, deploymentName: string, parameters: string, managementGroupId: string): Promise { +export async function DeployManagementGroupScope(azPath: string, region: string, template: string, deploymentMode: string, deploymentName: string, parameters: string, managementGroupId: string): Promise { // Check if region is set if (!region) { throw Error("Region must be set.") } // check if mode is set as this will be ignored - if (deploymentMode != "") { - core.warning("Deployment Mode is not supported for subscription scoped deployments, this parameter will be ignored!") + if (deploymentMode && deploymentMode != "validate") { + core.warning("This deployment mode is not supported for management group scoped deployments, this parameter will be ignored!") } // create the parameter list const azDeployParameters = [ - region ? `--location ${region}` : undefined, + region ? `--location "${region}"` : undefined, template ? template.startsWith("http") ? `--template-uri ${template}` : `--template-file ${template}` : undefined, - managementGroupId ? `--management-group-id ${managementGroupId}` : undefined, - deploymentName ? `--name ${deploymentName}` : undefined, + managementGroupId ? `--management-group-id "${managementGroupId}"` : undefined, + deploymentName ? `--name "${deploymentName}"` : undefined, parameters ? `--parameters ${parameters}` : undefined ].filter(Boolean).join(' '); @@ -28,10 +28,11 @@ export async function DeployManagementGroupScope(azPath: string, validationOnly: let commandOutput = ''; const deployOptions: ExecOptions = { silent: true, + ignoreReturnCode: true, failOnStdErr: true, listeners: { stderr: (data: BufferSource) => { - core.warning(data.toString()); + core.error(data.toString()); }, stdline: (data: string) => { if (!data.startsWith("[command]")) @@ -53,18 +54,25 @@ export async function DeployManagementGroupScope(azPath: string, validationOnly: // validate the deployment core.info("Validating template...") var code = await exec(`"${azPath}" deployment mg validate ${azDeployParameters} -o json`, [], validateOptions); - if (validationOnly && code != 0) { - throw new Error("Template validation failed") + if (deploymentMode === "validate" && code != 0) { + throw new Error("Template validation failed.") } else if (code != 0) { core.warning("Template validation failed.") } - // execute the deployment - core.info("Creating deployment...") - await exec(`"${azPath}" deployment mg create ${azDeployParameters} -o json`, [], deployOptions); - core.debug(commandOutput); - - // Parse the Outputs - core.info("Parsing outputs...") - return ParseOutputs(commandOutput) -} \ No newline at end of file + if (deploymentMode != "validate") { + // execute the deployment + core.info("Creating deployment...") + var deploymentCode = await exec(`"${azPath}" deployment mg create ${azDeployParameters} -o json`, [], deployOptions); + if (deploymentCode != 0) { + core.error("Deployment failed.") + } + + core.debug(commandOutput); + + // Parse the Outputs + core.info("Parsing outputs...") + return ParseOutputs(commandOutput) + } + return {} +} diff --git a/src/deploy/scope_resourcegroup.ts b/src/deploy/scope_resourcegroup.ts index 24a5df4..cacae6f 100644 --- a/src/deploy/scope_resourcegroup.ts +++ b/src/deploy/scope_resourcegroup.ts @@ -3,7 +3,7 @@ import { exec } from '@actions/exec'; import { ExecOptions } from '@actions/exec/lib/interfaces'; import { ParseOutputs, Outputs } from '../utils/utils'; -export async function DeployResourceGroupScope(azPath: string, validationOnly: boolean, resourceGroupName: string, template: string, deploymentMode: string, deploymentName: string, parameters: string): Promise { +export async function DeployResourceGroupScope(azPath: string, resourceGroupName: string, template: string, deploymentMode: string, deploymentName: string, parameters: string): Promise { // Check if resourceGroupName is set if (!resourceGroupName) { throw Error("ResourceGroup name must be set.") @@ -21,8 +21,8 @@ export async function DeployResourceGroupScope(azPath: string, validationOnly: b template ? template.startsWith("http") ? `--template-uri ${template}` : `--template-file ${template}` : undefined, - deploymentMode ? `--mode ${deploymentMode}` : undefined, - deploymentName ? `--name ${deploymentName}` : undefined, + deploymentMode && deploymentMode != "validate" ? `--mode ${deploymentMode}` : "--mode Incremental", + deploymentName ? `--name "${deploymentName}"` : undefined, parameters ? `--parameters ${parameters}` : undefined ].filter(Boolean).join(' '); @@ -30,10 +30,11 @@ export async function DeployResourceGroupScope(azPath: string, validationOnly: b let commandOutput = ''; const deployOptions: ExecOptions = { silent: true, + ignoreReturnCode: true, failOnStdErr: true, listeners: { stderr: (data: BufferSource) => { - core.warning(data.toString()); + core.error(data.toString()); }, stdline: (data: string) => { if (!data.startsWith("[command]")) @@ -55,18 +56,24 @@ export async function DeployResourceGroupScope(azPath: string, validationOnly: b // validate the deployment core.info("Validating template...") var code = await exec(`"${azPath}" deployment group validate ${azDeployParameters} -o json`, [], validateOptions); - if (validationOnly && code != 0) { - throw new Error("Template validation failed") + if (deploymentMode === "validate" && code != 0) { + throw new Error("Template validation failed.") } else if (code != 0) { core.warning("Template validation failed.") } - // execute the deployment - core.info("Creating deployment...") - await exec(`"${azPath}" deployment group create ${azDeployParameters} -o json`, [], deployOptions); - core.debug(commandOutput); - - // Parse the Outputs - core.info("Parsing outputs...") - return ParseOutputs(commandOutput) + if (deploymentMode != "validate") { + // execute the deployment + core.info("Creating deployment...") + var deploymentCode = await exec(`"${azPath}" deployment group create ${azDeployParameters} -o json`, [], deployOptions); + if (deploymentCode != 0) { + core.error("Deployment failed.") + } + core.debug(commandOutput); + + // Parse the Outputs + core.info("Parsing outputs...") + return ParseOutputs(commandOutput) + } + return {} } diff --git a/src/deploy/scope_subscription.ts b/src/deploy/scope_subscription.ts index c27dd3a..c5426ff 100644 --- a/src/deploy/scope_subscription.ts +++ b/src/deploy/scope_subscription.ts @@ -3,24 +3,24 @@ import { ExecOptions } from '@actions/exec/lib/interfaces'; import { ParseOutputs, Outputs } from '../utils/utils'; import * as core from '@actions/core'; -export async function DeploySubscriptionScope(azPath: string, validationOnly: boolean, region: string, template: string, deploymentMode: string, deploymentName: string, parameters: string): Promise { +export async function DeploySubscriptionScope(azPath: string, region: string, template: string, deploymentMode: string, deploymentName: string, parameters: string): Promise { // Check if region is set if (!region) { throw Error("Region must be set.") } // check if mode is set as this will be ignored - if (deploymentMode != "") { - core.warning("Deployment Mode is not supported for subscription scoped deployments, this parameter will be ignored!") + if (deploymentMode && deploymentMode != "validate") { + core.warning("This deployment mode is not supported for subscription scoped deployments, this parameter will be ignored!") } // create the parameter list const azDeployParameters = [ - region ? `--location ${region}` : undefined, + region ? `--location "${region}"` : undefined, template ? template.startsWith("http") ? `--template-uri ${template}` : `--template-file ${template}` : undefined, - deploymentName ? `--name ${deploymentName}` : undefined, + deploymentName ? `--name "${deploymentName}"` : undefined, parameters ? `--parameters ${parameters}` : undefined ].filter(Boolean).join(' '); @@ -28,10 +28,11 @@ export async function DeploySubscriptionScope(azPath: string, validationOnly: bo let commandOutput = ''; const deployOptions: ExecOptions = { silent: true, + ignoreReturnCode: true, failOnStdErr: true, listeners: { stderr: (data: BufferSource) => { - core.warning(data.toString()); + core.error(data.toString()); }, stdline: (data: string) => { if (!data.startsWith("[command]")) @@ -53,18 +54,24 @@ export async function DeploySubscriptionScope(azPath: string, validationOnly: bo // validate the deployment core.info("Validating template...") var code = await exec(`"${azPath}" deployment sub validate ${azDeployParameters} -o json`, [], validateOptions); - if (validationOnly && code != 0) { - throw new Error("Template validation failed") + if (deploymentMode === "validate" && code != 0) { + throw new Error("Template validation failed.") } else if (code != 0) { core.warning("Template validation failed.") } - // execute the deployment - core.info("Creating deployment...") - await exec(`"${azPath}" deployment sub create ${azDeployParameters} -o json`, [], deployOptions); - core.debug(commandOutput); - - // Parse the Outputs - core.info("Parsing outputs...") - return ParseOutputs(commandOutput) + if (deploymentMode != "validate") { + // execute the deployment + core.info("Creating deployment...") + var deploymentCode = await exec(`"${azPath}" deployment sub create ${azDeployParameters} -o json`, [], deployOptions); + if (deploymentCode != 0) { + core.error("Deployment failed.") + } + core.debug(commandOutput); + + // Parse the Outputs + core.info("Parsing outputs...") + return ParseOutputs(commandOutput) + } + return {} } \ No newline at end of file diff --git a/src/main.ts b/src/main.ts index 6217c6c..bc3d7d2 100644 --- a/src/main.ts +++ b/src/main.ts @@ -18,14 +18,13 @@ export async function main(): Promise { const region = getInput('region') const resourceGroupName = getInput('resourceGroupName') const template = getInput('template') - const deploymentMode = getInput('deploymentMode') + const deploymentMode = getInput('deploymentMode').toLowerCase() const deploymentName = getInput('deploymentName') const parameters = getInput('parameters') const managementGroupId = getInput('managementGroupId') - const validationOnly = false; // change the subscription context - if (scope != "managementgroup") { + if (scope !== "managementgroup" && subscriptionId !== "") { info("Changing subscription context...") await exec(`"${azPath}" account set --subscription ${subscriptionId}`, [], { silent: true }) } @@ -34,13 +33,13 @@ export async function main(): Promise { let result: Outputs = {}; switch(scope) { case "resourcegroup": - result = await DeployResourceGroupScope(azPath, validationOnly, resourceGroupName, template, deploymentMode, deploymentName, parameters) + result = await DeployResourceGroupScope(azPath, resourceGroupName, template, deploymentMode, deploymentName, parameters) break case "managementgroup": - result = await DeployManagementGroupScope(azPath, validationOnly, region, template, deploymentMode, deploymentName, parameters, managementGroupId) + result = await DeployManagementGroupScope(azPath, region, template, deploymentMode, deploymentName, parameters, managementGroupId) break case "subscription": - result = await DeploySubscriptionScope(azPath, validationOnly, region, template, deploymentMode, deploymentName, parameters) + result = await DeploySubscriptionScope(azPath, region, template, deploymentMode, deploymentName, parameters) break default: throw new Error("Invalid scope. Valid values are: 'resourcegroup', 'managementgroup', 'subscription'") diff --git a/test/main.tests.ts b/test/main.tests.ts index 9d86cff..43e90b6 100644 --- a/test/main.tests.ts +++ b/test/main.tests.ts @@ -4,9 +4,10 @@ import * as assert from 'assert'; // Unit Tests export async function runTests() { let result = await main() - assert.equal(Object.keys(result).length, 2, `Expected output count of 2 but got ${Object.keys(result).length}`) - assert.equal(result["containerName"].value, "github-action", `Got invalid value for location key, expected github-action but got ${result["containerName"].value}`) - assert.equal(result["location"].value, "westeurope", `Got invalid value for location key, expected westeurope but got ${result["location"].value}`) + if(result) + { + console.log(result) + } } runTests().catch(e => { diff --git a/test/parameters.json b/test/parameters.json index ad8ba24..7a7f909 100644 --- a/test/parameters.json +++ b/test/parameters.json @@ -1,41 +1,9 @@ { - "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", "contentVersion": "1.0.0.0", "parameters": { - "containerName": { - "value": "github-action" - }, - "region": { - "value": "westeurope" - }, - "imageType": { - "value": "Public" - }, - "imageName": { - "value": "whiteduck/sample-mvc" - }, - "osType": { - "value": "Linux" - }, - "numberCpuCores": { - "value": "1" - }, - "memory": { - "value": "0.5" - }, - "restartPolicy": { - "value": "OnFailure" - }, - "ipAddressType": { - "value": "Public" - }, - "ports": { - "value": [ - { - "port": "8080", - "protocol": "TCP" - } - ] - } + "targetMG": { + "value": "E2eTestGroupForArmAction" + } } -} + } \ No newline at end of file diff --git a/test/template.json b/test/template.json index 8dfffd6..5918d04 100644 --- a/test/template.json +++ b/test/template.json @@ -1,91 +1,63 @@ { - "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "region": { - "type": "string" - }, - "containerName": { - "type": "string" - }, - "imageType": { - "type": "string", - "allowedValues": [ - "Public", - "Private" - ] - }, - "imageName": { - "type": "string" - }, - "osType": { - "type": "string", - "allowedValues": [ - "Linux", - "Windows" - ] - }, - "numberCpuCores": { - "type": "string" - }, - "memory": { - "type": "string" - }, - "restartPolicy": { - "type": "string", - "allowedValues": [ - "OnFailure", - "Always", - "Never" - ] - }, - "ipAddressType": { - "type": "string" - }, - "ports": { - "type": "array" - } - }, - "resources": [ - { - "region": "[parameters('region')]", - "name": "[parameters('containerName')]", - "type": "Microsoft.ContainerInstance/containerGroups", - "apiVersion": "2018-10-01", - "properties": { - "containers": [ - { - "name": "[parameters('containerName')]", - "properties": { - "image": "[parameters('imageName')]", - "resources": { - "requests": { - "cpu": "[int(parameters('numberCpuCores'))]", - "memoryInGB": "[float(parameters('memory'))]" - } - }, - "ports": "[parameters('ports')]" - } - } - ], - "restartPolicy": "[parameters('restartPolicy')]", - "osType": "[parameters('osType')]", - "ipAddress": { - "type": "[parameters('ipAddressType')]", - "ports": "[parameters('ports')]" - } - }, - "tags": {} - } - ], - "outputs": { - "region": { - "type": "string", - "value": "[parameters('region')]" - }, - "containerName": { - "type": "string", - "value": "[parameters('containerName')]" - } - } -} + "$schema": "https://schema.management.azure.com/schemas/2019-08-01/managementGroupDeploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "targetMG": { + "type": "string", + "metadata": { + "description": "Target Management Group" + } + }, + "allowedLocations": { + "type": "array", + "defaultValue": [ + "australiaeast", + "australiasoutheast", + "australiacentral" + ], + "metadata": { + "description": "An array of the allowed locations, all other locations will be denied by the created policy." + } + } + }, + "variables": { + "mgScope": "[tenantResourceId('Microsoft.Management/managementGroups', parameters('targetMG'))]", + "policyDefinition": "LocationRestriction" + }, + "resources": [ + { + "type": "Microsoft.Authorization/policyDefinitions", + "name": "[variables('policyDefinition')]", + "apiVersion": "2019-09-01", + "properties": { + "policyType": "Custom", + "mode": "All", + "parameters": { + }, + "policyRule": { + "if": { + "not": { + "field": "location", + "in": "[parameters('allowedLocations')]" + } + }, + "then": { + "effect": "deny" + } + } + } + }, + { + "type": "Microsoft.Authorization/policyAssignments", + "name": "location-lock", + "apiVersion": "2019-09-01", + "dependsOn": [ + "[variables('policyDefinition')]" + ], + "properties": { + "scope": "[variables('mgScope')]", + "policyDefinitionId": "[extensionResourceId(variables('mgScope'), 'Microsoft.Authorization/policyDefinitions', variables('policyDefinition'))]" + } + } + ] +} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 8a108e1..87c158b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,6 +4,7 @@ // "incremental": true, /* Enable incremental compilation */ "target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */ "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ + "sourceMap": true, // "lib": [], /* Specify library files to be included in the compilation. */ // "allowJs": true, /* Allow javascript files to be compiled. */ // "checkJs": true, /* Report errors in .js files. */