From 7d35a3e5b228ae9e6ef7aca7e963238cc04c7940 Mon Sep 17 00:00:00 2001 From: Wanpeng Yang <97911035+wanpengyang@users.noreply.github.com> Date: Fri, 19 Apr 2024 10:10:19 -0400 Subject: [PATCH] Update to 1.3.0 (#33) * Diagnostic Settings Policies for PaaS services (#143) * Add diagnostic settings policies for data services * Add branch config for testing * Add missing types for auditing * Add diagnostic setting policies for compute services * Add diagnostic setting policies for integration services * Add diagnostic setting policies for network services * Remove policy for ACI since it doesn't have logs to collect * Remove extra resource type * Set region to 'global' for edge services * Remove branch config. used for testing * Updated App Service log categories * Add branch config * Remove branch config * Private Endpoint for App Service (#144) * Flexible policy assignment scope (#147) * Add deployment scope for policy assignment * Add branch test config * Set new parameter for policy assignment scope: var-policyAssignmentManagementGroupId * Update pipeline for new var * Add separate scope for testing * Update pipeline parameter name * Ensure new temp file is created to populate the parameters. * Remove test job * Remove branch config * Update readme * Update authoring guide with new parameter * Removed 'privatelink.monitor.azure.com' from Private DNS Zones (#149) * Automation scripts for Azure DevOps onboarding (#151) Implement #150, scripts and documentation * Snapshot landing zone schema to v0.3.0 (#152) * Enhance PBMM policy assignment to disable diagnostic settings metrics (#156) Ensure diagnostic settings policy only checks for logs * Issue #157 - Update scripts documentation (#158) Update scripts documentation (Issue #157) Update docs/onboarding/azure-devops-scripts.md Co-authored-by: Senthuran Sivananthan * Update Deployment Script's Azure CLI version to 2.32.0 (#164) Update Azure CLI version to 2.32.0 * Update DevOps Onboarding section of main readme (#162) * Repository clean up (#165) * Remove obsolete directory * Rotate resource group names for E2E deployments * Fix typo * Add branch config for testing * Fix typo * Remove branch configs * Remove timestamp from sample JSON templates. Timestamps are kept for E2E testing. * Remove date stamp * Linter: no-loc-expr-outside-params - ensure compliance (#169) * Update linter rules for location parameter * Add location parameter with default value based on resourceGroup() or deployment() * Update archetype schema and docs for location * Add branch config for testing * Update AKS version * Update branch config * Remove branch configs * Support for Tag inheritance from Subscription to Resource Group (#161) * Add policy and policy set to inherit tags from subscription to resource group * Add branch config for testing * Remove policy type as it's not built in * Updated resource type for resource group * Update policy assignment * Ensure assignment name is <= 24 chars * Revert resource group type * Setting mode to all * Update documentation * Add branch config * Add explicit dependsOn for subscription scaffolding to complete * Update test deployment parameters * Remove explicit dependsOn for subscription scaffolding to complete * Update doc to describe approaches for adding tags to RGs * Reduce the options for tagging resources given subscripton to RG tagging is available * Add example scenarios for tag inheritence * Fix typo * Remove branch configs * Resolve linter error: no-loc-expr-outside-params * Instructions for Azure DevOps Environments (#175) * Instructions for creating ADO pipeline environments * Fix formatting * Update `create-pipelines.bat` onboarding script to auto-provision environment (#178) * Update onboarding doc for logging & networking management group settings (#177) * Fix markdown linter warnings * Add instruction for logging and networking MGs * Snapshot JSON schemas to v0.4.0 (#182) * Update onboarding document Co-authored-by: Preston K. Parsard * Configurable management group hierarchy (#186) Implement configurable management group hierarchy * Show Variables fix (#191) * subscription(generic): add instructions for configuring parameters (#193) * Instructions for backfilling management group hierarchy (#197) * Add instructions for backfilling management group hierarchy * Update section titles, links and reference backfill instruction as part of MG setup * Instructions for installing AzCLI and jq * Clearfy that Tenant Root Group could have been renamed in the organization * Windows Shell example * Update instructions to delete pipeline variables that will be automatically created when MG heirarchy is used * Note on YAML indentation * Revise subscription deployment instructions (#201) * Redirect subscriptoin configuration guidance to archetype authoring guide doc * Revise instructions for creating ARM parameter files & management group id selection * Ensure values from multiline variables are properly logged (#202) Print multi-line environment variables (typically JSON objects) in Show Variables step * Fix pipeline scripts reference to `subscription-ci` (#207) * Delete Lock for Log Analytics Workspace resource group (#205) Add delete lock for LAW RG * Support Defender Plan for Cosmos DB (#200) Add CosmosDB Defender Plan and custom policy to deploy Defender Plan for Cosmos DB * fixing doc typo in hubnetwork-azfw (#211) Co-authored-by: Adil Ha * Backward compatibility when setting pipeline variables from management group hierarchy (#213) * Update OZ subnet name to App Management Zone (#217) * Document delete lock usage (#216) Document when and where delete locks are used * Add instructions for customizing policy set assignments (#215) * Fix formatting (#218) * Improve `delete-management-groups.bat` script (#224) * Private DNS Policy - Change Cosmos DB namespace to Microsoft.DocumentDB (#228) * Change Cosmos DB namespace to Microsoft.DocumentDB * Add branch config * Remove branch config * Flexible policy assignment parameters JSON files (#222) * Externalize Log Analytics Workspace parameters when loading pipeline variables (#220) Externalize the log analytics parameters to load arbitary LAW variables * Initial GC 30-day cloud guardrails compliance/guidance (#226) Initial GC 30-day cloud guardrails doc * Update networking documentation for generic subscription archetype (#230) * Use built-in policy for Cosmos DB for Defender Plan (#232) * Use built-in policy for Cosmos DB for Defender Plan * Add branch config * Remove branch config * Updating recommendations to reflect licensing reqs (#229) * Fix order of `platform-connectivity-hub-azfw-policy` pipeline listed in run-pipelines.bat script #233 (#234) * PBMM & HITRUST/HIPAA policy update (#238) * Migrate Logging configuration to JSON parameters file (#236) * Update azure-devops-pipelines.md (#242) * Support logging infrastructure for multiple regions in same subscription (#244) Ensure subscription scoped deployments are unique per region * Support multiple private dns zone configuration when updating private DNS Zones through Azure Policy (#246) Update Private DNS Zone policy to support multiple dnsZoneConfigs * Include new Databricks' log categories for diagnostic settings (#248) Add new databricks' log categories for diagnostic settings * Azure Active Directory support for Synapse (#259) * Migrate Networking configuration to JSON parameters file (#250) * Revise subnet configuration for Generic Subscription archetype (#252) * Revise subnet configuration for Machine Learning archetype (#254) * Revise subnet configuration for Healthcare archetype (#256) * Removed extra configuration files (#260) * Update common.yml example (#262) * Support for optional subnets in Machine Learning & Healthcare archetypes (#264) * Organize deployment parameters for Hub Networking with Azure Firewall (#265) * Updated documentation (#267) * Organize deployment parameters for Hub Networking with NVA (#266) * Snapshot ARM parameters JSON schemas (#268) * PowerShell deployment scripts (#271) * Powershell deployment script for archetypes (#273) Support for deploying subscriptions * Deployment flow diagram (#274) * GitHub workflow implementation (#276) Implement GitHub workflows to deploy the Azure Landing Zones for Canadian Public Sector * Support schema validation (#277) * Add environment configuration override and protect sensitive parameters (#280) * Pass-thru secure strings as-is until ready for use (#281) * Fix DeploySubscriptionIds parameter type casting (#282) * Correct wiring of the subscriptions-ci pipeline and prompt for NVA firewall username & password (#285) * Support jobs in GitHub Actions (#286) * Ensure multiple subscriptions can be moved to a management in parallel (#288) Ensure deployment name for moving subscription is unique * Separate Azure Firewall Policy deployment switch & unique telemetry tracking for policy assignments (#289) * Disable metrics in diagnostic settings for AKS through Policy (#295) * Concurrent role deployment with PowerShell & GitHub Actions (#299) * Disable fail fast for matrix deployments (#297) * Flexible policy deployment using PowerShell & GitHub Actions (#300) * Log Analytics solutions for SQL servers on machines (#303) * Serial defender plan deployments & revised resource/resource group names (#307) * Update resource group names for Logging & Networking (#309) Remove `-rg` suffix * Add service health notification info (#310) * Reference the Guardrails Solution Accelerator for 30-day guardrail assessment (#313) * Fix typo in onboarding guidance (#320) * Update machinelearning.md (#327) * Resolve linter warning: prefer-unquoted-property-names (#322) * Add missing log categories in diagnostic settings for Azure Firewall (#324) * Support azkms.core.windows.net and IPs in firewall allow list (#329) * Support data collection rule (#331) * Network security group support for private endpoints subnet (#333) * Suppress false positive linter warning: secure-secrets-in-params (#335) * Update diagnostic settings profile name (#337) * Revised Event Hub Diagnostic Settings policy (#339) * Version August 2022 schema changes (#342) * Update CODEOWNERS (#344) Adding Barry Willis and Kevin Evans to the CODEOWNERS file for the entire repo * Add Barry to code owners list (#346) * Update hubnetwork-azfw.md (#345) Having domain controllers under the "Connectivity" subscription is an anti-pattern that causes confusion to users. Co-authored-by: Barrington Willis <51492255+tredell@users.noreply.github.com> * Updated documents, from docs.microsoft.com - to Learn. (#350) Updated documents, from docs.microsoft.com - to Learn. * Fixed Linter warnings & build errors (#354) * Fixed BCP321 Linter warning in networking files * Fixed Role Definition Id References to use the ResourceId function * changed the pOlicyScopedId var to be set by using the MGResourceID Function * fixed BCP321 warning * fixed the remaining linter warnings * fixed the remaining linter errors in the policy definitions * updated the linter rules * Fixed Bug on policy defnition * Fixed the AKS policy deployment * Commit 95556ddd: changed the extensionResourceId function to tenantResourceId for all built-in polify definitions * fixed linter warnings in policy files * changed the invalid dummy service alert phone number to a valid phone number * changed the servcie health number prefix to 604 * updated AKS version in the Data Archetypes * Changed hte AKS version to only have the Major.Minor * Added the patch version to the AKS versions in the Data Archetypes * Identity Archetype (#359) * Squashed commit of the following: commit 6d6b3e49855c365f49a4674534b985bacf9cd74c Author: Barry Willis Date: Mon Feb 27 08:07:45 2023 -0800 changed the areacode on the logging service health alerts architype commit 86b4505c2ffd5127978883c0bc6a1f9b0e7d3268 Author: Barry Willis Date: Fri Feb 24 16:39:08 2023 -0800 prepping for testing in ESLZ test environment commit 0f92b6bf70aee1377b4d49db436fa7024f1bfd25 Merge: 2a3584a 7749e7b Author: Barry Willis Date: Fri Feb 24 16:10:37 2023 -0800 Merge remote-tracking branch 'origin/main' into IdentityLZ commit 7749e7bf7a8756e3b2ffd09016e3e9d9954407db Merge: f6555a4 5337654 Author: Barry Willis Date: Fri Feb 24 16:08:54 2023 -0800 Merge remote-tracking branch 'github-CanadaPubSecALZ/main' commit f6555a41227fdbe47a6981798e2cb2bb97bd7cd6 Author: Barry Willis Date: Mon Feb 13 12:30:20 2023 -0800 Added the patch version to the AKS versions in the Data Archetypes commit 8edcb63d833fd177ede60c9a51b6228f448c0c33 Author: Barry Willis Date: Mon Feb 13 11:32:54 2023 -0800 Changed hte AKS version to only have the Major.Minor commit 37123d71623b7c6ed288a5ba32c7cab5f8e75e6f Author: Barry Willis Date: Mon Feb 13 11:17:38 2023 -0800 updated AKS version in the Data Archetypes commit 459b3c62751cb6bfedf2ddc5800ad39137417d38 Author: Barry Willis Date: Mon Feb 13 08:55:13 2023 -0800 changed the servcie health number prefix to 604 commit cccf88662c3a0e0d7b2f625a13ec191053017985 Author: Barry Willis Date: Mon Feb 13 07:42:52 2023 -0800 changed the invalid dummy service alert phone number to a valid phone number commit 8e9628d26e1285c437a6ec8a3ebd479299f3cb5f Author: Barry Willis Date: Mon Feb 13 07:01:36 2023 -0800 fixed linter warnings in policy files commit 6c2b2f7d2d53b97d0014306656406cf564189779 Author: Barry Willis Date: Sat Feb 11 15:36:36 2023 -0800 Commit 95556ddd: changed the extensionResourceId function to tenantResourceId for all built-in polify definitions commit c58ba48f5073c0b86b41c54fddca9cab0368b59a Author: Barry Willis Date: Sat Feb 11 15:09:56 2023 -0800 Fixed the AKS policy deployment commit f9e8418b7e1faf8cc8122acc9414e12c5bfbd22e Author: Barry Willis Date: Sat Feb 11 14:04:22 2023 -0800 Fixed Bug on policy defnition commit 1a3c82e446072db49d927343a4792e30bdb31f05 Author: Barry Willis Date: Fri Feb 10 19:09:02 2023 -0800 updated the linter rules commit 20e188051a8999d7a5e6ee925ec193f6e1d2dea6 Author: Barry Willis Date: Fri Feb 10 18:52:18 2023 -0800 fixed the remaining linter errors in the policy definitions commit 1610a28e355af15a86d8a555a97ca9912cc11aeb Author: Barry Willis Date: Fri Feb 10 18:27:14 2023 -0800 fixed the remaining linter warnings commit 9f0e049fa09e19f0cf312f4826520e1005e58434 Author: Barry Willis Date: Fri Feb 10 17:31:21 2023 -0800 fixed BCP321 warning commit 466d7b0c070f4bb4fef94b1fb9bac2f3da754c4a Author: Barry Willis Date: Fri Feb 10 17:22:46 2023 -0800 changed the pOlicyScopedId var to be set by using the MGResourceID Function commit 9362967e5006d9ec3882cdc5bec5aae5b872bf29 Author: Barry Willis Date: Fri Feb 10 16:48:26 2023 -0800 Fixed Role Definition Id References to use the ResourceId function commit 4bcbc28212ecac9bff2a8e3c720a9a364479733c Author: Barry Willis Date: Fri Feb 10 16:07:33 2023 -0800 Fixed BCP321 Linter warning in networking files commit 2a3584a7cac9c5822c7a226bc8a5d44f52d69a65 Author: Barry Willis Date: Fri Feb 10 15:07:43 2023 -0800 Removed Linter exception BCP321 - will fix in the linter PR commit a0b48ec7710a5ee8023a066e4cb5394074002c1e Author: Barry Willis Date: Fri Feb 10 10:39:36 2023 -0800 Fixed the bugs with conditionally deploying DNS Resolver commit 4f24be78f48465b404c529b276db66496c9958db Author: Barry Willis Date: Wed Feb 8 15:29:38 2023 -0800 Updated documentation and made the DNS Resolver subnets optional commit 03fcb5e50b0670c67d1850063dd828ffa6945cf8 Merge: dfe0d9a 0fa01e8 Author: Barry Willis Date: Mon Feb 6 16:58:41 2023 -0800 Merge remote-tracking branch 'origin/main' into IdentityLZ commit dfe0d9acab086df1d9dfbfbdae5770fbf5da999a Author: Barry Willis Date: Wed Jan 11 15:52:06 2023 -0800 added Schema validation to the identity config file commit fb88630b5d707db6b7f4ab1aa2455ff79920d5b3 Author: Barry Willis Date: Mon Jan 9 10:28:13 2023 -0800 changed the DNS Resolver ruleset to be an object-array commit 78aaf4d6cdeff8d9832d8a309f26c10cefe97a22 Author: Barry Willis Date: Sat Jan 7 13:57:37 2023 -0800 first pass at creating conditional forwarding rulesets in the Identity LZ commit e7b554d04daee83a55a985073ec0c59084c7f3c2 Author: Barry Willis Date: Fri Jan 6 08:54:27 2023 -0800 Configured Subnet Delegation for Az DNS Resolver commit 978ab9925f876945ba02280493f7deba1c07e7ee Author: Barry Willis Date: Thu Jan 5 19:52:24 2023 -0800 added Private DNS Resolver to the Identity LZ commit 9735d58fc04d7a587a76a5387deb112c466390fe Author: Barry Willis Date: Thu Jan 5 13:19:05 2023 -0800 Removed the optional Subnet commit 4cd57ed41a09672b3cfbc1792c2edbdc3569a060 Author: Barry Willis Date: Thu Jan 5 13:09:36 2023 -0800 first cut at the identity LZ framework commit a119eea02fca28a2028362f484aa2835c9313c1d Author: Barry Willis Date: Wed Dec 21 11:54:58 2022 -0800 added identitypathfromroot in the branch config file commit 75b6ccc2ab6efd55037e0a5a938d49f2eef32de4 Author: Barry Willis Date: Wed Dec 21 11:35:12 2022 -0800 Added: identity vars display Changed: location reference to identity param file commit e0cfc41b5a83c4c331689fcafa5edc9928e93d39 Author: Barry Willis Date: Wed Dec 21 11:22:35 2022 -0800 fixed misconfigured working directory commit fb58b16999aeb9cc6b6b81647c76e95024e1267c Author: Barry Willis Date: Wed Dec 21 11:18:46 2022 -0800 removed schema validation to test deployment commit 240189de7e30fa57654c3ec76ec37c762ff80133 Author: Barry Willis Date: Wed Dec 21 11:15:43 2022 -0800 fixed bug - neworking region is now identity region commit 89e63b5976cb5cdc4e85d0b25c01234ffe4853d7 Author: Barry Willis Date: Wed Dec 21 11:11:48 2022 -0800 initial identity lz deployment commit d4b40b26b893b78d7a9250dffe24c3e9ce06d690 Author: Barry Willis Date: Wed Dec 21 11:03:29 2022 -0800 Added default region for Identity Subscription commit 41e611818d09181b1a455f612425cae20f0683f7 Author: Barry Willis Date: Wed Dec 21 08:29:33 2022 -0800 Changed bastion subnet range in identity subnet commit f5a43f2d44803e80db8a043d31e5c9f72fc51675 Author: Barry Willis Date: Wed Dec 21 07:33:03 2022 -0800 Param file for Identity LZ commit 13d084b0fe74f39ca1423b2eb9f333a2b760b1f2 Author: Barry Willis Date: Tue Dec 20 15:19:23 2022 +0000 Deleted identity.parameteres.json commit 5ba9a12fa8e8e02f60f3f2afea43681cc84d7446 Merge: 002b2be e395307 Author: Barry Willis Date: Tue Dec 20 07:18:40 2022 -0800 Merge branch 'IdentityLZ' of https://dev.azure.com/Tredell/CanadaALZ/_git/CanadaALZ into IdentityLZ commit 002b2be1bb5b555a334f35cbb505e7a68f321649 Author: Barry Willis Date: Tue Dec 20 07:18:32 2022 -0800 id-lz - created param section for id lz commit e395307b1c12786cc28cf3d4b00586dde69739d5 Author: Barry Willis Date: Tue Dec 20 07:13:54 2022 -0800 id-lz - created param section for id lz commit 7f4a43eb4fdc7f6f37ebab8e661981cccbee9f50 Author: Barry Willis Date: Mon Dec 19 14:54:57 2022 -0800 disabled privatelink infrastructure to be deployed in hub lz commit db85049ac94b5c394d586b6960343bc1286997f1 Author: Barry Willis Date: Mon Dec 19 14:46:36 2022 -0800 Configured hub networking parameter files commit 8d772e868803d1b712013f7db21044d48ab730d2 Author: Barry Willis Date: Mon Dec 19 14:07:43 2022 -0800 removed comment from json - not supported commit 89cde8d92704f1a41a123af46da6dd90568d99cb Author: Barry Willis Date: Mon Dec 19 12:56:47 2022 -0800 Configuring Policies for deployment to Test enviornment commit ba781ee844a4abd403071e072645988b63ada494 Author: Barry Willis Date: Mon Dec 19 12:40:53 2022 -0800 added a default security Group commit 1269da21e08fdf4c29a53b38a4d18722c64461e0 Author: Barry Willis Date: Mon Dec 19 12:26:14 2022 -0800 setting up logging for my test environment commit 4d6a41f4133380223f5895dba270cbce4ae5a39b Author: Barry Willis Date: Mon Dec 19 12:13:08 2022 -0800 testing the path to the logging configuraiton file commit 75d0b99caf6aed5f809c28566cad35569d78be58 Author: Barry Willis Date: Mon Dec 19 12:00:14 2022 -0800 added the full path to the logging parameters file commit 32e8382bcb8deaaaab0c7bc1c2791483ef439971 Author: Barry Willis Date: Mon Dec 19 11:55:00 2022 -0800 path to logging parameters file was incorrect commit 5757d36a486e7f3b707f00848d19cfe64de83358 Author: Barry Willis Date: Mon Dec 19 11:37:20 2022 -0800 Changed MG Root to match test enviornment commit 1fdd02db1638420decf5ab021fb617b95920aada Author: Barry Willis Date: Mon Dec 19 11:09:46 2022 -0800 Adding config file for IdentityLZ branch * PowerShell Deployment Files created * GitHub Action Pipelines modified to add the Identity Archetype * made the Identity GitHub Action optional * put the boolean option in single quotes * fixed a few bugs (BCP321 & references to the wrong tenant) * changed the sub id for the logging subscription * Removed the hardcoded reference to the LAW in the identity param file * updated the param file with the LAW ID * disabled private dns zone deployment in the identity sub * removed the config files from my custom branch * uncommented the validation in the Identity ADO Pipeline * removed commented trigger code from ADO Identity Pipeline * renenabled the dployment of the DNSPrivateEndPoints policyset * removed the provider registration for containerservices in the deploy-identity-pipeline yaml * added an explanation comment to the dnsforwardingruleset file * Added telemetry tracking for the identity subscription * fixed cut and paste errors * Updated test cases & documentation * added the consistency check & pull request checks for github actions * fixed spelling error * Bug fixes - network routing & ADO Identity Pipelines (#362) * Fixed Bug: missing identityPathFromRoot variable missing * Fixed Bug: Allow Network transit thru the hub * renamed the Subscriptions Yaml * Update DDoS.bicep (#363) Change policySetDefinitions to policyDefinitions for the policyScopedId variable. * Update identity.md (#365) Updated page title to reflect content * Scripts to generate config from template, support JSON config intellisense in editors, fix bugs in deployment scripts (#379) Fixes path normalization bug in deployment scripts #374 Fixes subscription filtering bug in deployment scripts #375 Adds CanadaPubSecALZ configuration JSON schema support for editors #376 Adds Scripts to generate CanadaPubSecALZ configuration files using existing environments as template #377 Adds Deploy landing zones to new Azure subscriptions in new primary tenant #378 * update to 1.3.0 Squashed commit of the following: commit db45632283e6982fb095f6be33540c28ad54960a Author: Steve Keeler Date: Sun Jul 9 23:14:55 2023 -0400 Scripts to generate config from template, support JSON config intellisense in editors, fix bugs in deployment scripts (#379) Fixes path normalization bug in deployment scripts #374 Fixes subscription filtering bug in deployment scripts #375 Adds CanadaPubSecALZ configuration JSON schema support for editors #376 Adds Scripts to generate CanadaPubSecALZ configuration files using existing environments as template #377 Adds Deploy landing zones to new Azure subscriptions in new primary tenant #378 commit 5830bcb63193565ab291076b54765f2d8986f64b Author: David Christiansen Date: Tue Apr 25 21:12:23 2023 +0100 Update identity.md (#365) Updated page title to reflect content commit 674f6cb1e7ee407765eeb9d99a8163ef0a461b32 Author: Yanick Lepine <65724245+ylepine@users.noreply.github.com> Date: Thu Mar 16 13:13:38 2023 -0400 Update DDoS.bicep (#363) Change policySetDefinitions to policyDefinitions for the policyScopedId variable. commit 5680e6582a6c28907898da2026ef3c1f0e56a332 Author: Barrington Willis <51492255+tredell@users.noreply.github.com> Date: Mon Mar 13 06:31:54 2023 -0700 Bug fixes - network routing & ADO Identity Pipelines (#362) * Fixed Bug: missing identityPathFromRoot variable missing * Fixed Bug: Allow Network transit thru the hub * renamed the Subscriptions Yaml commit f13f6ec24f5b8c0f318cf66f6cd1a2f3c7a01534 Author: Barrington Willis <51492255+tredell@users.noreply.github.com> Date: Fri Mar 3 07:00:06 2023 -0800 Identity Archetype (#359) * Squashed commit of the following: commit 6d6b3e49855c365f49a4674534b985bacf9cd74c Author: Barry Willis Date: Mon Feb 27 08:07:45 2023 -0800 changed the areacode on the logging service health alerts architype commit 86b4505c2ffd5127978883c0bc6a1f9b0e7d3268 Author: Barry Willis Date: Fri Feb 24 16:39:08 2023 -0800 prepping for testing in ESLZ test environment commit 0f92b6bf70aee1377b4d49db436fa7024f1bfd25 Merge: 2a3584a 7749e7b Author: Barry Willis Date: Fri Feb 24 16:10:37 2023 -0800 Merge remote-tracking branch 'origin/main' into IdentityLZ commit 7749e7bf7a8756e3b2ffd09016e3e9d9954407db Merge: f6555a4 5337654 Author: Barry Willis Date: Fri Feb 24 16:08:54 2023 -0800 Merge remote-tracking branch 'github-CanadaPubSecALZ/main' commit f6555a41227fdbe47a6981798e2cb2bb97bd7cd6 Author: Barry Willis Date: Mon Feb 13 12:30:20 2023 -0800 Added the patch version to the AKS versions in the Data Archetypes commit 8edcb63d833fd177ede60c9a51b6228f448c0c33 Author: Barry Willis Date: Mon Feb 13 11:32:54 2023 -0800 Changed hte AKS version to only have the Major.Minor commit 37123d71623b7c6ed288a5ba32c7cab5f8e75e6f Author: Barry Willis Date: Mon Feb 13 11:17:38 2023 -0800 updated AKS version in the Data Archetypes commit 459b3c62751cb6bfedf2ddc5800ad39137417d38 Author: Barry Willis Date: Mon Feb 13 08:55:13 2023 -0800 changed the servcie health number prefix to 604 commit cccf88662c3a0e0d7b2f625a13ec191053017985 Author: Barry Willis Date: Mon Feb 13 07:42:52 2023 -0800 changed the invalid dummy service alert phone number to a valid phone number commit 8e9628d26e1285c437a6ec8a3ebd479299f3cb5f Author: Barry Willis Date: Mon Feb 13 07:01:36 2023 -0800 fixed linter warnings in policy files commit 6c2b2f7d2d53b97d0014306656406cf564189779 Author: Barry Willis Date: Sat Feb 11 15:36:36 2023 -0800 Commit 95556ddd: changed the extensionResourceId function to tenantResourceId for all built-in polify definitions commit c58ba48f5073c0b86b41c54fddca9cab0368b59a Author: Barry Willis Date: Sat Feb 11 15:09:56 2023 -0800 Fixed the AKS policy deployment commit f9e8418b7e1faf8cc8122acc9414e12c5bfbd22e Author: Barry Willis Date: Sat Feb 11 14:04:22 2023 -0800 Fixed Bug on policy defnition commit 1a3c82e446072db49d927343a4792e30bdb31f05 Author: Barry Willis Date: Fri Feb 10 19:09:02 2023 -0800 updated the linter rules commit 20e188051a8999d7a5e6ee925ec193f6e1d2dea6 Author: Barry Willis Date: Fri Feb 10 18:52:18 2023 -0800 fixed the remaining linter errors in the policy definitions commit 1610a28e355af15a86d8a555a97ca9912cc11aeb Author: Barry Willis Date: Fri Feb 10 18:27:14 2023 -0800 fixed the remaining linter warnings commit 9f0e049fa09e19f0cf312f4826520e1005e58434 Author: Barry Willis Date: Fri Feb 10 17:31:21 2023 -0800 fixed BCP321 warning commit 466d7b0c070f4bb4fef94b1fb9bac2f3da754c4a Author: Barry Willis Date: Fri Feb 10 17:22:46 2023 -0800 changed the pOlicyScopedId var to be set by using the MGResourceID Function commit 9362967e5006d9ec3882cdc5bec5aae5b872bf29 Author: Barry Willis Date: Fri Feb 10 16:48:26 2023 -0800 Fixed Role Definition Id References to use the ResourceId function commit 4bcbc28212ecac9bff2a8e3c720a9a364479733c Author: Barry Willis Date: Fri Feb 10 16:07:33 2023 -0800 Fixed BCP321 Linter warning in networking files commit 2a3584a7cac9c5822c7a226bc8a5d44f52d69a65 Author: Barry Willis Date: Fri Feb 10 15:07:43 2023 -0800 Removed Linter exception BCP321 - will fix in the linter PR commit a0b48ec7710a5ee8023a066e4cb5394074002c1e Author: Barry Willis Date: Fri Feb 10 10:39:36 2023 -0800 Fixed the bugs with conditionally deploying DNS Resolver commit 4f24be78f48465b404c529b276db66496c9958db Author: Barry Willis Date: Wed Feb 8 15:29:38 2023 -0800 Updated documentation and made the DNS Resolver subnets optional commit 03fcb5e50b0670c67d1850063dd828ffa6945cf8 Merge: dfe0d9a 0fa01e8 Author: Barry Willis Date: Mon Feb 6 16:58:41 2023 -0800 Merge remote-tracking branch 'origin/main' into IdentityLZ commit dfe0d9acab086df1d9dfbfbdae5770fbf5da999a Author: Barry Willis Date: Wed Jan 11 15:52:06 2023 -0800 added Schema validation to the identity config file commit fb88630b5d707db6b7f4ab1aa2455ff79920d5b3 Author: Barry Willis Date: Mon Jan 9 10:28:13 2023 -0800 changed the DNS Resolver ruleset to be an object-array commit 78aaf4d6cdeff8d9832d8a309f26c10cefe97a22 Author: Barry Willis Date: Sat Jan 7 13:57:37 2023 -0800 first pass at creating conditional forwarding rulesets in the Identity LZ commit e7b554d04daee83a55a985073ec0c59084c7f3c2 Author: Barry Willis Date: Fri Jan 6 08:54:27 2023 -0800 Configured Subnet Delegation for Az DNS Resolver commit 978ab9925f876945ba02280493f7deba1c07e7ee Author: Barry Willis Date: Thu Jan 5 19:52:24 2023 -0800 added Private DNS Resolver to the Identity LZ commit 9735d58fc04d7a587a76a5387deb112c466390fe Author: Barry Willis Date: Thu Jan 5 13:19:05 2023 -0800 Removed the optional Subnet commit 4cd57ed41a09672b3cfbc1792c2edbdc3569a060 Author: Barry Willis Date: Thu Jan 5 13:09:36 2023 -0800 first cut at the identity LZ framework commit a119eea02fca28a2028362f484aa2835c9313c1d Author: Barry Willis Date: Wed Dec 21 11:54:58 2022 -0800 added identitypathfromroot in the branch config file commit 75b6ccc2ab6efd55037e0a5a938d49f2eef32de4 Author: Barry Willis Date: Wed Dec 21 11:35:12 2022 -0800 Added: identity vars display Changed: location reference to identity param file commit e0cfc41b5a83c4c331689fcafa5edc9928e93d39 Author: Barry Willis Date: Wed Dec 21 11:22:35 2022 -0800 fixed misconfigured working directory commit fb58b16999aeb9cc6b6b81647c76e95024e1267c Author: Barry Willis Date: Wed Dec 21 11:18:46 2022 -0800 removed schema validation to test deployment commit 240189de7e30fa57654c3ec76ec37c762ff80133 Author: Barry Willis Date: Wed Dec 21 11:15:43 2022 -0800 fixed bug - neworking region is now identity region commit 89e63b5976cb5cdc4e85d0b25c01234ffe4853d7 Author: Barry Willis Date: Wed Dec 21 11:11:48 2022 -0800 initial identity lz deployment commit d4b40b26b893b78d7a9250dffe24c3e9ce06d690 Author: Barry Willis Date: Wed Dec 21 11:03:29 2022 -0800 Added default region for Identity Subscription commit 41e611818d09181b1a455f612425cae20f0683f7 Author: Barry Willis Date: Wed Dec 21 08:29:33 2022 -0800 Changed bastion subnet range in identity subnet commit f5a43f2d44803e80db8a043d31e5c9f72fc51675 Author: Barry Willis Date: Wed Dec 21 07:33:03 2022 -0800 Param file for Identity LZ commit 13d084b0fe74f39ca1423b2eb9f333a2b760b1f2 Author: Barry Willis Date: Tue Dec 20 15:19:23 2022 +0000 Deleted identity.parameteres.json commit 5ba9a12fa8e8e02f60f3f2afea43681cc84d7446 Merge: 002b2be e395307 Author: Barry Willis Date: Tue Dec 20 07:18:40 2022 -0800 Merge branch 'IdentityLZ' of https://dev.azure.com/Tredell/CanadaALZ/_git/CanadaALZ into IdentityLZ commit 002b2be1bb5b555a334f35cbb505e7a68f321649 Author: Barry Willis Date: Tue Dec 20 07:18:32 2022 -0800 id-lz - created param section for id lz commit e395307b1c12786cc28cf3d4b00586dde69739d5 Author: Barry Willis Date: Tue Dec 20 07:13:54 2022 -0800 id-lz - created param section for id lz commit 7f4a43eb4fdc7f6f37ebab8e661981cccbee9f50 Author: Barry Willis Date: Mon Dec 19 14:54:57 2022 -0800 disabled privatelink infrastructure to be deployed in hub lz commit db85049ac94b5c394d586b6960343bc1286997f1 Author: Barry Willis Date: Mon Dec 19 14:46:36 2022 -0800 Configured hub networking parameter files commit 8d772e868803d1b712013f7db21044d48ab730d2 Author: Barry Willis Date: Mon Dec 19 14:07:43 2022 -0800 removed comment from json - not supported commit 89cde8d92704f1a41a123af46da6dd90568d99cb Author: Barry Willis Date: Mon Dec 19 12:56:47 2022 -0800 Configuring Policies for deployment to Test enviornment commit ba781ee844a4abd403071e072645988b63ada494 Author: Barry Willis Date: Mon Dec 19 12:40:53 2022 -0800 added a default security Group commit 1269da21e08fdf4c29a53b38a4d18722c64461e0 Author: Barry Willis Date: Mon Dec 19 12:26:14 2022 -0800 setting up logging for my test environment commit 4d6a41f4133380223f5895dba270cbce4ae5a39b Author: Barry Willis Date: Mon Dec 19 12:13:08 2022 -0800 testing the path to the logging configuraiton file commit 75d0b99caf6aed5f809c28566cad35569d78be58 Author: Barry Willis Date: Mon Dec 19 12:00:14 2022 -0800 added the full path to the logging parameters file commit 32e8382bcb8deaaaab0c7bc1c2791483ef439971 Author: Barry Willis Date: Mon Dec 19 11:55:00 2022 -0800 path to logging parameters file was incorrect commit 5757d36a486e7f3b707f00848d19cfe64de83358 Author: Barry Willis Date: Mon Dec 19 11:37:20 2022 -0800 Changed MG Root to match test enviornment commit 1fdd02db1638420decf5ab021fb617b95920aada Author: Barry Willis Date: Mon Dec 19 11:09:46 2022 -0800 Adding config file for IdentityLZ branch * PowerShell Deployment Files created * GitHub Action Pipelines modified to add the Identity Archetype * made the Identity GitHub Action optional * put the boolean option in single quotes * fixed a few bugs (BCP321 & references to the wrong tenant) * changed the sub id for the logging subscription * Removed the hardcoded reference to the LAW in the identity param file * updated the param file with the LAW ID * disabled private dns zone deployment in the identity sub * removed the config files from my custom branch * uncommented the validation in the Identity ADO Pipeline * removed commented trigger code from ADO Identity Pipeline * renenabled the dployment of the DNSPrivateEndPoints policyset * removed the provider registration for containerservices in the deploy-identity-pipeline yaml * added an explanation comment to the dnsforwardingruleset file * Added telemetry tracking for the identity subscription * fixed cut and paste errors * Updated test cases & documentation * added the consistency check & pull request checks for github actions * fixed spelling error commit 533765439f98250eccbbccc194f82309ff4be9ec Author: Barrington Willis <51492255+tredell@users.noreply.github.com> Date: Fri Feb 24 12:57:36 2023 -0800 Fixed Linter warnings & build errors (#354) * Fixed BCP321 Linter warning in networking files * Fixed Role Definition Id References to use the ResourceId function * changed the pOlicyScopedId var to be set by using the MGResourceID Function * fixed BCP321 warning * fixed the remaining linter warnings * fixed the remaining linter errors in the policy definitions * updated the linter rules * Fixed Bug on policy defnition * Fixed the AKS policy deployment * Commit 95556ddd: changed the extensionResourceId function to tenantResourceId for all built-in polify definitions * fixed linter warnings in policy files * changed the invalid dummy service alert phone number to a valid phone number * changed the servcie health number prefix to 604 * updated AKS version in the Data Archetypes * Changed hte AKS version to only have the Major.Minor * Added the patch version to the AKS versions in the Data Archetypes commit 0fa01e8b7b4320d3d9d50a38d044cdff5da1a3c6 Author: Luke Murray <24467442+lukemurraynz@users.noreply.github.com> Date: Tue Feb 7 12:26:03 2023 +1300 Updated documents, from docs.microsoft.com - to Learn. (#350) Updated documents, from docs.microsoft.com - to Learn. commit e44c7eabf85bb4d5ec526c8f4229dbc31b282ed3 Author: Obay Date: Wed Nov 30 19:14:57 2022 -0800 Update hubnetwork-azfw.md (#345) Having domain controllers under the "Connectivity" subscription is an anti-pattern that causes confusion to users. Co-authored-by: Barrington Willis <51492255+tredell@users.noreply.github.com> commit 12cd557bc479041ee6fca7f76c7fe1e4c17c7e74 Author: Steve Keeler Date: Wed Nov 30 21:27:08 2022 -0500 Add Barry to code owners list (#346) commit c714e65b81d4bf5048bcf56351534a8be26c5c0c Author: Steve Keeler Date: Fri Oct 14 15:48:33 2022 -0400 Update CODEOWNERS (#344) Adding Barry Willis and Kevin Evans to the CODEOWNERS file for the entire repo commit b8a9bc91168f5afe9cb4c6ea35148714c11b4761 Author: Steve Keeler Date: Thu Sep 1 15:31:28 2022 -0400 Version August 2022 schema changes (#342) commit 5851a09acff454df0bb8bbb2d6406fcd9a8efb6d Author: Senthuran Sivananthan Date: Wed Aug 17 18:50:15 2022 -0400 Revised Event Hub Diagnostic Settings policy (#339) commit e5fe39930e55ae9cb62745499d1a520a098693df Author: Senthuran Sivananthan Date: Wed Aug 17 18:37:43 2022 -0400 Update diagnostic settings profile name (#337) commit db52627fe3769b7430c99be757f9761238b27adc Author: Senthuran Sivananthan Date: Wed Aug 17 18:17:12 2022 -0400 Suppress false positive linter warning: secure-secrets-in-params (#335) commit 2a6042d38ccd04844d9cc445e0a95ead182e5a6b Author: Senthuran Sivananthan Date: Wed Aug 17 17:59:13 2022 -0400 Network security group support for private endpoints subnet (#333) commit e069a4b6ac4f5be8d7614eeb5a67d0cfb3534e52 Author: Senthuran Sivananthan Date: Wed Aug 17 17:28:39 2022 -0400 Support data collection rule (#331) commit c2afa0d99717c56bacc211cfb5ed13234880d9a1 Author: Senthuran Sivananthan Date: Mon Aug 8 15:42:22 2022 -0400 Support azkms.core.windows.net and IPs in firewall allow list (#329) commit a7f521dcf919114a9441296407fc4dd06be46927 Author: Senthuran Sivananthan Date: Tue Jul 19 23:31:56 2022 -0400 Add missing log categories in diagnostic settings for Azure Firewall (#324) commit 60198bc19eb4d87d0bbebc24d4c2fe240d2297ab Author: Senthuran Sivananthan Date: Tue Jul 19 23:11:10 2022 -0400 Resolve linter warning: prefer-unquoted-property-names (#322) commit a4e53fffe4b1f2a2fdbf25ec92a181ef625dd240 Author: Sabyasachi Dasgupta Date: Mon Jul 18 16:44:01 2022 -0400 Update machinelearning.md (#327) commit 8fc587a6bf2e53e516ded633d96c652874ab5875 Author: Ifyagolu <55541295+Ifyagolu@users.noreply.github.com> Date: Fri Jun 24 17:05:28 2022 -0400 Fix typo in onboarding guidance (#320) commit e9a0962b7db12c5438782d2597afd494de5354b2 Author: Islam Gomaa Date: Fri May 27 16:13:52 2022 -0400 Reference the Guardrails Solution Accelerator for 30-day guardrail assessment (#313) commit 2b11801386654f6b3f68bd63c887d74ec7a4fdb8 Author: Senthuran Sivananthan Date: Thu May 19 10:38:55 2022 -0400 Add service health notification info (#310) commit bce747c9fdc96c2be78881a4dc9276351ff40b64 Author: Senthuran Sivananthan Date: Wed May 18 09:29:03 2022 -0400 Update resource group names for Logging & Networking (#309) Remove `-rg` suffix commit 6765c48680e47ccc380ab0df929e3cd1af4f8a5b Author: Senthuran Sivananthan Date: Tue May 17 15:14:33 2022 -0400 Serial defender plan deployments & revised resource/resource group names (#307) commit 62adb00d6a8561030b39272f1d710c2a4e0cfcba Author: Senthuran Sivananthan Date: Mon May 16 13:53:37 2022 -0400 Log Analytics solutions for SQL servers on machines (#303) commit c1a3b99c969f802d8325245387b617f21bc0c921 Author: Senthuran Sivananthan Date: Mon May 16 09:26:47 2022 -0400 Flexible policy deployment using PowerShell & GitHub Actions (#300) commit 0ce5c1ac9ef8ff728a19e608bf8bd3654b453cbb Author: Senthuran Sivananthan Date: Sun May 15 12:19:01 2022 -0400 Disable fail fast for matrix deployments (#297) commit c078a797d9be10bf1b2dc7bed01957637ddb73ea Author: Senthuran Sivananthan Date: Sun May 15 11:19:43 2022 -0400 Concurrent role deployment with PowerShell & GitHub Actions (#299) commit 31a214abbf65c10b106962b1493a1830e37f9702 Author: Senthuran Sivananthan Date: Sun May 15 10:39:08 2022 -0400 Disable metrics in diagnostic settings for AKS through Policy (#295) commit 6a90a2fe9d881730a32303fe6a10d1bbcc22f943 Author: Senthuran Sivananthan Date: Wed May 11 10:56:26 2022 -0400 Separate Azure Firewall Policy deployment switch & unique telemetry tracking for policy assignments (#289) commit c4133077e1d97a6beaa6e4811588236912d5c768 Author: Senthuran Sivananthan Date: Tue May 10 16:46:06 2022 -0400 Ensure multiple subscriptions can be moved to a management in parallel (#288) Ensure deployment name for moving subscription is unique commit 93d2f13847d56c195e2c170d314a3bbc5cfe5c63 Author: Senthuran Sivananthan Date: Tue May 10 14:53:18 2022 -0400 Support jobs in GitHub Actions (#286) commit 31e8d0ab602bfcf856c9134666eb4814817d6964 Author: Steve Keeler Date: Tue May 10 12:30:36 2022 -0400 Correct wiring of the subscriptions-ci pipeline and prompt for NVA firewall username & password (#285) commit 229b14466384252ba034546095f5c21a932cb6fc Author: Steve Keeler Date: Mon May 9 20:41:06 2022 -0400 Fix DeploySubscriptionIds parameter type casting (#282) commit 799ad52d778ebbc4fc4ed53d56c872d56ab2fc29 Author: Senthuran Sivananthan Date: Mon May 9 20:10:33 2022 -0400 Pass-thru secure strings as-is until ready for use (#281) commit a9c941948d51c59c758d07bce702bcb36aee70ec Author: Steve Keeler Date: Mon May 9 17:11:12 2022 -0400 Add environment configuration override and protect sensitive parameters (#280) commit ce6c27f4e02cf194b3b13574c2caf4b60f8e8205 Author: Senthuran Sivananthan Date: Mon May 9 11:23:57 2022 -0400 Support schema validation (#277) commit 1d8dbd7bafc62b402719fb187698cfd950e8e3df Author: Steve Keeler Date: Mon May 9 08:07:26 2022 -0400 GitHub workflow implementation (#276) Implement GitHub workflows to deploy the Azure Landing Zones for Canadian Public Sector commit 08d8f9256aaf3236a6920abe67e7d58b95887a0c Author: Senthuran Sivananthan Date: Mon May 2 16:03:02 2022 -0400 Deployment flow diagram (#274) commit db098e17a13f111c18aa3af33c81f1cb54979cd1 Author: Senthuran Sivananthan Date: Fri Apr 29 22:37:58 2022 -0400 Powershell deployment script for archetypes (#273) Support for deploying subscriptions commit 15c2847a4255108680937da0192d54ccc2d7f16c Author: Senthuran Sivananthan Date: Fri Apr 29 16:29:22 2022 -0400 PowerShell deployment scripts (#271) commit 352257187e7d03bf5abade4a18302bdd310ab82c Author: Senthuran Sivananthan Date: Wed Apr 27 18:10:23 2022 -0400 Snapshot ARM parameters JSON schemas (#268) commit 60f3b59013e27c549e2d57bd16fba2ea26bf12b5 Author: Senthuran Sivananthan Date: Wed Apr 27 17:29:58 2022 -0400 Organize deployment parameters for Hub Networking with NVA (#266) commit 926521a1c01ab420ccaa319d47516a2870cf3a15 Author: ghostme Date: Wed Apr 27 15:20:08 2022 -0400 Updated documentation (#267) commit d68824a2eed32c62cc199f374ba15ea732025241 Author: Senthuran Sivananthan Date: Mon Apr 25 14:32:25 2022 -0400 Organize deployment parameters for Hub Networking with Azure Firewall (#265) commit 2bc196a0960bfecb9c545226000c5c34dbbabec8 Author: Senthuran Sivananthan Date: Mon Apr 25 14:03:31 2022 -0400 Support for optional subnets in Machine Learning & Healthcare archetypes (#264) commit b33cd36261fd797834cdcbeebe53ce1262ef21ac Author: Senthuran Sivananthan Date: Thu Apr 21 09:32:43 2022 -0400 Update common.yml example (#262) commit 300835322afd2d85f34aa8b8ff5921d3839c2e6c Author: Senthuran Sivananthan Date: Wed Apr 20 12:44:45 2022 -0400 Removed extra configuration files (#260) commit 1ee5b9e736feca7270c4ad62d27c4366751f1cab Author: Senthuran Sivananthan Date: Wed Apr 20 11:56:14 2022 -0400 Revise subnet configuration for Healthcare archetype (#256) commit 72fe50db665710eabc8e6edffae5d658d0497822 Author: Senthuran Sivananthan Date: Wed Apr 20 11:43:09 2022 -0400 Revise subnet configuration for Machine Learning archetype (#254) commit 70833771ac433d5de7950423dd8085777bfb03be Author: Senthuran Sivananthan Date: Wed Apr 20 11:38:07 2022 -0400 Revise subnet configuration for Generic Subscription archetype (#252) commit 3d9c60d251a98b2ebc400aadb2c452f3f6262712 Author: Senthuran Sivananthan Date: Wed Apr 20 11:30:10 2022 -0400 Migrate Networking configuration to JSON parameters file (#250) commit 38fc344508cd6b4707aac0fca2e0cf3e8609a882 Author: Mohamed Sharaf Date: Wed Apr 20 10:29:52 2022 -0400 Azure Active Directory support for Synapse (#259) commit 89613dbc876831f543f2749cbe6f804278a65612 Author: Senthuran Sivananthan Date: Tue Apr 12 21:31:06 2022 -0400 Include new Databricks' log categories for diagnostic settings (#248) Add new databricks' log categories for diagnostic settings commit 700eb9645cbde1435bdda80b28faa03a52dee671 Author: Senthuran Sivananthan Date: Tue Apr 12 17:33:12 2022 -0400 Support multiple private dns zone configuration when updating private DNS Zones through Azure Policy (#246) Update Private DNS Zone policy to support multiple dnsZoneConfigs commit 1c3727990cc12a401c0ecebdbf31234d71c472ab Author: Senthuran Sivananthan Date: Mon Apr 11 11:24:00 2022 -0400 Support logging infrastructure for multiple regions in same subscription (#244) Ensure subscription scoped deployments are unique per region commit 0e258f96cd99c622665d382d73aeba1e78f52319 Author: Steve Keeler Date: Sat Apr 9 13:50:50 2022 -0400 Update azure-devops-pipelines.md (#242) commit bfe1f588adc59922145fcf9a47c19173130cf321 Author: Senthuran Sivananthan Date: Fri Apr 8 11:31:52 2022 -0400 Migrate Logging configuration to JSON parameters file (#236) commit cc5f017b01e06331d4246d5fc0286cf50d525470 Author: Senthuran Sivananthan Date: Fri Apr 8 10:26:12 2022 -0400 PBMM & HITRUST/HIPAA policy update (#238) commit 3259994f47c482153368a9fb115ce60b9e3488fb Author: Steve Keeler Date: Tue Apr 5 14:41:17 2022 -0400 Fix order of `platform-connectivity-hub-azfw-policy` pipeline listed in run-pipelines.bat script #233 (#234) commit cb96311bf94224c1cf94470320c9c8fec029e165 Author: ccmsft <98336965+ccmsft@users.noreply.github.com> Date: Mon Apr 4 09:39:17 2022 -0400 Updating recommendations to reflect licensing reqs (#229) commit 3ce2cf875b5d6c9464a0262f183a37f40399f8dd Author: Senthuran Sivananthan Date: Fri Apr 1 22:49:44 2022 -0400 Use built-in policy for Cosmos DB for Defender Plan (#232) * Use built-in policy for Cosmos DB for Defender Plan * Add branch config * Remove branch config commit d2f959a2550b694d79fb0aa6d1a9d2b8166090c8 Author: ghostme Date: Fri Apr 1 10:05:21 2022 -0400 Update networking documentation for generic subscription archetype (#230) commit 575440e4c629b1c00686ba62e5911749375832ff Author: ccmsft <98336965+ccmsft@users.noreply.github.com> Date: Wed Mar 30 23:36:35 2022 -0400 Initial GC 30-day cloud guardrails compliance/guidance (#226) Initial GC 30-day cloud guardrails doc commit 6b36096f2356255a967a7d9cd14dd04a5dc3b6ce Author: Senthuran Sivananthan Date: Wed Mar 30 22:40:17 2022 -0400 Externalize Log Analytics Workspace parameters when loading pipeline variables (#220) Externalize the log analytics parameters to load arbitary LAW variables commit 0210df4fd3a11dfcaee3a82f2da1e2315bf70400 Author: Senthuran Sivananthan Date: Wed Mar 30 21:51:30 2022 -0400 Flexible policy assignment parameters JSON files (#222) commit f25f95781d6f9f3c2169bbe4b148c3b748a6ac93 Author: Senthuran Sivananthan Date: Wed Mar 30 20:57:07 2022 -0400 Private DNS Policy - Change Cosmos DB namespace to Microsoft.DocumentDB (#228) * Change Cosmos DB namespace to Microsoft.DocumentDB * Add branch config * Remove branch config commit 453a0f8bc78dbf7a78c46d01f0cde28b3ab2bbaa Author: Steve Keeler Date: Wed Mar 30 19:00:07 2022 -0400 Improve `delete-management-groups.bat` script (#224) commit 2e5a56b04fd25149da78e77f396073945ba785f5 Author: Senthuran Sivananthan Date: Thu Mar 24 09:02:36 2022 -0400 Fix formatting (#218) commit bf5e94bcdee854db8fde7a8eb60d7886bc2c2191 Author: Senthuran Sivananthan Date: Wed Mar 23 23:01:02 2022 -0400 Add instructions for customizing policy set assignments (#215) commit 0538d4d7d8765fcd558c99fdbf7aa7d6655c8b95 Author: Senthuran Sivananthan Date: Wed Mar 23 22:57:00 2022 -0400 Document delete lock usage (#216) Document when and where delete locks are used commit 789b18a888290ada72d8fe2328097429ee9823d6 Author: Senthuran Sivananthan Date: Wed Mar 23 22:49:24 2022 -0400 Update OZ subnet name to App Management Zone (#217) commit 97c2904a773f94adf26cd52924f0dfccab985cdf Author: Senthuran Sivananthan Date: Fri Mar 11 21:59:40 2022 -0500 Backward compatibility when setting pipeline variables from management group hierarchy (#213) commit 30b9cc2060e96dd99b12743bb4c959181a403e91 Author: Adil Ha Date: Fri Mar 11 11:26:31 2022 -0500 fixing doc typo in hubnetwork-azfw (#211) Co-authored-by: Adil Ha commit 27363b730f34536fbf7f9994e08da7aa5af3c58e Author: Senthuran Sivananthan Date: Sat Mar 5 13:04:13 2022 -0500 Support Defender Plan for Cosmos DB (#200) Add CosmosDB Defender Plan and custom policy to deploy Defender Plan for Cosmos DB commit 81eccd1d54956f7c7addb2a969ebb3e62e99b588 Author: Senthuran Sivananthan Date: Sat Mar 5 12:48:45 2022 -0500 Delete Lock for Log Analytics Workspace resource group (#205) Add delete lock for LAW RG commit 678355f149698ecfdab6d10669e631702f1d9d49 Author: Steve Keeler Date: Sat Mar 5 11:03:46 2022 -0500 Fix pipeline scripts reference to `subscription-ci` (#207) commit 5753cf0e35a9f921c4cb59ec90db787e26d6d400 Author: Senthuran Sivananthan Date: Thu Mar 3 14:44:31 2022 -0500 Ensure values from multiline variables are properly logged (#202) Print multi-line environment variables (typically JSON objects) in Show Variables step commit d6b1c08fec1a96c332cf5abb758b16cd8bfede87 Author: Senthuran Sivananthan Date: Thu Mar 3 14:09:47 2022 -0500 Revise subscription deployment instructions (#201) * Redirect subscriptoin configuration guidance to archetype authoring guide doc * Revise instructions for creating ARM parameter files & management group id selection commit 5e7322ee0b64ffa379e1ac546972796a76407db7 Author: Senthuran Sivananthan Date: Wed Mar 2 08:22:35 2022 -0500 Instructions for backfilling management group hierarchy (#197) * Add instructions for backfilling management group hierarchy * Update section titles, links and reference backfill instruction as part of MG setup * Instructions for installing AzCLI and jq * Clearfy that Tenant Root Group could have been renamed in the organization * Windows Shell example * Update instructions to delete pipeline variables that will be automatically created when MG heirarchy is used * Note on YAML indentation commit 5d33909d70f821039df0deab2d26a5d180d7a16c Author: Preston K. Parsard Date: Tue Mar 1 10:46:04 2022 -0500 subscription(generic): add instructions for configuring parameters (#193) commit 17846c4959c5156dee905736e3631fa56193d9e7 Author: Steve Keeler Date: Sun Feb 27 20:30:20 2022 -0500 Show Variables fix (#191) commit c62dcfcd5862ae15196000e0fd481d214081c817 Author: Steve Keeler Date: Sun Feb 27 16:50:20 2022 -0500 Configurable management group hierarchy (#186) Implement configurable management group hierarchy commit 9a141f7e5bf238f21838898ff908b6fc7f6d8fcc Author: Preston K. Parsard Date: Sat Feb 26 19:45:35 2022 -0500 Update onboarding document Co-authored-by: Preston K. Parsard commit 6b6ef29fd266fe0b2c23fed5f1bf6cc3fdb5e4a8 Author: Senthuran Sivananthan Date: Sat Feb 26 18:22:48 2022 -0500 Snapshot JSON schemas to v0.4.0 (#182) commit 4dd1f4a901fbd44c54a32fdf9ac23f5ca5bed736 Author: Senthuran Sivananthan Date: Wed Feb 23 15:39:43 2022 -0500 Update onboarding doc for logging & networking management group settings (#177) * Fix markdown linter warnings * Add instruction for logging and networking MGs commit 5d7eec3a319524b5ded5f32e6db951566c365ffc Author: Steve Keeler Date: Wed Feb 23 12:51:20 2022 -0500 Update `create-pipelines.bat` onboarding script to auto-provision environment (#178) commit 488fc6e767639f3acd00a2dea11a8f2a6476379e Author: Senthuran Sivananthan Date: Tue Feb 22 09:05:20 2022 -0500 Instructions for Azure DevOps Environments (#175) * Instructions for creating ADO pipeline environments * Fix formatting commit edabd873d42a622fc5d1503c099c514bb4f2bd7f Author: Senthuran Sivananthan Date: Thu Feb 17 23:29:42 2022 -0500 Support for Tag inheritance from Subscription to Resource Group (#161) * Add policy and policy set to inherit tags from subscription to resource group * Add branch config for testing * Remove policy type as it's not built in * Updated resource type for resource group * Update policy assignment * Ensure assignment name is <= 24 chars * Revert resource group type * Setting mode to all * Update documentation * Add branch config * Add explicit dependsOn for subscription scaffolding to complete * Update test deployment parameters * Remove explicit dependsOn for subscription scaffolding to complete * Update doc to describe approaches for adding tags to RGs * Reduce the options for tagging resources given subscripton to RG tagging is available * Add example scenarios for tag inheritence * Fix typo * Remove branch configs * Resolve linter error: no-loc-expr-outside-params commit e71ed265f2267d35cd36d30bab217f9ecbb6891c Author: Senthuran Sivananthan Date: Wed Feb 16 20:09:19 2022 -0500 Linter: no-loc-expr-outside-params - ensure compliance (#169) * Update linter rules for location parameter * Add location parameter with default value based on resourceGroup() or deployment() * Update archetype schema and docs for location * Add branch config for testing * Update AKS version * Update branch config * Remove branch configs commit 6061fa0b930200d73e906e0bedefafeb35e43296 Author: Senthuran Sivananthan Date: Thu Feb 10 16:49:42 2022 -0500 Repository clean up (#165) * Remove obsolete directory * Rotate resource group names for E2E deployments * Fix typo * Add branch config for testing * Fix typo * Remove branch configs * Remove timestamp from sample JSON templates. Timestamps are kept for E2E testing. * Remove date stamp commit 5104f393a618a0f0f7072100fd810df4534a3210 Author: Steve Keeler Date: Thu Feb 10 09:08:17 2022 -0500 Update DevOps Onboarding section of main readme (#162) commit 209f61cf72ac91555f8b2171dcf84c6daae6a7cc Author: Senthuran Sivananthan Date: Thu Feb 10 09:06:31 2022 -0500 Update Deployment Script's Azure CLI version to 2.32.0 (#164) Update Azure CLI version to 2.32.0 commit d7d52570c8dce3ed8bcc3b809191d1cd2ddf5e3f Author: Steve Keeler Date: Mon Feb 7 13:51:17 2022 -0500 Issue #157 - Update scripts documentation (#158) Update scripts documentation (Issue #157) Update docs/onboarding/azure-devops-scripts.md Co-authored-by: Senthuran Sivananthan commit b628c68ff84bb5b8796d6821161450010d19ce3b Author: Senthuran Sivananthan Date: Fri Feb 4 12:42:31 2022 -0500 Enhance PBMM policy assignment to disable diagnostic settings metrics (#156) Ensure diagnostic settings policy only checks for logs commit 61afd59bb6d7f6c2a37518d41c64ced985cafd92 Author: Senthuran Sivananthan Date: Mon Jan 31 12:52:09 2022 -0500 Snapshot landing zone schema to v0.3.0 (#152) commit 09f09ede5613cf600441616831f762595aecdbed Author: Steve Keeler Date: Mon Jan 31 09:20:20 2022 -0500 Automation scripts for Azure DevOps onboarding (#151) Implement #150, scripts and documentation commit 82dd82606059a6643d7de294cb1f15afab41cd94 Author: SlavaRoikhman <52217047+SlavaRoikhman@users.noreply.github.com> Date: Thu Jan 27 13:32:41 2022 -0500 Removed 'privatelink.monitor.azure.com' from Private DNS Zones (#149) commit 73ce2eb316175f1bf86135010d5f35ce9bbc6da7 Author: Senthuran Sivananthan Date: Fri Jan 21 23:23:45 2022 -0500 Flexible policy assignment scope (#147) * Add deployment scope for policy assignment * Add branch test config * Set new parameter for policy assignment scope: var-policyAssignmentManagementGroupId * Update pipeline for new var * Add separate scope for testing * Update pipeline parameter name * Ensure new temp file is created to populate the parameters. * Remove test job * Remove branch config * Update readme * Update authoring guide with new parameter commit c71051b21804f0b069acc02718ced57840863e86 Author: hudua <40040433+hudua@users.noreply.github.com> Date: Fri Jan 21 14:21:08 2022 -0500 Private Endpoint for App Service (#144) commit fff245db0c7f94221ce73404a2c5fb1a9ad44207 Author: Senthuran Sivananthan Date: Fri Jan 21 10:51:43 2022 -0500 Diagnostic Settings Policies for PaaS services (#143) * Add diagnostic settings policies for data services * Add branch config for testing * Add missing types for auditing * Add diagnostic setting policies for compute services * Add diagnostic setting policies for integration services * Add diagnostic setting policies for network services * Remove policy for ACI since it doesn't have logs to collect * Remove extra resource type * Set region to 'global' for edge services * Remove branch config. used for testing * Updated App Service log categories * Add branch config * Remove branch config * comma everytime... * no need for testing * test * Revert "no need for testing" This reverts commit 52278e6aebcec125101348ef218b08002f26b2e7. * Revert "test" This reverts commit bea0bf356079670fe04f6ba02fff1b6955803b97. * plan * add cdssnc-main configs * add default environmentName * fix typo --------- Co-authored-by: Senthuran Sivananthan Co-authored-by: hudua <40040433+hudua@users.noreply.github.com> Co-authored-by: SlavaRoikhman <52217047+SlavaRoikhman@users.noreply.github.com> Co-authored-by: Steve Keeler Co-authored-by: Senthuran Sivananthan Co-authored-by: Preston K. Parsard Co-authored-by: Preston K. Parsard Co-authored-by: Adil Ha Co-authored-by: Adil Ha Co-authored-by: ccmsft <98336965+ccmsft@users.noreply.github.com> Co-authored-by: ghostme Co-authored-by: Mohamed Sharaf Co-authored-by: Islam Gomaa Co-authored-by: Ifyagolu <55541295+Ifyagolu@users.noreply.github.com> Co-authored-by: Sabyasachi Dasgupta Co-authored-by: Obay Co-authored-by: Barrington Willis <51492255+tredell@users.noreply.github.com> Co-authored-by: Luke Murray <24467442+lukemurraynz@users.noreply.github.com> Co-authored-by: Yanick Lepine <65724245+ylepine@users.noreply.github.com> Co-authored-by: David Christiansen --- .github/workflows/0-everything.yml | 2 +- .github/workflows/1-management-groups.yml | 3 +- .github/workflows/2-roles.yml | 3 +- .github/workflows/3-logging.yml | 3 +- .github/workflows/4-policy.yml | 5 +- .github/workflows/5-azure-firewall-policy.yml | 3 +- .../5-hub-network-with-azure-firewall.yml | 3 +- .github/workflows/5-hub-network-with-nva.yml | 3 +- .github/workflows/6-identity.yml | 3 +- .github/workflows/6-subscriptions.yml | 1 + .github/workflows/7-subscriptions.yml | 3 +- .gitignore | 1 + .../templates/jobs/trigger-subscriptions.yml | 6 +- README.md | 1 + .../identity.parameters.json | 187 +++++ .../cdssnc-main/identity.parameters.json | 178 +++++ .../logging.parameters.json | 149 ++++ .../azure-firewall-policy.parameters.json | 22 + .../hub-azfw/hub-network.parameters.json | 231 ++++++ .../hub-nva/hub-network.parameters.json | 318 +++++++++ .../azure-firewall-policy.parameters.json | 22 + .../hub-azfw/hub-network.parameters.json | 224 ++++++ ...0d7a360_machinelearning_canadacentral.json | 206 ++++++ ...10cc2b79b6c7_healthcare_canadacentral.json | 200 ++++++ ...05_generic-subscription_canadacentral.json | 192 +++++ ...d9ea82c_machinelearning_canadacentral.json | 206 ++++++ ...f3f1a61_machinelearning_canadacentral.json | 207 ++++++ ...e16f12_machinelearning_canadacentral.json} | 76 +- ...0d7a360_machinelearning_canadacentral.json | 206 ++++++ ...10cc2b79b6c7_healthcare_canadacentral.json | 200 ++++++ ...05_generic-subscription_canadacentral.json | 192 +++++ ...d9ea82c_machinelearning_canadacentral.json | 206 ++++++ ...f3f1a61_machinelearning_canadacentral.json | 207 ++++++ ...5e16f12_machinelearning_canadacentral.json | 235 +++++++ config/variables/CanadaESLZ-main.yml | 86 --- config/variables/CanadaPubSecALZ-main.yml | 78 +++ config/variables/cdssnc-main.yml | 108 ++- docs/archetypes/authoring-guide.md | 16 +- docs/onboarding/azure-devops-pipelines.md | 54 +- docs/onboarding/configuration-scripts.md | 663 ++++++++++++++++++ docs/policy/readme.md | 12 +- roles/la-vminsights-readonly.bicep | 2 +- .../configuration/Connect-AlzCredential.ps1 | 70 ++ .../configuration/Get-AlzConfiguration.ps1 | 55 ++ .../configuration/Get-AlzSubscriptions.ps1 | 55 ++ .../configuration/Install-Prerequisites.ps1 | 14 + .../configuration/New-AlzConfiguration.ps1 | 475 +++++++++++++ scripts/configuration/New-AlzCredential.ps1 | 132 ++++ scripts/configuration/New-AlzDeployment.ps1 | 217 ++++++ .../configuration/Remove-AlzConfiguration.ps1 | 150 ++++ .../configuration/Remove-AlzCredential.ps1 | 123 ++++ scripts/configuration/Test-AlzCredential.ps1 | 138 ++++ .../Functions/EnvironmentContext.ps1 | 26 +- .../Functions/HubNetworkWithAzureFirewall.ps1 | 46 +- .../Functions/HubNetworkWithNVA.ps1 | 44 +- .../deployments/Functions/Subscriptions.ps1 | 30 +- scripts/deployments/RunWorkflows.ps1 | 16 +- scripts/onboarding/create-pipelines.bat | 2 +- .../set-variables.CanadaPubSecALZ.bat | 54 ++ 59 files changed, 6101 insertions(+), 269 deletions(-) create mode 100644 config/identity/CanadaPubSecALZ-main/identity.parameters.json create mode 100644 config/identity/cdssnc-main/identity.parameters.json create mode 100644 config/logging/CanadaPubSecALZ-main/logging.parameters.json create mode 100644 config/networking/CanadaPubSecALZ-main/hub-azfw-policy/azure-firewall-policy.parameters.json create mode 100644 config/networking/CanadaPubSecALZ-main/hub-azfw/hub-network.parameters.json create mode 100644 config/networking/CanadaPubSecALZ-main/hub-nva/hub-network.parameters.json create mode 100644 config/networking/cdssnc-main/hub-azfw-policy/azure-firewall-policy.parameters.json create mode 100644 config/networking/cdssnc-main/hub-azfw/hub-network.parameters.json create mode 100644 config/subscriptions/CanadaPubSecALZ-main/DevTest/0a5970ed-b9d5-464a-acef-8a06f0d7a360_machinelearning_canadacentral.json create mode 100644 config/subscriptions/CanadaPubSecALZ-main/DevTest/1f519216-5e39-4b51-a9b6-10cc2b79b6c7_healthcare_canadacentral.json create mode 100644 config/subscriptions/CanadaPubSecALZ-main/DevTest/8422552f-3840-4934-a971-6ee349ffbb05_generic-subscription_canadacentral.json create mode 100644 config/subscriptions/CanadaPubSecALZ-main/DevTest/9d9817f5-c218-4553-b686-58be8d9ea82c_machinelearning_canadacentral.json create mode 100644 config/subscriptions/CanadaPubSecALZ-main/DevTest/bbe30f1a-fda5-4873-b51b-c838cf3f1a61_machinelearning_canadacentral.json rename config/subscriptions/{CanadaESLZ-main/pubsec/LandingZones/DevTest/8c6e48a4-4c73-4a1f-9f95-9447804f2c98_machinelearning_canadacentral.json => CanadaPubSecALZ-main/DevTest/f881fccb-2598-4b9c-b87c-b392f5e16f12_machinelearning_canadacentral.json} (72%) create mode 100644 config/subscriptions/cdssnc-main/DevTest/0a5970ed-b9d5-464a-acef-8a06f0d7a360_machinelearning_canadacentral.json create mode 100644 config/subscriptions/cdssnc-main/DevTest/1f519216-5e39-4b51-a9b6-10cc2b79b6c7_healthcare_canadacentral.json create mode 100644 config/subscriptions/cdssnc-main/DevTest/8422552f-3840-4934-a971-6ee349ffbb05_generic-subscription_canadacentral.json create mode 100644 config/subscriptions/cdssnc-main/DevTest/9d9817f5-c218-4553-b686-58be8d9ea82c_machinelearning_canadacentral.json create mode 100644 config/subscriptions/cdssnc-main/DevTest/bbe30f1a-fda5-4873-b51b-c838cf3f1a61_machinelearning_canadacentral.json create mode 100644 config/subscriptions/cdssnc-main/DevTest/f881fccb-2598-4b9c-b87c-b392f5e16f12_machinelearning_canadacentral.json delete mode 100644 config/variables/CanadaESLZ-main.yml create mode 100644 config/variables/CanadaPubSecALZ-main.yml create mode 100644 docs/onboarding/configuration-scripts.md create mode 100644 scripts/configuration/Connect-AlzCredential.ps1 create mode 100644 scripts/configuration/Get-AlzConfiguration.ps1 create mode 100644 scripts/configuration/Get-AlzSubscriptions.ps1 create mode 100644 scripts/configuration/Install-Prerequisites.ps1 create mode 100644 scripts/configuration/New-AlzConfiguration.ps1 create mode 100644 scripts/configuration/New-AlzCredential.ps1 create mode 100644 scripts/configuration/New-AlzDeployment.ps1 create mode 100644 scripts/configuration/Remove-AlzConfiguration.ps1 create mode 100644 scripts/configuration/Remove-AlzCredential.ps1 create mode 100644 scripts/configuration/Test-AlzCredential.ps1 create mode 100644 scripts/onboarding/set-variables.CanadaPubSecALZ.bat diff --git a/.github/workflows/0-everything.yml b/.github/workflows/0-everything.yml index e2f7b01a..6f58d224 100644 --- a/.github/workflows/0-everything.yml +++ b/.github/workflows/0-everything.yml @@ -31,7 +31,7 @@ on: required: false environmentName: type: string - description: Environment name (optional), e.g. CanadaESLZ-main + description: Environment name (optional), e.g. CanadaPubSecALZ-main required: false defaults: diff --git a/.github/workflows/1-management-groups.yml b/.github/workflows/1-management-groups.yml index 17ffebe1..35fe55e5 100644 --- a/.github/workflows/1-management-groups.yml +++ b/.github/workflows/1-management-groups.yml @@ -14,8 +14,9 @@ on: inputs: environmentName: type: string - description: Environment name (optional), e.g. CanadaESLZ-main + description: Environment name (optional), e.g. CanadaPubSecALZ-main required: false + default: cdssnc-main defaults: run: diff --git a/.github/workflows/2-roles.yml b/.github/workflows/2-roles.yml index 115cb15c..376313fc 100644 --- a/.github/workflows/2-roles.yml +++ b/.github/workflows/2-roles.yml @@ -14,8 +14,9 @@ on: inputs: environmentName: type: string - description: Environment name (optional), e.g. CanadaESLZ-main + description: Environment name (optional), e.g. CanadaPubSecALZ-main required: false + default: cdssnc-main defaults: run: diff --git a/.github/workflows/3-logging.yml b/.github/workflows/3-logging.yml index a90b118b..98920e7d 100644 --- a/.github/workflows/3-logging.yml +++ b/.github/workflows/3-logging.yml @@ -14,8 +14,9 @@ on: inputs: environmentName: type: string - description: Environment name (optional), e.g. CanadaESLZ-main + description: Environment name (optional), e.g. CanadaPubSecALZ-main required: false + default: cdssnc-main defaults: run: diff --git a/.github/workflows/4-policy.yml b/.github/workflows/4-policy.yml index 6ecf8b9d..4fe64caa 100644 --- a/.github/workflows/4-policy.yml +++ b/.github/workflows/4-policy.yml @@ -14,9 +14,10 @@ on: inputs: environmentName: type: string - description: Environment name (optional), e.g. CanadaESLZ-main + description: Environment name (optional), e.g. CanadaPubSecALZ-main required: false - + default: cdssnc-main + defaults: run: shell: pwsh diff --git a/.github/workflows/5-azure-firewall-policy.yml b/.github/workflows/5-azure-firewall-policy.yml index b2240abf..a111fbb0 100644 --- a/.github/workflows/5-azure-firewall-policy.yml +++ b/.github/workflows/5-azure-firewall-policy.yml @@ -14,8 +14,9 @@ on: inputs: environmentName: type: string - description: Environment name (optional), e.g. CanadaESLZ-main + description: Environment name (optional), e.g. CanadaPubSecALZ-main required: false + default: cdssnc-main defaults: run: diff --git a/.github/workflows/5-hub-network-with-azure-firewall.yml b/.github/workflows/5-hub-network-with-azure-firewall.yml index ae131650..6efeedaf 100644 --- a/.github/workflows/5-hub-network-with-azure-firewall.yml +++ b/.github/workflows/5-hub-network-with-azure-firewall.yml @@ -14,8 +14,9 @@ on: inputs: environmentName: type: string - description: Environment name (optional), e.g. CanadaESLZ-main + description: Environment name (optional), e.g. CanadaPubSecALZ-main required: false + default: cdssnc-main defaults: run: diff --git a/.github/workflows/5-hub-network-with-nva.yml b/.github/workflows/5-hub-network-with-nva.yml index 65557837..9a5e9b8a 100644 --- a/.github/workflows/5-hub-network-with-nva.yml +++ b/.github/workflows/5-hub-network-with-nva.yml @@ -14,8 +14,9 @@ on: inputs: environmentName: type: string - description: Environment name (optional), e.g. CanadaESLZ-main + description: Environment name (optional), e.g. CanadaPubSecALZ-main required: false + default: cdssnc-main defaults: run: diff --git a/.github/workflows/6-identity.yml b/.github/workflows/6-identity.yml index 0804b1ab..3866ed3f 100644 --- a/.github/workflows/6-identity.yml +++ b/.github/workflows/6-identity.yml @@ -14,8 +14,9 @@ on: inputs: environmentName: type: string - description: Environment name (optional), e.g. CanadaESLZ-main + description: Environment name (optional), e.g. CanadaPubSecALZ-main required: false + default: cdssnc-main defaults: run: diff --git a/.github/workflows/6-subscriptions.yml b/.github/workflows/6-subscriptions.yml index 438d5466..87862e2d 100644 --- a/.github/workflows/6-subscriptions.yml +++ b/.github/workflows/6-subscriptions.yml @@ -20,6 +20,7 @@ on: type: string description: Environment name (optional), e.g. CanadaESLZ-main required: false + default: cdssnc-main defaults: run: diff --git a/.github/workflows/7-subscriptions.yml b/.github/workflows/7-subscriptions.yml index 0b0a0d33..efcf7f91 100644 --- a/.github/workflows/7-subscriptions.yml +++ b/.github/workflows/7-subscriptions.yml @@ -19,8 +19,9 @@ on: required: true environmentName: type: string - description: Environment name (optional), e.g. CanadaESLZ-main + description: Environment name (optional), e.g. CanadaPubSecALZ-main required: false + default: cdssnc-main defaults: run: diff --git a/.gitignore b/.gitignore index d0b2c249..bb915074 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ experiments/* **/*.swp +**/*.diff .vscode/* /*.sh /*.ps1 diff --git a/.pipelines/templates/jobs/trigger-subscriptions.yml b/.pipelines/templates/jobs/trigger-subscriptions.yml index 679946e1..bf069428 100644 --- a/.pipelines/templates/jobs/trigger-subscriptions.yml +++ b/.pipelines/templates/jobs/trigger-subscriptions.yml @@ -89,13 +89,17 @@ jobs: { $url = "$($env:SYSTEM_TEAMFOUNDATIONCOLLECTIONURI)$env:SYSTEM_TEAMPROJECTID/_apis/pipelines/$($env:SYSTEM_DEFINITIONID)/runs?api-version=6.0-preview.1" Write-Host "Invoking pipeline definition with URL: $url" + $paths = $env:SUBSCRIPTION_CHANGES -split ',' + $guids = $paths -replace '.*?([0-9a-f]{8}[-]?([0-9a-f]{4}[-]?){3}[0-9a-f]{12}).*', '$1' + $changes = $guids -join ',' $body = @" { "templateParameters": { - "subscriptions":"[$env:SUBSCRIPTION_CHANGES]" + "subscriptions":"[$changes]" }, } "@ + Write-Host "Invoking pipeline definition with body: $body" $headers = @{ Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN" } $pipeline = Invoke-RestMethod -Uri $url -Headers $headers -Method Post -Body $body -ContentType application/json Write-Host "Pipeline invocation result = $($pipeline | ConvertTo-Json -Depth 100)" diff --git a/README.md b/README.md index f42af606..d07ef966 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,7 @@ See the following onboarding guides for setup instructions: * [Azure DevOps Setup](docs/onboarding/azure-devops-setup.md) provides guidance on considerations and recommended practices when creating and configuring your Azure DevOps Services environment. * [Azure DevOps Scripts](docs/onboarding/azure-devops-scripts.md) provides guidance on the scripts available to help simplify the onboarding process to Azure Landing Zones design using Azure DevOps pipelines. * [Azure DevOps Pipelines](docs/onboarding/azure-devops-pipelines.md) provides guidance on the manual steps for onboarding to the Azure Landing Zones design using Azure DevOps Pipelines. +* [Configuration Scripts](docs/onboarding/configuration-scripts.md) provides guidance on the scripts available to help simplify the configuration process of the Azure Landing Zones design. ## Goals diff --git a/config/identity/CanadaPubSecALZ-main/identity.parameters.json b/config/identity/CanadaPubSecALZ-main/identity.parameters.json new file mode 100644 index 00000000..de75793c --- /dev/null +++ b/config/identity/CanadaPubSecALZ-main/identity.parameters.json @@ -0,0 +1,187 @@ +{ + "$schema": "https://raw.githubusercontent.com/Azure/CanadaPubSecALZ/main/schemas/latest/landingzones/lz-platform-identity.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "serviceHealthAlerts": { + "value": { + "alertRuleName": "Identity Alerts", + "receivers": { + "app": [ + "identity@example.com" + ], + "sms": [ + { + "countryCode": "1", + "phoneNumber": "6135555555" + } + ], + "email": [ + "identity@example.com" + ], + "voice": [ + { + "countryCode": "1", + "phoneNumber": "6135555555" + } + ] + }, + "regions": [ + "Global", + "Canada Central", + "Canada East" + ], + "resourceGroupName": "service-health-alerts-rg", + "actionGroupName": "Identity Alerts", + "actionGroupShortName": "identity-ag", + "incidentTypes": [ + "Incident", + "Security" + ], + "alertRuleDescription": "Identity Alerts for Incidents and Security" + } + }, + "securityCenter": { + "value": { + "email": "security@example.com", + "phone": "6135555555" + } + }, + "subscriptionRoleAssignments": { + "value": [ + { + "comments": "Built-in Contributor Role", + "securityGroupObjectIds": [ + "b4df54ba-7232-40fa-8f51-f84e8d149322" + ], + "roleDefinitionId": "b24988ac-6180-42a0-ab88-20f7382dd24c" + } + ] + }, + "subscriptionBudget": { + "value": { + "createBudget": false + } + }, + "subscriptionTags": { + "value": { + "ISSO": "isso-tbd", + "ClientOrganization": "client-organization-tag", + "CostCenter": "cost-center-tag", + "DataSensitivity": "data-sensitivity-tag", + "ProjectContact": "project-contact-tag", + "ProjectName": "project-name-tag", + "TechnicalContact": "technical-contact-tag" + } + }, + "resourceTags": { + "value": { + "ClientOrganization": "client-organization-tag", + "CostCenter": "cost-center-tag", + "DataSensitivity": "data-sensitivity-tag", + "ProjectContact": "project-contact-tag", + "ProjectName": "project-name-tag", + "TechnicalContact": "technical-contact-tag" + } + }, + "resourceGroups": { + "value": { + "automation": "automation", + "networking": "networking", + "networkWatcher": "NetworkWatcherRG", + "backupRecoveryVault": "backup", + "domainControllers": "DomainControllersRG", + "dnsResolver": "dns-resolverRG", + "dnsCondionalForwarders": "dns-CondionalForwardersRG", + "privateDnsZones": "pubsec-dns" + } + }, + "automation": { + "value": { + "name": "automation" + } + }, + "backupRecoveryVault": { + "value": { + "enabled": true, + "name": "backup-vault" + } + }, + "privateDnsZones": { + "value": { + "enabled": false, + "resourceGroupName": "pubsec-dns" + } + }, + "privateDnsResolver": { + "value": { + "enabled": true, + "name": "dns-resolver", + "inboundEndpointName": "dns-resolver-Inbound", + "outboundEndpointName": "dns-resolver-Outbound" + } + }, + "privateDnsResolverRuleset": { + "value": { + "enabled": true, + "name": "dns-resolver-ruleset", + "linkRuleSetToVnet": true, + "linkRuleSetToVnetName": "dns-resolver-vnet-link", + "forwardingRules": [ + { + "name": "default", + "domain": "dontMakeMeThink.local", + "state": "Enabled", + "targetDnsServers": [ + { + "ipAddress": "10.99.99.100" + }, + { + "ipAddress": "10.99.99.99" + } + ] + } + ] + } + }, + "hubNetwork": { + "value": { + "virtualNetworkId": "/subscriptions/4fd845de-f6c8-4e6d-9a87-c21c4ebf7edd/resourceGroups/pubsec-hub-networking/providers/Microsoft.Network/virtualNetworks/hub-vnet", + "rfc1918IPRange": "10.18.0.0/22", + "rfc6598IPRange": "100.60.0.0/16", + "egressVirtualApplianceIp": "10.18.1.4" + } + }, + "network": { + "value": { + "deployVnet": true, + "peerToHubVirtualNetwork": true, + "useRemoteGateway": false, + "name": "id-vnet", + "dnsServers": [ + "10.18.1.4" + ], + "addressPrefixes": [ + "10.15.0.0/24" + ], + "subnets": { + "domainControllers": { + "comments": "Identity Subnet for Domain Controllers and VM-Based DNS Servers", + "name": "DomainControllers", + "addressPrefix": "10.15.0.0/27" + }, + "dnsResolverInbound": { + "comments": "Azure DNS Resolver Inbound Requests subnet", + "name": "AzureDNSResolver-Inbound", + "addressPrefix": "10.15.0.32/27" + }, + "dnsResolverOutbound": { + "comments": "Azure DNS Resolver Outbound Requests subnet", + "name": "AzureDNSResolver-Outbound", + "addressPrefix": "10.15.0.64/27" + }, + "optional": [] + } + } + } + } +} diff --git a/config/identity/cdssnc-main/identity.parameters.json b/config/identity/cdssnc-main/identity.parameters.json new file mode 100644 index 00000000..c7eb762a --- /dev/null +++ b/config/identity/cdssnc-main/identity.parameters.json @@ -0,0 +1,178 @@ +{ + "$schema": "https://raw.githubusercontent.com/Azure/CanadaPubSecALZ/main/schemas/latest/landingzones/lz-platform-identity.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "serviceHealthAlerts": { + "value": { + "alertRuleName": "Identity Alerts", + "receivers": { + "app": [ + ], + "sms": [ + + ], + "email": [ + "sre-and-tech-ops@cds-snc.ca " + ], + "voice": [ + ] + }, + "regions": [ + "Global", + "Canada Central", + "Canada East" + ], + "resourceGroupName": "service-health-alerts-rg", + "actionGroupName": "Identity Alerts", + "actionGroupShortName": "identity-ag", + "incidentTypes": [ + "Incident", + "Security" + ], + "alertRuleDescription": "Identity Alerts for Incidents and Security" + } + }, + "securityCenter": { + "value": { + "email": "security@cds-snc.ca", + "phone": "" + } + }, + "subscriptionRoleAssignments": { + "value": [ + { + "comments": "Built-in Contributor Role", + "securityGroupObjectIds": [ + ], + "roleDefinitionId": "b24988ac-6180-42a0-ab88-20f7382dd24c" + } + ] + }, + "subscriptionBudget": { + "value": { + "createBudget": false + } + }, + "subscriptionTags": { + "value": { + "ISSO": "security@cds-snc.ca", + "ClientOrganization": "cds-snc", + "CostCenter": "sentinel", + "DataSensitivity": "U", + "ProjectContact": "Security@CDS", + "ProjectName": "Sentinel", + "TechnicalContact": "security@cds-snc.ca" + } + }, + "resourceTags": { + "value": { + "ClientOrganization": "cds-snc", + "CostCenter": "sentinel", + "DataSensitivity": "U", + "ProjectContact": "Security@CDS", + "ProjectName": "Sentinel", + "TechnicalContact": "security@cds-snc.ca" + } + }, + "resourceGroups": { + "value": { + "automation": "automation", + "networking": "networking", + "networkWatcher": "NetworkWatcherRG", + "backupRecoveryVault": "backup", + "domainControllers": "DomainControllersRG", + "dnsResolver": "dns-resolverRG", + "dnsCondionalForwarders": "dns-CondionalForwardersRG", + "privateDnsZones": "pubsec-dns" + } + }, + "automation": { + "value": { + "name": "automation" + } + }, + "backupRecoveryVault": { + "value": { + "enabled": true, + "name": "backup-vault" + } + }, + "privateDnsZones": { + "value": { + "enabled": false, + "resourceGroupName": "pubsec-dns" + } + }, + "privateDnsResolver": { + "value": { + "enabled": true, + "name": "dns-resolver", + "inboundEndpointName": "dns-resolver-Inbound", + "outboundEndpointName": "dns-resolver-Outbound" + } + }, + "privateDnsResolverRuleset": { + "value": { + "enabled": true, + "name": "dns-resolver-ruleset", + "linkRuleSetToVnet": true, + "linkRuleSetToVnetName": "dns-resolver-vnet-link", + "forwardingRules": [ + { + "name": "default", + "domain": "dontMakeMeThink.local", + "state": "Enabled", + "targetDnsServers": [ + { + "ipAddress": "10.99.99.100" + }, + { + "ipAddress": "10.99.99.99" + } + ] + } + ] + } + }, + "hubNetwork": { + "value": { + "virtualNetworkId": "/subscriptions/4fd845de-f6c8-4e6d-9a87-c21c4ebf7edd/resourceGroups/pubsec-hub-networking/providers/Microsoft.Network/virtualNetworks/hub-vnet", + "rfc1918IPRange": "10.18.0.0/22", + "rfc6598IPRange": "100.60.0.0/16", + "egressVirtualApplianceIp": "10.18.1.4" + } + }, + "network": { + "value": { + "deployVnet": true, + "peerToHubVirtualNetwork": true, + "useRemoteGateway": false, + "name": "id-vnet", + "dnsServers": [ + "10.18.1.4" + ], + "addressPrefixes": [ + "10.15.0.0/24" + ], + "subnets": { + "domainControllers": { + "comments": "Identity Subnet for Domain Controllers and VM-Based DNS Servers", + "name": "DomainControllers", + "addressPrefix": "10.15.0.0/27" + }, + "dnsResolverInbound": { + "comments": "Azure DNS Resolver Inbound Requests subnet", + "name": "AzureDNSResolver-Inbound", + "addressPrefix": "10.15.0.32/27" + }, + "dnsResolverOutbound": { + "comments": "Azure DNS Resolver Outbound Requests subnet", + "name": "AzureDNSResolver-Outbound", + "addressPrefix": "10.15.0.64/27" + }, + "optional": [] + } + } + } + } +} diff --git a/config/logging/CanadaPubSecALZ-main/logging.parameters.json b/config/logging/CanadaPubSecALZ-main/logging.parameters.json new file mode 100644 index 00000000..ee0ee242 --- /dev/null +++ b/config/logging/CanadaPubSecALZ-main/logging.parameters.json @@ -0,0 +1,149 @@ +{ + "$schema": "https://raw.githubusercontent.com/Azure/CanadaPubSecALZ/main/schemas/latest/landingzones/lz-platform-logging.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "serviceHealthAlerts": { + "value": { + "alertRuleName": "Logging Alerts", + "receivers": { + "app": [ + "logging@example.com" + ], + "sms": [ + { + "countryCode": "1", + "phoneNumber": "6135555555" + } + ], + "email": [ + "logging@example.com" + ], + "voice": [ + { + "countryCode": "1", + "phoneNumber": "6135555555" + } + ] + }, + "regions": [ + "Global", + "Canada Central", + "Canada East" + ], + "resourceGroupName": "service-health-alerts-rg", + "actionGroupName": "Logging Alerts", + "actionGroupShortName": "logging-ag", + "incidentTypes": [ + "Incident", + "Security" + ], + "alertRuleDescription": "Logging Alerts for Incidents and Security" + } + }, + "securityCenter": { + "value": { + "email": "security@example.com", + "phone": "6135555555" + } + }, + "subscriptionRoleAssignments": { + "value": [ + { + "comments": "Built-in Contributor Role", + "securityGroupObjectIds": [ + "9e16fb9d-7ea4-43fb-a92c-a5dbe308f921" + ], + "roleDefinitionId": "b24988ac-6180-42a0-ab88-20f7382dd24c" + } + ] + }, + "subscriptionBudget": { + "value": { + "createBudget": false + } + }, + "subscriptionTags": { + "value": { + "ISSO": "isso-tbd" + } + }, + "resourceTags": { + "value": { + "ClientOrganization": "client-organization-tag", + "CostCenter": "cost-center-tag", + "DataSensitivity": "data-sensitivity-tag", + "ProjectContact": "project-contact-tag", + "ProjectName": "project-name-tag", + "TechnicalContact": "technical-contact-tag" + } + }, + "logAnalyticsResourceGroupName": { + "value": "pubsec-central-logging" + }, + "logAnalyticsWorkspaceName": { + "value": "log-analytics-workspace" + }, + "logAnalyticsRetentionInDays": { + "value": 730 + }, + "logAnalyticsAutomationAccountName": { + "value": "automation-account" + }, + "dataCollectionRule": { + "value": { + "enabled": false, + "name": "DCR-AzureMonitorLogs", + "windowsEventLogs": [ + { + "streams": [ + "Microsoft-Event" + ], + "xPathQueries": [ + "Application!*[System[(Level=1 or Level=2 or Level=3)]]", + "Security!*[System[(band(Keywords,13510798882111488))]]", + "System!*[System[(Level=1 or Level=2 or Level=3)]]" + ], + "name": "eventLogsDataSource" + } + ], + "syslog": [ + { + "streams": [ + "Microsoft-Syslog" + ], + "facilityNames": [ + "auth", + "authpriv", + "cron", + "daemon", + "mark", + "kern", + "local0", + "local1", + "local2", + "local3", + "local4", + "local5", + "local6", + "local7", + "lpr", + "mail", + "news", + "syslog", + "user", + "uucp" + ], + "logLevels": [ + "Warning", + "Error", + "Critical", + "Alert", + "Emergency" + ], + "name": "sysLogsDataSource" + } + ] + } + } + } +} diff --git a/config/networking/CanadaPubSecALZ-main/hub-azfw-policy/azure-firewall-policy.parameters.json b/config/networking/CanadaPubSecALZ-main/hub-azfw-policy/azure-firewall-policy.parameters.json new file mode 100644 index 00000000..becb6455 --- /dev/null +++ b/config/networking/CanadaPubSecALZ-main/hub-azfw-policy/azure-firewall-policy.parameters.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://raw.githubusercontent.com/Azure/CanadaPubSecALZ/main/schemas/latest/landingzones/lz-platform-connectivity-hub-azfw-policy.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "resourceTags": { + "value": { + "ClientOrganization": "client-organization-tag", + "CostCenter": "cost-center-tag", + "DataSensitivity": "data-sensitivity-tag", + "ProjectContact": "project-contact-tag", + "ProjectName": "project-name-tag", + "TechnicalContact": "technical-contact-tag" + } + }, + "resourceGroupName": { + "value": "pubsec-azure-firewall-policy" + }, + "policyName": { + "value": "pubsecAzureFirewallPolicy" + } + } +} diff --git a/config/networking/CanadaPubSecALZ-main/hub-azfw/hub-network.parameters.json b/config/networking/CanadaPubSecALZ-main/hub-azfw/hub-network.parameters.json new file mode 100644 index 00000000..b6ecc49b --- /dev/null +++ b/config/networking/CanadaPubSecALZ-main/hub-azfw/hub-network.parameters.json @@ -0,0 +1,231 @@ +{ + "$schema": "https://raw.githubusercontent.com/Azure/CanadaPubSecALZ/main/schemas/latest/landingzones/lz-platform-connectivity-hub-azfw.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "serviceHealthAlerts": { + "value": { + "alertRuleName": "Networking Alerts", + "receivers": { + "app": [ + "networking@example.com" + ], + "sms": [ + { + "countryCode": "1", + "phoneNumber": "6135555555" + } + ], + "email": [ + "networking@example.com" + ], + "voice": [ + { + "countryCode": "1", + "phoneNumber": "6135555555" + } + ] + }, + "regions": [ + "Global", + "Canada Central", + "Canada East" + ], + "resourceGroupName": "service-health-alerts-rg", + "actionGroupName": "Networking Alerts", + "actionGroupShortName": "network-ag", + "incidentTypes": [ + "Incident", + "Security" + ], + "alertRuleDescription": "Networking Alerts for Incidents and Security" + } + }, + "securityCenter": { + "value": { + "email": "security@example.com", + "phone": "6135555555" + } + }, + "subscriptionRoleAssignments": { + "value": [ + { + "comments": "Built-in Contributor Role", + "securityGroupObjectIds": [ + "12d01649-fdb7-4769-afe5-66248082a064" + ], + "roleDefinitionId": "b24988ac-6180-42a0-ab88-20f7382dd24c" + } + ] + }, + "subscriptionBudget": { + "value": { + "createBudget": false + } + }, + "subscriptionTags": { + "value": { + "ISSO": "isso-tbd" + } + }, + "resourceTags": { + "value": { + "ClientOrganization": "client-organization-tag", + "CostCenter": "cost-center-tag", + "DataSensitivity": "data-sensitivity-tag", + "ProjectContact": "project-contact-tag", + "ProjectName": "project-name-tag", + "TechnicalContact": "technical-contact-tag" + } + }, + "privateDnsZones": { + "value": { + "enabled": true, + "resourceGroupName": "private-dns-rg" + } + }, + "ddosStandard": { + "value": { + "resourceGroupName": "ddos-rg", + "enabled": false, + "planName": "ddos-plan" + } + }, + "publicAccessZone": { + "value": { + "enabled": true, + "resourceGroupName": "pubsec-public-access-zone" + } + }, + "managementRestrictedZone": { + "value": { + "enabled": true, + "resourceGroupName": "pubsec-management-restricted-zone", + "network": { + "name": "management-restricted-vnet", + "addressPrefixes": [ + "10.18.4.0/22" + ], + "subnets": [ + { + "comments": "Management (Access Zone) Subnet", + "name": "MazSubnet", + "addressPrefix": "10.18.4.0/25", + "nsg": { + "enabled": true + }, + "udr": { + "enabled": true + } + }, + { + "comments": "Infrastructure Services (Restricted Zone) Subnet", + "name": "InfSubnet", + "addressPrefix": "10.18.4.128/25", + "nsg": { + "enabled": true + }, + "udr": { + "enabled": true + } + }, + { + "comments": "Security Services (Restricted Zone) Subnet", + "name": "SecSubnet", + "addressPrefix": "10.18.5.0/26", + "nsg": { + "enabled": true + }, + "udr": { + "enabled": true + } + }, + { + "comments": "Logging Services (Restricted Zone) Subnet", + "name": "LogSubnet", + "addressPrefix": "10.18.5.64/26", + "nsg": { + "enabled": true + }, + "udr": { + "enabled": true + } + }, + { + "comments": "Core Management Interfaces (Restricted Zone) Subnet", + "name": "MgmtSubnet", + "addressPrefix": "10.18.5.128/26", + "nsg": { + "enabled": true + }, + "udr": { + "enabled": true + } + } + ] + } + } + }, + "hub": { + "value": { + "resourceGroupName": "pubsec-hub-networking", + "bastion": { + "enabled": true, + "name": "bastion", + "sku": "Standard", + "scaleUnits": 2 + }, + "azureFirewall": { + "name": "pubsecAzureFirewall", + "availabilityZones": [ + "1", + "2", + "3" + ], + "forcedTunnelingEnabled": false, + "forcedTunnelingNextHop": "10.17.1.4" + }, + "network": { + "name": "hub-vnet", + "addressPrefixes": [ + "10.18.0.0/22", + "100.60.0.0/16" + ], + "addressPrefixBastion": "192.168.0.0/16", + "subnets": { + "gateway": { + "comments": "Gateway Subnet used for VPN and/or Express Route connectivity", + "name": "GatewaySubnet", + "addressPrefix": "10.18.0.0/27" + }, + "firewall": { + "comments": "Azure Firewall", + "name": "AzureFirewallSubnet", + "addressPrefix": "10.18.1.0/24" + }, + "firewallManagement": { + "comments": "Azure Firewall Management", + "name": "AzureFirewallManagementSubnet", + "addressPrefix": "10.18.2.0/26" + }, + "bastion": { + "comments": "Azure Bastion", + "name": "AzureBastionSubnet", + "addressPrefix": "192.168.0.0/24" + }, + "publicAccess": { + "comments": "Public Access Zone (Application Gateway)", + "name": "PAZSubnet", + "addressPrefix": "100.60.1.0/24" + }, + "optional": [] + } + } + } + }, + "networkWatcher": { + "value": { + "resourceGroupName": "NetworkWatcherRG" + } + } + } +} diff --git a/config/networking/CanadaPubSecALZ-main/hub-nva/hub-network.parameters.json b/config/networking/CanadaPubSecALZ-main/hub-nva/hub-network.parameters.json new file mode 100644 index 00000000..2dcd55f5 --- /dev/null +++ b/config/networking/CanadaPubSecALZ-main/hub-nva/hub-network.parameters.json @@ -0,0 +1,318 @@ +{ + "$schema": "https://raw.githubusercontent.com/Azure/CanadaPubSecALZ/main/schemas/latest/landingzones/lz-platform-connectivity-hub-nva.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "serviceHealthAlerts": { + "value": { + "alertRuleName": "Networking Alerts", + "receivers": { + "app": [ + "networking@example.com" + ], + "sms": [ + { + "countryCode": "1", + "phoneNumber": "6135555555" + } + ], + "email": [ + "networking@example.com" + ], + "voice": [ + { + "countryCode": "1", + "phoneNumber": "6135555555" + } + ] + }, + "regions": [ + "Global", + "Canada Central", + "Canada East" + ], + "resourceGroupName": "service-health-alerts-rg", + "actionGroupName": "Networking Alerts", + "actionGroupShortName": "network-ag", + "incidentTypes": [ + "Incident", + "Security" + ], + "alertRuleDescription": "Networking Alerts for Incidents and Security" + } + }, + "securityCenter": { + "value": { + "email": "security@example.com", + "phone": "6135555555" + } + }, + "subscriptionRoleAssignments": { + "value": [ + { + "comments": "Built-in Contributor Role", + "securityGroupObjectIds": [ + "12d01649-fdb7-4769-afe5-66248082a064" + ], + "roleDefinitionId": "b24988ac-6180-42a0-ab88-20f7382dd24c" + } + ] + }, + "subscriptionBudget": { + "value": { + "createBudget": false + } + }, + "subscriptionTags": { + "value": { + "ISSO": "isso-tbd" + } + }, + "resourceTags": { + "value": { + "ClientOrganization": "client-organization-tag", + "CostCenter": "cost-center-tag", + "DataSensitivity": "data-sensitivity-tag", + "ProjectContact": "project-contact-tag", + "ProjectName": "project-name-tag", + "TechnicalContact": "technical-contact-tag" + } + }, + "privateDnsZones": { + "value": { + "enabled": true, + "resourceGroupName": "private-dns-rg" + } + }, + "ddosStandard": { + "value": { + "resourceGroupName": "ddos-rg", + "enabled": false, + "planName": "ddos-plan" + } + }, + "publicAccessZone": { + "value": { + "enabled": true, + "resourceGroupName": "pubsec-public-access-zone" + } + }, + "managementRestrictedZone": { + "value": { + "enabled": true, + "resourceGroupName": "pubsec-management-restricted-zone", + "network": { + "name": "management-restricted-vnet", + "addressPrefixes": [ + "10.18.4.0/22" + ], + "subnets": [ + { + "comments": "Management (Access Zone) Subnet", + "name": "MazSubnet", + "addressPrefix": "10.18.4.0/25", + "nsg": { + "enabled": true + }, + "udr": { + "enabled": true + } + }, + { + "comments": "Infrastructure Services (Restricted Zone) Subnet", + "name": "InfSubnet", + "addressPrefix": "10.18.4.128/25", + "nsg": { + "enabled": true + }, + "udr": { + "enabled": true + } + }, + { + "comments": "Security Services (Restricted Zone) Subnet", + "name": "SecSubnet", + "addressPrefix": "10.18.5.0/26", + "nsg": { + "enabled": true + }, + "udr": { + "enabled": true + } + }, + { + "comments": "Logging Services (Restricted Zone) Subnet", + "name": "LogSubnet", + "addressPrefix": "10.18.5.64/26", + "nsg": { + "enabled": true + }, + "udr": { + "enabled": true + } + }, + { + "comments": "Core Management Interfaces (Restricted Zone) Subnet", + "name": "MgmtSubnet", + "addressPrefix": "10.18.5.128/26", + "nsg": { + "enabled": true + }, + "udr": { + "enabled": true + } + } + ] + } + } + }, + "hub": { + "value": { + "resourceGroupName": "pubsec-hub-networking", + "bastion": { + "enabled": true, + "name": "bastion", + "sku": "Standard", + "scaleUnits": 2 + }, + "network": { + "name": "hub-vnet", + "addressPrefixes": [ + "10.18.0.0/22", + "100.60.0.0/16" + ], + "addressPrefixBastion": "192.168.0.0/16", + "subnets": { + "gateway": { + "comments": "Gateway Subnet used for VPN and/or Express Route connectivity", + "name": "GatewaySubnet", + "addressPrefix": "10.18.1.0/27" + }, + "bastion": { + "comments": "Azure Bastion", + "name": "AzureBastionSubnet", + "addressPrefix": "192.168.0.0/24" + }, + "public": { + "comments": "Public Subnet Name (External Facing (Internet/Ground))", + "name": "PublicSubnet", + "addressPrefix": "100.60.0.0/24" + }, + "publicAccessZone": { + "comments": "Public Access Zone (i.e. Application Gateway)", + "name": "PAZSubnet", + "addressPrefix": "100.60.1.0/24" + }, + "externalAccessNetwork": { + "comments": "External Access Network", + "name": "EanSubnet", + "addressPrefix": "10.18.0.0/27" + }, + "nonProductionInternal": { + "comments": "Non-production Internal for firewall appliances (Internal Facing Non-Production Traffic)", + "name": "DevIntSubnet", + "addressPrefix": "10.18.0.64/27" + }, + "productionInternal": { + "comments": "Production Internal for firewall appliances (Internal Facing Production Traffic)", + "name": "PrdIntSubnet", + "addressPrefix": "10.18.0.32/27" + }, + "managementRestrictedZoneInternal": { + "comments": "Management Restricted Zone", + "name": "MrzSubnet", + "addressPrefix": "10.18.0.96/27" + }, + "highAvailability": { + "comments": "High Availability (Firewall to Firewall heartbeat)", + "name": "HASubnet", + "addressPrefix": "10.18.0.128/28" + }, + "optional": [] + } + }, + "nvaFirewall": { + "image": { + "publisher": "fortinet", + "offer": "fortinet_fortigate-vm_v5", + "sku": "fortinet_fg-vm", + "version": "6.4.5", + "plan": "fortinet_fg-vm" + }, + "nonProduction": { + "internalLoadBalancer": { + "name": "pubsecDevFWILB", + "tcpProbe": { + "name": "lbprobe", + "port": 8008, + "intervalInSeconds": 5, + "numberOfProbes": 2 + }, + "internalIp": "10.18.0.68", + "externalIp": "100.60.0.7" + }, + "deployVirtualMachines": false, + "virtualMachines": [ + { + "name": "pubsecDevFW1", + "vmSku": "Standard_D8s_v4", + "internalIp": "10.18.0.69", + "externalIp": "100.60.0.8", + "mrzInternalIp": "10.18.0.104", + "highAvailabilityIp": "10.18.0.134", + "availabilityZone": "2" + }, + { + "name": "pubsecDevFW2", + "vmSku": "Standard_D8s_v4", + "internalIp": "10.18.0.70", + "externalIp": "100.60.0.9", + "mrzInternalIp": "10.18.0.105", + "highAvailabilityIp": "10.18.0.135", + "availabilityZone": "3" + } + ] + }, + "production": { + "internalLoadBalancer": { + "name": "pubsecProdFWILB", + "tcpProbe": { + "name": "lbprobe", + "port": 8008, + "intervalInSeconds": 5, + "numberOfProbes": 2 + }, + "internalIp": "10.18.0.36", + "externalIp": "100.60.0.4" + }, + "deployVirtualMachines": false, + "virtualMachines": [ + { + "name": "pubsecProdFW1", + "vmSku": "Standard_F8s_v2", + "internalIp": "10.18.0.37", + "externalIp": "100.60.0.5", + "mrzInternalIp": "10.18.0.101", + "highAvailabilityIp": "10.18.0.132", + "availabilityZone": "1" + }, + { + "name": "pubsecProdFW2", + "vmSku": "Standard_F8s_v2", + "internalIp": "10.18.0.38", + "externalIp": "100.60.0.6", + "mrzInternalIp": "10.18.0.102", + "highAvailabilityIp": "10.18.0.133", + "availabilityZone": "2" + } + ] + } + } + } + }, + "networkWatcher": { + "value": { + "resourceGroupName": "NetworkWatcherRG" + } + } + } +} diff --git a/config/networking/cdssnc-main/hub-azfw-policy/azure-firewall-policy.parameters.json b/config/networking/cdssnc-main/hub-azfw-policy/azure-firewall-policy.parameters.json new file mode 100644 index 00000000..2533f5a9 --- /dev/null +++ b/config/networking/cdssnc-main/hub-azfw-policy/azure-firewall-policy.parameters.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://raw.githubusercontent.com/Azure/CanadaPubSecALZ/main/schemas/latest/landingzones/lz-platform-connectivity-hub-azfw-policy.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "resourceTags": { + "value": { + "ClientOrganization": "cds-snc", + "CostCenter": "sentinel", + "DataSensitivity": "U", + "ProjectContact": "Security@CDS", + "ProjectName": "Sentinel", + "TechnicalContact": "security@cds-snc.ca" + } + }, + "resourceGroupName": { + "value": "pubsec-azure-firewall-policy" + }, + "policyName": { + "value": "pubsecAzureFirewallPolicy" + } + } +} diff --git a/config/networking/cdssnc-main/hub-azfw/hub-network.parameters.json b/config/networking/cdssnc-main/hub-azfw/hub-network.parameters.json new file mode 100644 index 00000000..ee754e4d --- /dev/null +++ b/config/networking/cdssnc-main/hub-azfw/hub-network.parameters.json @@ -0,0 +1,224 @@ +{ + "$schema": "https://raw.githubusercontent.com/Azure/CanadaPubSecALZ/main/schemas/latest/landingzones/lz-platform-connectivity-hub-azfw.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "serviceHealthAlerts": { + "value": { + "alertRuleName": "Networking Alerts", + "receivers": { + "app": [ + + ], + "sms": [ + + ], + "email": [ + "sre-and-tech-ops@cds-snc.ca" + ], + "voice": [ + + ] + }, + "regions": [ + "Global", + "Canada Central", + "Canada East" + ], + "resourceGroupName": "service-health-alerts-rg", + "actionGroupName": "Networking Alerts", + "actionGroupShortName": "network-ag", + "incidentTypes": [ + "Incident", + "Security" + ], + "alertRuleDescription": "Networking Alerts for Incidents and Security" + } + }, + "securityCenter": { + "value": { + "email": "security@cds-snc.ca", + "phone": "" + } + }, + "subscriptionRoleAssignments": { + "value": [ + { + "comments": "Built-in Contributor Role", + "securityGroupObjectIds": [ + ], + "roleDefinitionId": "b24988ac-6180-42a0-ab88-20f7382dd24c" + } + ] + }, + "subscriptionBudget": { + "value": { + "createBudget": false + } + }, + "subscriptionTags": { + "value": { + "ISSO": "security@cds-snc.ca" + } + }, + "resourceTags": { + "value": { + "ClientOrganization": "cds-snc", + "CostCenter": "sentinel", + "DataSensitivity": "U", + "ProjectContact": "Security@CDS", + "ProjectName": "Sentinel", + "TechnicalContact": "security@cds-snc.ca" + } + }, + "privateDnsZones": { + "value": { + "enabled": true, + "resourceGroupName": "private-dns-rg" + } + }, + "ddosStandard": { + "value": { + "resourceGroupName": "ddos-rg", + "enabled": false, + "planName": "ddos-plan" + } + }, + "publicAccessZone": { + "value": { + "enabled": true, + "resourceGroupName": "pubsec-public-access-zone" + } + }, + "managementRestrictedZone": { + "value": { + "enabled": true, + "resourceGroupName": "pubsec-management-restricted-zone", + "network": { + "name": "management-restricted-vnet", + "addressPrefixes": [ + "10.18.4.0/22" + ], + "subnets": [ + { + "comments": "Management (Access Zone) Subnet", + "name": "MazSubnet", + "addressPrefix": "10.18.4.0/25", + "nsg": { + "enabled": true + }, + "udr": { + "enabled": true + } + }, + { + "comments": "Infrastructure Services (Restricted Zone) Subnet", + "name": "InfSubnet", + "addressPrefix": "10.18.4.128/25", + "nsg": { + "enabled": true + }, + "udr": { + "enabled": true + } + }, + { + "comments": "Security Services (Restricted Zone) Subnet", + "name": "SecSubnet", + "addressPrefix": "10.18.5.0/26", + "nsg": { + "enabled": true + }, + "udr": { + "enabled": true + } + }, + { + "comments": "Logging Services (Restricted Zone) Subnet", + "name": "LogSubnet", + "addressPrefix": "10.18.5.64/26", + "nsg": { + "enabled": true + }, + "udr": { + "enabled": true + } + }, + { + "comments": "Core Management Interfaces (Restricted Zone) Subnet", + "name": "MgmtSubnet", + "addressPrefix": "10.18.5.128/26", + "nsg": { + "enabled": true + }, + "udr": { + "enabled": true + } + } + ] + } + } + }, + "hub": { + "value": { + "resourceGroupName": "pubsec-hub-networking", + "bastion": { + "enabled": true, + "name": "bastion", + "sku": "Standard", + "scaleUnits": 2 + }, + "azureFirewall": { + "name": "pubsecAzureFirewall", + "availabilityZones": [ + "1", + "2", + "3" + ], + "forcedTunnelingEnabled": false, + "forcedTunnelingNextHop": "10.17.1.4" + }, + "network": { + "name": "hub-vnet", + "addressPrefixes": [ + "10.18.0.0/22", + "100.60.0.0/16" + ], + "addressPrefixBastion": "192.168.0.0/16", + "subnets": { + "gateway": { + "comments": "Gateway Subnet used for VPN and/or Express Route connectivity", + "name": "GatewaySubnet", + "addressPrefix": "10.18.0.0/27" + }, + "firewall": { + "comments": "Azure Firewall", + "name": "AzureFirewallSubnet", + "addressPrefix": "10.18.1.0/24" + }, + "firewallManagement": { + "comments": "Azure Firewall Management", + "name": "AzureFirewallManagementSubnet", + "addressPrefix": "10.18.2.0/26" + }, + "bastion": { + "comments": "Azure Bastion", + "name": "AzureBastionSubnet", + "addressPrefix": "192.168.0.0/24" + }, + "publicAccess": { + "comments": "Public Access Zone (Application Gateway)", + "name": "PAZSubnet", + "addressPrefix": "100.60.1.0/24" + }, + "optional": [] + } + } + } + }, + "networkWatcher": { + "value": { + "resourceGroupName": "NetworkWatcherRG" + } + } + } +} diff --git a/config/subscriptions/CanadaPubSecALZ-main/DevTest/0a5970ed-b9d5-464a-acef-8a06f0d7a360_machinelearning_canadacentral.json b/config/subscriptions/CanadaPubSecALZ-main/DevTest/0a5970ed-b9d5-464a-acef-8a06f0d7a360_machinelearning_canadacentral.json new file mode 100644 index 00000000..ad33c1ca --- /dev/null +++ b/config/subscriptions/CanadaPubSecALZ-main/DevTest/0a5970ed-b9d5-464a-acef-8a06f0d7a360_machinelearning_canadacentral.json @@ -0,0 +1,206 @@ +{ + "$schema": "https://raw.githubusercontent.com/Azure/CanadaPubSecALZ/main/schemas/latest/landingzones/lz-machinelearning.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "serviceHealthAlerts": { + "value": { + "alertRuleName": "Subscription Owners Alerts", + "receivers": { + "app": [ + "subscription-owners@example.com" + ], + "sms": [ + { + "countryCode": "1", + "phoneNumber": "6135555555" + } + ], + "email": [ + "subscription-owners@example.com" + ], + "voice": [ + { + "countryCode": "1", + "phoneNumber": "6135555555" + } + ] + }, + "regions": [ + "Global", + "Canada Central", + "Canada East" + ], + "resourceGroupName": "service-health-alerts-rg", + "actionGroupName": "Subscription Owners Alerts", + "actionGroupShortName": "sub-own-ag", + "incidentTypes": [ + "Incident", + "Security" + ], + "alertRuleDescription": "Subscription Owners Alerts for Incidents and Security" + } + }, + "securityCenter": { + "value": { + "email": "security@example.com", + "phone": "6135555555" + } + }, + "subscriptionRoleAssignments": { + "value": [ + { + "comments": "Built-in Contributor Role", + "securityGroupObjectIds": [ + "49f9256a-d77a-43ba-8cc5-957eb40dedee" + ], + "roleDefinitionId": "b24988ac-6180-42a0-ab88-20f7382dd24c" + }, + { + "comments": "Custom Role: Landing Zone Application Owner", + "securityGroupObjectIds": [ + "43d97b7e-27b8-4fa7-a339-c935f7752bb9" + ], + "roleDefinitionId": "b4c87314-c1a1-5320-9c43-779585186bcc" + } + ] + }, + "subscriptionBudget": { + "value": { + "createBudget": false + } + }, + "subscriptionTags": { + "value": { + "ISSO": "isso-tag" + } + }, + "resourceTags": { + "value": { + "ClientOrganization": "client-organization-tag", + "CostCenter": "cost-center-tag", + "DataSensitivity": "data-sensitivity-tag", + "ProjectContact": "project-contact-tag", + "ProjectName": "project-name-tag", + "TechnicalContact": "technical-contact-tag" + } + }, + "resourceGroups": { + "value": { + "automation": "azmlnocmk-automation", + "compute": "azmlnocmk-compute", + "monitor": "azmlnocmk-monitor", + "networking": "azmlnocmk-networking", + "networkWatcher": "NetworkWatcherRG", + "security": "azmlnocmk-security", + "storage": "azmlnocmk-storage" + } + }, + "useCMK": { + "value": false + }, + "automation": { + "value": { + "name": "automation" + } + }, + "keyVault": { + "value": { + "secretExpiryInDays": 3650 + } + }, + "aks": { + "value": { + "version": "1.25.5", + "enabled": true, + "networkPlugin": "kubenet", + "networkPolicy": "calico", + "podCidr": "11.0.0.0/16", + "serviceCidr": "20.0.0.0/16", + "dnsServiceIP": "20.0.0.10", + "dockerBridgeCidr": "30.0.0.1/16" + } + }, + "appServiceLinuxContainer": { + "value": { + "enabled": true, + "skuName": "P1V2", + "skuTier": "Premium", + "enablePrivateEndpoint": true + } + }, + "sqldb": { + "value": { + "enabled": true, + "sqlAuthenticationUsername": "azadmin", + "aadAuthenticationOnly": false + } + }, + "sqlmi": { + "value": { + "enabled": false + } + }, + "aml": { + "value": { + "enableHbiWorkspace": false + } + }, + "hubNetwork": { + "value": { + "virtualNetworkId": "/subscriptions/4fd845de-f6c8-4e6d-9a87-c21c4ebf7edd/resourceGroups/pubsec-hub-networking/providers/Microsoft.Network/virtualNetworks/hub-vnet", + "rfc1918IPRange": "10.18.0.0/22", + "rfc6598IPRange": "100.60.0.0/16", + "egressVirtualApplianceIp": "10.18.1.4", + "privateDnsManagedByHub": true, + "privateDnsManagedByHubSubscriptionId": "4fd845de-f6c8-4e6d-9a87-c21c4ebf7edd", + "privateDnsManagedByHubResourceGroupName": "private-dns-rg" + } + }, + "network": { + "value": { + "peerToHubVirtualNetwork": true, + "useRemoteGateway": false, + "name": "azmlnocmk-vnet", + "dnsServers": [ + "10.18.1.4" + ], + "addressPrefixes": [ + "10.3.0.0/16" + ], + "subnets": { + "sqlmi": { + "comments": "SQL Managed Instances Delegated Subnet", + "name": "sqlmi", + "addressPrefix": "10.3.5.0/25" + }, + "databricksPublic": { + "comments": "Databricks Public Delegated Subnet", + "name": "databrickspublic", + "addressPrefix": "10.3.6.0/25" + }, + "databricksPrivate": { + "comments": "Databricks Private Delegated Subnet", + "name": "databricksprivate", + "addressPrefix": "10.3.7.0/25" + }, + "privateEndpoints": { + "comments": "Private Endpoints Subnet", + "name": "privateendpoints", + "addressPrefix": "10.3.8.0/25" + }, + "aks": { + "comments": "AKS Subnet", + "name": "aks", + "addressPrefix": "10.3.9.0/25" + }, + "appService": { + "comments": "App Service Subnet", + "name": "appService", + "addressPrefix": "10.3.10.0/25" + }, + "optional": [] + } + } + } + } +} diff --git a/config/subscriptions/CanadaPubSecALZ-main/DevTest/1f519216-5e39-4b51-a9b6-10cc2b79b6c7_healthcare_canadacentral.json b/config/subscriptions/CanadaPubSecALZ-main/DevTest/1f519216-5e39-4b51-a9b6-10cc2b79b6c7_healthcare_canadacentral.json new file mode 100644 index 00000000..33ad6983 --- /dev/null +++ b/config/subscriptions/CanadaPubSecALZ-main/DevTest/1f519216-5e39-4b51-a9b6-10cc2b79b6c7_healthcare_canadacentral.json @@ -0,0 +1,200 @@ +{ + "$schema": "https://raw.githubusercontent.com/Azure/CanadaPubSecALZ/main/schemas/latest/landingzones/lz-healthcare.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "serviceHealthAlerts": { + "value": { + "alertRuleName": "Subscription Owners Alerts", + "receivers": { + "app": [ + "subscription-owners@example.com" + ], + "sms": [ + { + "countryCode": "1", + "phoneNumber": "6135555555" + } + ], + "email": [ + "subscription-owners@example.com" + ], + "voice": [ + { + "countryCode": "1", + "phoneNumber": "6135555555" + } + ] + }, + "regions": [ + "Global", + "Canada Central", + "Canada East" + ], + "resourceGroupName": "service-health-alerts-rg", + "actionGroupName": "Subscription Owners Alerts", + "actionGroupShortName": "sub-own-ag", + "incidentTypes": [ + "Incident", + "Security" + ], + "alertRuleDescription": "Subscription Owners Alerts for Incidents and Security" + } + }, + "securityCenter": { + "value": { + "email": "security@example.com", + "phone": "6135555555" + } + }, + "subscriptionRoleAssignments": { + "value": [ + { + "comments": "Built-in Contributor Role", + "securityGroupObjectIds": [ + "49f9256a-d77a-43ba-8cc5-957eb40dedee" + ], + "roleDefinitionId": "b24988ac-6180-42a0-ab88-20f7382dd24c" + }, + { + "comments": "Custom Role: Landing Zone Application Owner", + "securityGroupObjectIds": [ + "43d97b7e-27b8-4fa7-a339-c935f7752bb9" + ], + "roleDefinitionId": "b4c87314-c1a1-5320-9c43-779585186bcc" + } + ] + }, + "subscriptionBudget": { + "value": { + "createBudget": false + } + }, + "subscriptionTags": { + "value": { + "ISSO": "isso-tag" + } + }, + "resourceTags": { + "value": { + "ClientOrganization": "client-organization-tag", + "CostCenter": "cost-center-tag", + "DataSensitivity": "data-sensitivity-tag", + "ProjectContact": "project-contact-tag", + "ProjectName": "project-name-tag", + "TechnicalContact": "technical-contact-tag" + } + }, + "resourceGroups": { + "value": { + "automation": "health-automation", + "compute": "health-compute", + "monitor": "health-monitor", + "networking": "health-network", + "networkWatcher": "NetworkWatcherRG", + "security": "health-security", + "storage": "health-storage" + } + }, + "useCMK": { + "value": true + }, + "keyVault": { + "value": { + "secretExpiryInDays": 3650 + } + }, + "automation": { + "value": { + "name": "automation" + } + }, + "sqldb": { + "value": { + "enabled": true, + "sqlAuthenticationUsername": "azadmin", + "aadAuthenticationOnly": false + } + }, + "synapse": { + "value": { + "aadAuthenticationOnly": true, + "aadLoginName": "az.admins", + "aadLoginObjectID": "e0357d81-55d8-44e9-9d9c-ab09dc710785", + "aadLoginType": "Group" + } + }, + "hubNetwork": { + "value": { + "virtualNetworkId": "/subscriptions/4fd845de-f6c8-4e6d-9a87-c21c4ebf7edd/resourceGroups/pubsec-hub-networking/providers/Microsoft.Network/virtualNetworks/hub-vnet", + "rfc1918IPRange": "10.18.0.0/22", + "rfc6598IPRange": "100.60.0.0/16", + "egressVirtualApplianceIp": "10.18.1.4", + "privateDnsManagedByHub": true, + "privateDnsManagedByHubSubscriptionId": "4fd845de-f6c8-4e6d-9a87-c21c4ebf7edd", + "privateDnsManagedByHubResourceGroupName": "private-dns-rg" + } + }, + "network": { + "value": { + "peerToHubVirtualNetwork": true, + "useRemoteGateway": false, + "name": "health-vnet", + "dnsServers": [ + "10.18.1.4" + ], + "addressPrefixes": [ + "10.5.0.0/16" + ], + "subnets": { + "databricksPublic": { + "comments": "Databricks Public Delegated Subnet", + "name": "databrickspublic", + "addressPrefix": "10.5.5.0/25" + }, + "databricksPrivate": { + "comments": "Databricks Private Delegated Subnet", + "name": "databricksprivate", + "addressPrefix": "10.5.6.0/25" + }, + "privateEndpoints": { + "comments": "Private Endpoints Subnet", + "name": "privateendpoints", + "addressPrefix": "10.5.7.0/25" + }, + "web": { + "comments": "Azure Web App Delegated Subnet", + "name": "webapp", + "addressPrefix": "10.5.8.0/25" + }, + "optional": [ + { + "comments": "Optional Subnet 1", + "name": "virtualMachines", + "addressPrefix": "10.5.9.0/25", + "nsg": { + "enabled": true + }, + "udr": { + "enabled": true + } + }, + { + "comments": "Optional Subnet 2 with delegation for NetApp Volumes", + "name": "NetappVolumes", + "addressPrefix": "10.5.10.0/25", + "nsg": { + "enabled": false + }, + "udr": { + "enabled": false + }, + "delegations": { + "serviceName": "Microsoft.NetApp/volumes" + } + } + ] + } + } + } + } +} diff --git a/config/subscriptions/CanadaPubSecALZ-main/DevTest/8422552f-3840-4934-a971-6ee349ffbb05_generic-subscription_canadacentral.json b/config/subscriptions/CanadaPubSecALZ-main/DevTest/8422552f-3840-4934-a971-6ee349ffbb05_generic-subscription_canadacentral.json new file mode 100644 index 00000000..f7cd93c6 --- /dev/null +++ b/config/subscriptions/CanadaPubSecALZ-main/DevTest/8422552f-3840-4934-a971-6ee349ffbb05_generic-subscription_canadacentral.json @@ -0,0 +1,192 @@ +{ + "$schema": "https://raw.githubusercontent.com/Azure/CanadaPubSecALZ/main/schemas/latest/landingzones/lz-generic-subscription.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "location": { + "value": "canadacentral" + }, + "serviceHealthAlerts": { + "value": { + "alertRuleName": "Subscription Owners Alerts", + "receivers": { + "app": [ + "subscription-owners@example.com" + ], + "sms": [ + { + "countryCode": "1", + "phoneNumber": "6135555555" + } + ], + "email": [ + "subscription-owners@example.com" + ], + "voice": [ + { + "countryCode": "1", + "phoneNumber": "6135555555" + } + ] + }, + "regions": [ + "Global", + "Canada Central", + "Canada East" + ], + "resourceGroupName": "service-health-alerts-rg", + "actionGroupName": "Subscription Owners Alerts", + "actionGroupShortName": "sub-own-ag", + "incidentTypes": [ + "Incident", + "Security" + ], + "alertRuleDescription": "Subscription Owners Alerts for Incidents and Security" + } + }, + "securityCenter": { + "value": { + "email": "security@example.com", + "phone": "6135555555" + } + }, + "subscriptionRoleAssignments": { + "value": [ + { + "comments": "Built-in Contributor Role", + "securityGroupObjectIds": [ + "49f9256a-d77a-43ba-8cc5-957eb40dedee" + ], + "roleDefinitionId": "b24988ac-6180-42a0-ab88-20f7382dd24c" + }, + { + "comments": "Custom Role: Landing Zone Application Owner", + "securityGroupObjectIds": [ + "43d97b7e-27b8-4fa7-a339-c935f7752bb9" + ], + "roleDefinitionId": "b4c87314-c1a1-5320-9c43-779585186bcc" + } + ] + }, + "subscriptionBudget": { + "value": { + "createBudget": false + } + }, + "subscriptionTags": { + "value": { + "ISSO": "isso-tag" + } + }, + "resourceTags": { + "value": { + "ClientOrganization": "client-organization-tag", + "CostCenter": "cost-center-tag", + "DataSensitivity": "data-sensitivity-tag", + "ProjectContact": "project-contact-tag", + "ProjectName": "project-name-tag", + "TechnicalContact": "technical-contact-tag" + } + }, + "resourceGroups": { + "value": { + "automation": "automation", + "networking": "networking", + "networkWatcher": "NetworkWatcherRG", + "backupRecoveryVault": "backup" + } + }, + "automation": { + "value": { + "name": "automation" + } + }, + "backupRecoveryVault": { + "value": { + "enabled": true, + "name": "backup-vault" + } + }, + "hubNetwork": { + "value": { + "virtualNetworkId": "/subscriptions/4fd845de-f6c8-4e6d-9a87-c21c4ebf7edd/resourceGroups/pubsec-hub-networking/providers/Microsoft.Network/virtualNetworks/hub-vnet", + "rfc1918IPRange": "10.18.0.0/22", + "rfc6598IPRange": "100.60.0.0/16", + "egressVirtualApplianceIp": "10.18.1.4" + } + }, + "network": { + "value": { + "deployVnet": true, + "peerToHubVirtualNetwork": true, + "useRemoteGateway": false, + "name": "vnet", + "dnsServers": [ + "10.18.1.4" + ], + "addressPrefixes": [ + "10.2.0.0/16" + ], + "subnets": [ + { + "comments": "App Management Zone (OZ)", + "name": "appManagement", + "addressPrefix": "10.2.1.0/25", + "nsg": { + "enabled": true + }, + "udr": { + "enabled": true + } + }, + { + "comments": "Presentation Zone (PAZ)", + "name": "web", + "addressPrefix": "10.2.2.0/25", + "nsg": { + "enabled": true + }, + "udr": { + "enabled": true + } + }, + { + "comments": "Application Zone (RZ)", + "name": "app", + "addressPrefix": "10.2.3.0/25", + "nsg": { + "enabled": true + }, + "udr": { + "enabled": true + } + }, + { + "comments": "Data Zone (HRZ)", + "name": "data", + "addressPrefix": "10.2.4.0/25", + "nsg": { + "enabled": true + }, + "udr": { + "enabled": true + } + }, + { + "comments": "App Service", + "name": "appservice", + "addressPrefix": "10.2.5.0/25", + "nsg": { + "enabled": false + }, + "udr": { + "enabled": false + }, + "delegations": { + "serviceName": "Microsoft.Web/serverFarms" + } + } + ] + } + } + } +} diff --git a/config/subscriptions/CanadaPubSecALZ-main/DevTest/9d9817f5-c218-4553-b686-58be8d9ea82c_machinelearning_canadacentral.json b/config/subscriptions/CanadaPubSecALZ-main/DevTest/9d9817f5-c218-4553-b686-58be8d9ea82c_machinelearning_canadacentral.json new file mode 100644 index 00000000..e13ce6b6 --- /dev/null +++ b/config/subscriptions/CanadaPubSecALZ-main/DevTest/9d9817f5-c218-4553-b686-58be8d9ea82c_machinelearning_canadacentral.json @@ -0,0 +1,206 @@ +{ + "$schema": "https://raw.githubusercontent.com/Azure/CanadaPubSecALZ/main/schemas/latest/landingzones/lz-machinelearning.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "serviceHealthAlerts": { + "value": { + "alertRuleName": "Subscription Owners Alerts", + "receivers": { + "app": [ + "subscription-owners@example.com" + ], + "sms": [ + { + "countryCode": "1", + "phoneNumber": "6135555555" + } + ], + "email": [ + "subscription-owners@example.com" + ], + "voice": [ + { + "countryCode": "1", + "phoneNumber": "6135555555" + } + ] + }, + "regions": [ + "Global", + "Canada Central", + "Canada East" + ], + "resourceGroupName": "service-health-alerts-rg", + "actionGroupName": "Subscription Owners Alerts", + "actionGroupShortName": "sub-own-ag", + "incidentTypes": [ + "Incident", + "Security" + ], + "alertRuleDescription": "Subscription Owners Alerts for Incidents and Security" + } + }, + "securityCenter": { + "value": { + "email": "security@example.com", + "phone": "6135555555" + } + }, + "subscriptionRoleAssignments": { + "value": [ + { + "comments": "Built-in Contributor Role", + "securityGroupObjectIds": [ + "49f9256a-d77a-43ba-8cc5-957eb40dedee" + ], + "roleDefinitionId": "b24988ac-6180-42a0-ab88-20f7382dd24c" + }, + { + "comments": "Custom Role: Landing Zone Application Owner", + "securityGroupObjectIds": [ + "43d97b7e-27b8-4fa7-a339-c935f7752bb9" + ], + "roleDefinitionId": "b4c87314-c1a1-5320-9c43-779585186bcc" + } + ] + }, + "subscriptionBudget": { + "value": { + "createBudget": false + } + }, + "subscriptionTags": { + "value": { + "ISSO": "isso-tag" + } + }, + "resourceTags": { + "value": { + "ClientOrganization": "client-organization-tag", + "CostCenter": "cost-center-tag", + "DataSensitivity": "data-sensitivity-tag", + "ProjectContact": "project-contact-tag", + "ProjectName": "project-name-tag", + "TechnicalContact": "technical-contact-tag" + } + }, + "resourceGroups": { + "value": { + "automation": "azmlcmk-automation", + "compute": "azmlcmk-compute", + "monitor": "azmlcmk-monitor", + "networking": "azmlcmk-networking", + "networkWatcher": "NetworkWatcherRG", + "security": "azmlcmk-security", + "storage": "azmlcmk-storage" + } + }, + "useCMK": { + "value": true + }, + "automation": { + "value": { + "name": "automation" + } + }, + "keyVault": { + "value": { + "secretExpiryInDays": 3650 + } + }, + "aks": { + "value": { + "version": "1.25.5", + "enabled": true, + "networkPlugin": "kubenet", + "networkPolicy": "calico", + "podCidr": "11.0.0.0/16", + "serviceCidr": "20.0.0.0/16", + "dnsServiceIP": "20.0.0.10", + "dockerBridgeCidr": "30.0.0.1/16" + } + }, + "appServiceLinuxContainer": { + "value": { + "enabled": true, + "skuName": "P1V2", + "skuTier": "Premium", + "enablePrivateEndpoint": true + } + }, + "sqldb": { + "value": { + "enabled": true, + "sqlAuthenticationUsername": "azadmin", + "aadAuthenticationOnly": false + } + }, + "sqlmi": { + "value": { + "enabled": false + } + }, + "aml": { + "value": { + "enableHbiWorkspace": false + } + }, + "hubNetwork": { + "value": { + "virtualNetworkId": "/subscriptions/4fd845de-f6c8-4e6d-9a87-c21c4ebf7edd/resourceGroups/pubsec-hub-networking/providers/Microsoft.Network/virtualNetworks/hub-vnet", + "rfc1918IPRange": "10.18.0.0/22", + "rfc6598IPRange": "100.60.0.0/16", + "egressVirtualApplianceIp": "10.18.1.4", + "privateDnsManagedByHub": true, + "privateDnsManagedByHubSubscriptionId": "4fd845de-f6c8-4e6d-9a87-c21c4ebf7edd", + "privateDnsManagedByHubResourceGroupName": "private-dns-rg" + } + }, + "network": { + "value": { + "peerToHubVirtualNetwork": true, + "useRemoteGateway": false, + "name": "azmlcmk-vnet", + "dnsServers": [ + "10.18.1.4" + ], + "addressPrefixes": [ + "10.1.0.0/16" + ], + "subnets": { + "sqlmi": { + "comments": "SQL Managed Instances Delegated Subnet", + "name": "sqlmi", + "addressPrefix": "10.1.5.0/25" + }, + "databricksPublic": { + "comments": "Databricks Public Delegated Subnet", + "name": "databrickspublic", + "addressPrefix": "10.1.6.0/25" + }, + "databricksPrivate": { + "comments": "Databricks Private Delegated Subnet", + "name": "databricksprivate", + "addressPrefix": "10.1.7.0/25" + }, + "privateEndpoints": { + "comments": "Private Endpoints Subnet", + "name": "privateendpoints", + "addressPrefix": "10.1.8.0/25" + }, + "aks": { + "comments": "AKS Subnet", + "name": "aks", + "addressPrefix": "10.1.9.0/25" + }, + "appService": { + "comments": "App Service Subnet", + "name": "appService", + "addressPrefix": "10.1.10.0/25" + }, + "optional": [] + } + } + } + } +} \ No newline at end of file diff --git a/config/subscriptions/CanadaPubSecALZ-main/DevTest/bbe30f1a-fda5-4873-b51b-c838cf3f1a61_machinelearning_canadacentral.json b/config/subscriptions/CanadaPubSecALZ-main/DevTest/bbe30f1a-fda5-4873-b51b-c838cf3f1a61_machinelearning_canadacentral.json new file mode 100644 index 00000000..e6c64226 --- /dev/null +++ b/config/subscriptions/CanadaPubSecALZ-main/DevTest/bbe30f1a-fda5-4873-b51b-c838cf3f1a61_machinelearning_canadacentral.json @@ -0,0 +1,207 @@ +{ + "$schema": "https://raw.githubusercontent.com/Azure/CanadaPubSecALZ/main/schemas/latest/landingzones/lz-machinelearning.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "serviceHealthAlerts": { + "value": { + "alertRuleName": "Subscription Owners Alerts", + "receivers": { + "app": [ + "subscription-owners@example.com" + ], + "sms": [ + { + "countryCode": "1", + "phoneNumber": "6135555555" + } + ], + "email": [ + "subscription-owners@example.com" + ], + "voice": [ + { + "countryCode": "1", + "phoneNumber": "6135555555" + } + ] + }, + "regions": [ + "Global", + "Canada Central", + "Canada East" + ], + "resourceGroupName": "service-health-alerts-rg", + "actionGroupName": "Subscription Owners Alerts", + "actionGroupShortName": "sub-own-ag", + "incidentTypes": [ + "Incident", + "Security" + ], + "alertRuleDescription": "Subscription Owners Alerts for Incidents and Security" + } + }, + "securityCenter": { + "value": { + "email": "security@example.com", + "phone": "6135555555" + } + }, + "subscriptionRoleAssignments": { + "value": [ + { + "comments": "Built-in Contributor Role", + "securityGroupObjectIds": [ + "49f9256a-d77a-43ba-8cc5-957eb40dedee" + ], + "roleDefinitionId": "b24988ac-6180-42a0-ab88-20f7382dd24c" + }, + { + "comments": "Custom Role: Landing Zone Application Owner", + "securityGroupObjectIds": [ + "43d97b7e-27b8-4fa7-a339-c935f7752bb9" + ], + "roleDefinitionId": "b4c87314-c1a1-5320-9c43-779585186bcc" + } + ] + }, + "subscriptionBudget": { + "value": { + "createBudget": false + } + }, + "subscriptionTags": { + "value": { + "ISSO": "isso-tag" + } + }, + "resourceTags": { + "value": { + "ClientOrganization": "client-organization-tag", + "CostCenter": "cost-center-tag", + "DataSensitivity": "data-sensitivity-tag", + "ProjectContact": "project-contact-tag", + "ProjectName": "project-name-tag", + "TechnicalContact": "technical-contact-tag" + } + }, + "resourceGroups": { + "value": { + "automation": "azmlcmksqlmi-automation", + "compute": "azmlcmksqlmi-compute", + "monitor": "azmlcmksqlmi-monitor", + "networking": "azmlcmksqlmi-networking", + "networkWatcher": "NetworkWatcherRG", + "security": "azmlcmksqlmi-security", + "storage": "azmlcmksqlmi-storage" + } + }, + "useCMK": { + "value": true + }, + "automation": { + "value": { + "name": "automation" + } + }, + "keyVault": { + "value": { + "secretExpiryInDays": 3650 + } + }, + "aks": { + "value": { + "version": "1.25.5", + "enabled": true, + "networkPlugin": "kubenet", + "networkPolicy": "calico", + "podCidr": "11.0.0.0/16", + "serviceCidr": "20.0.0.0/16", + "dnsServiceIP": "20.0.0.10", + "dockerBridgeCidr": "30.0.0.1/16" + } + }, + "appServiceLinuxContainer": { + "value": { + "enabled": true, + "skuName": "P1V2", + "skuTier": "Premium", + "enablePrivateEndpoint": true + } + }, + "sqldb": { + "value": { + "enabled": true, + "sqlAuthenticationUsername": "azadmin", + "aadAuthenticationOnly": false + } + }, + "sqlmi": { + "value": { + "enabled": true, + "username": "azadmin" + } + }, + "aml": { + "value": { + "enableHbiWorkspace": false + } + }, + "hubNetwork": { + "value": { + "virtualNetworkId": "/subscriptions/4fd845de-f6c8-4e6d-9a87-c21c4ebf7edd/resourceGroups/pubsec-hub-networking/providers/Microsoft.Network/virtualNetworks/hub-vnet", + "rfc1918IPRange": "10.18.0.0/22", + "rfc6598IPRange": "100.60.0.0/16", + "egressVirtualApplianceIp": "10.18.1.4", + "privateDnsManagedByHub": true, + "privateDnsManagedByHubSubscriptionId": "4fd845de-f6c8-4e6d-9a87-c21c4ebf7edd", + "privateDnsManagedByHubResourceGroupName": "private-dns-rg" + } + }, + "network": { + "value": { + "peerToHubVirtualNetwork": true, + "useRemoteGateway": false, + "name": "azmlcmksqlmi-vnet", + "dnsServers": [ + "10.18.1.4" + ], + "addressPrefixes": [ + "10.4.0.0/16" + ], + "subnets": { + "sqlmi": { + "comments": "SQL Managed Instances Delegated Subnet", + "name": "sqlmi", + "addressPrefix": "10.4.5.0/25" + }, + "databricksPublic": { + "comments": "Databricks Public Delegated Subnet", + "name": "databrickspublic", + "addressPrefix": "10.4.6.0/25" + }, + "databricksPrivate": { + "comments": "Databricks Private Delegated Subnet", + "name": "databricksprivate", + "addressPrefix": "10.4.7.0/25" + }, + "privateEndpoints": { + "comments": "Private Endpoints Subnet", + "name": "privateendpoints", + "addressPrefix": "10.4.8.0/25" + }, + "aks": { + "comments": "AKS Subnet", + "name": "aks", + "addressPrefix": "10.4.9.0/25" + }, + "appService": { + "comments": "App Service Subnet", + "name": "appService", + "addressPrefix": "10.4.10.0/25" + }, + "optional": [] + } + } + } + } +} diff --git a/config/subscriptions/CanadaESLZ-main/pubsec/LandingZones/DevTest/8c6e48a4-4c73-4a1f-9f95-9447804f2c98_machinelearning_canadacentral.json b/config/subscriptions/CanadaPubSecALZ-main/DevTest/f881fccb-2598-4b9c-b87c-b392f5e16f12_machinelearning_canadacentral.json similarity index 72% rename from config/subscriptions/CanadaESLZ-main/pubsec/LandingZones/DevTest/8c6e48a4-4c73-4a1f-9f95-9447804f2c98_machinelearning_canadacentral.json rename to config/subscriptions/CanadaPubSecALZ-main/DevTest/f881fccb-2598-4b9c-b87c-b392f5e16f12_machinelearning_canadacentral.json index d86daddb..3be3347c 100644 --- a/config/subscriptions/CanadaESLZ-main/pubsec/LandingZones/DevTest/8c6e48a4-4c73-4a1f-9f95-9447804f2c98_machinelearning_canadacentral.json +++ b/config/subscriptions/CanadaPubSecALZ-main/DevTest/f881fccb-2598-4b9c-b87c-b392f5e16f12_machinelearning_canadacentral.json @@ -1,38 +1,66 @@ { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "$schema": "https://raw.githubusercontent.com/Azure/CanadaPubSecALZ/main/schemas/latest/landingzones/lz-machinelearning.json#", "contentVersion": "1.0.0.0", "parameters": { "serviceHealthAlerts": { "value": { - "resourceGroupName": "service-health", - "incidentTypes": [ "Incident", "Security" ], - "regions": [ "Global", "Canada East", "Canada Central" ], - "receivers": { - "app": [ "alzcanadapubsec@microsoft.com" ], - "email": [ "alzcanadapubsec@microsoft.com" ], - "sms": [ { "countryCode": "1", "phoneNumber": "6045555555" } ], - "voice": [ { "countryCode": "1", "phoneNumber": "6045555555" } ] - }, - "actionGroupName": "Service health action group", - "actionGroupShortName": "health-alert", - "alertRuleName": "Incidents and Security", - "alertRuleDescription": "Service Health: Incidents and Security" + "alertRuleName": "Subscription Owners Alerts", + "receivers": { + "app": [ + "subscription-owners@example.com" + ], + "sms": [ + { + "countryCode": "1", + "phoneNumber": "6135555555" + } + ], + "email": [ + "subscription-owners@example.com" + ], + "voice": [ + { + "countryCode": "1", + "phoneNumber": "6135555555" + } + ] + }, + "regions": [ + "Global", + "Canada Central", + "Canada East" + ], + "resourceGroupName": "service-health-alerts-rg", + "actionGroupName": "Subscription Owners Alerts", + "actionGroupShortName": "sub-own-ag", + "incidentTypes": [ + "Incident", + "Security" + ], + "alertRuleDescription": "Subscription Owners Alerts for Incidents and Security" } }, "securityCenter": { "value": { - "email": "alzcanadapubsec@microsoft.com", - "phone": "6045555555" + "email": "security@example.com", + "phone": "6135555555" } }, "subscriptionRoleAssignments": { "value": [ { - "comments": "Built-in Role: Contributor", - "roleDefinitionId": "b24988ac-6180-42a0-ab88-20f7382dd24c", + "comments": "Built-in Contributor Role", "securityGroupObjectIds": [ - "38f33f7e-a471-4630-8ce9-c6653495a2ee" - ] + "49f9256a-d77a-43ba-8cc5-957eb40dedee" + ], + "roleDefinitionId": "b24988ac-6180-42a0-ab88-20f7382dd24c" + }, + { + "comments": "Custom Role: Landing Zone Application Owner", + "securityGroupObjectIds": [ + "43d97b7e-27b8-4fa7-a339-c935f7752bb9" + ], + "roleDefinitionId": "b4c87314-c1a1-5320-9c43-779585186bcc" } ] }, @@ -122,13 +150,13 @@ }, "hubNetwork": { "value": { - "virtualNetworkId": "/subscriptions/ed7f4eed-9010-4227-b115-2a5e37728f27/resourceGroups/pubsec-hub-networking/providers/Microsoft.Network/virtualNetworks/hub-vnet", + "virtualNetworkId": "/subscriptions/4fd845de-f6c8-4e6d-9a87-c21c4ebf7edd/resourceGroups/pubsec-hub-networking/providers/Microsoft.Network/virtualNetworks/hub-vnet", "rfc1918IPRange": "10.18.0.0/22", "rfc6598IPRange": "100.60.0.0/16", "egressVirtualApplianceIp": "10.18.1.4", "privateDnsManagedByHub": true, - "privateDnsManagedByHubSubscriptionId": "ed7f4eed-9010-4227-b115-2a5e37728f27", - "privateDnsManagedByHubResourceGroupName": "pubsec-dns" + "privateDnsManagedByHubSubscriptionId": "4fd845de-f6c8-4e6d-9a87-c21c4ebf7edd", + "privateDnsManagedByHubResourceGroupName": "private-dns-rg" } }, "network": { @@ -204,4 +232,4 @@ } } } -} \ No newline at end of file +} diff --git a/config/subscriptions/cdssnc-main/DevTest/0a5970ed-b9d5-464a-acef-8a06f0d7a360_machinelearning_canadacentral.json b/config/subscriptions/cdssnc-main/DevTest/0a5970ed-b9d5-464a-acef-8a06f0d7a360_machinelearning_canadacentral.json new file mode 100644 index 00000000..ad33c1ca --- /dev/null +++ b/config/subscriptions/cdssnc-main/DevTest/0a5970ed-b9d5-464a-acef-8a06f0d7a360_machinelearning_canadacentral.json @@ -0,0 +1,206 @@ +{ + "$schema": "https://raw.githubusercontent.com/Azure/CanadaPubSecALZ/main/schemas/latest/landingzones/lz-machinelearning.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "serviceHealthAlerts": { + "value": { + "alertRuleName": "Subscription Owners Alerts", + "receivers": { + "app": [ + "subscription-owners@example.com" + ], + "sms": [ + { + "countryCode": "1", + "phoneNumber": "6135555555" + } + ], + "email": [ + "subscription-owners@example.com" + ], + "voice": [ + { + "countryCode": "1", + "phoneNumber": "6135555555" + } + ] + }, + "regions": [ + "Global", + "Canada Central", + "Canada East" + ], + "resourceGroupName": "service-health-alerts-rg", + "actionGroupName": "Subscription Owners Alerts", + "actionGroupShortName": "sub-own-ag", + "incidentTypes": [ + "Incident", + "Security" + ], + "alertRuleDescription": "Subscription Owners Alerts for Incidents and Security" + } + }, + "securityCenter": { + "value": { + "email": "security@example.com", + "phone": "6135555555" + } + }, + "subscriptionRoleAssignments": { + "value": [ + { + "comments": "Built-in Contributor Role", + "securityGroupObjectIds": [ + "49f9256a-d77a-43ba-8cc5-957eb40dedee" + ], + "roleDefinitionId": "b24988ac-6180-42a0-ab88-20f7382dd24c" + }, + { + "comments": "Custom Role: Landing Zone Application Owner", + "securityGroupObjectIds": [ + "43d97b7e-27b8-4fa7-a339-c935f7752bb9" + ], + "roleDefinitionId": "b4c87314-c1a1-5320-9c43-779585186bcc" + } + ] + }, + "subscriptionBudget": { + "value": { + "createBudget": false + } + }, + "subscriptionTags": { + "value": { + "ISSO": "isso-tag" + } + }, + "resourceTags": { + "value": { + "ClientOrganization": "client-organization-tag", + "CostCenter": "cost-center-tag", + "DataSensitivity": "data-sensitivity-tag", + "ProjectContact": "project-contact-tag", + "ProjectName": "project-name-tag", + "TechnicalContact": "technical-contact-tag" + } + }, + "resourceGroups": { + "value": { + "automation": "azmlnocmk-automation", + "compute": "azmlnocmk-compute", + "monitor": "azmlnocmk-monitor", + "networking": "azmlnocmk-networking", + "networkWatcher": "NetworkWatcherRG", + "security": "azmlnocmk-security", + "storage": "azmlnocmk-storage" + } + }, + "useCMK": { + "value": false + }, + "automation": { + "value": { + "name": "automation" + } + }, + "keyVault": { + "value": { + "secretExpiryInDays": 3650 + } + }, + "aks": { + "value": { + "version": "1.25.5", + "enabled": true, + "networkPlugin": "kubenet", + "networkPolicy": "calico", + "podCidr": "11.0.0.0/16", + "serviceCidr": "20.0.0.0/16", + "dnsServiceIP": "20.0.0.10", + "dockerBridgeCidr": "30.0.0.1/16" + } + }, + "appServiceLinuxContainer": { + "value": { + "enabled": true, + "skuName": "P1V2", + "skuTier": "Premium", + "enablePrivateEndpoint": true + } + }, + "sqldb": { + "value": { + "enabled": true, + "sqlAuthenticationUsername": "azadmin", + "aadAuthenticationOnly": false + } + }, + "sqlmi": { + "value": { + "enabled": false + } + }, + "aml": { + "value": { + "enableHbiWorkspace": false + } + }, + "hubNetwork": { + "value": { + "virtualNetworkId": "/subscriptions/4fd845de-f6c8-4e6d-9a87-c21c4ebf7edd/resourceGroups/pubsec-hub-networking/providers/Microsoft.Network/virtualNetworks/hub-vnet", + "rfc1918IPRange": "10.18.0.0/22", + "rfc6598IPRange": "100.60.0.0/16", + "egressVirtualApplianceIp": "10.18.1.4", + "privateDnsManagedByHub": true, + "privateDnsManagedByHubSubscriptionId": "4fd845de-f6c8-4e6d-9a87-c21c4ebf7edd", + "privateDnsManagedByHubResourceGroupName": "private-dns-rg" + } + }, + "network": { + "value": { + "peerToHubVirtualNetwork": true, + "useRemoteGateway": false, + "name": "azmlnocmk-vnet", + "dnsServers": [ + "10.18.1.4" + ], + "addressPrefixes": [ + "10.3.0.0/16" + ], + "subnets": { + "sqlmi": { + "comments": "SQL Managed Instances Delegated Subnet", + "name": "sqlmi", + "addressPrefix": "10.3.5.0/25" + }, + "databricksPublic": { + "comments": "Databricks Public Delegated Subnet", + "name": "databrickspublic", + "addressPrefix": "10.3.6.0/25" + }, + "databricksPrivate": { + "comments": "Databricks Private Delegated Subnet", + "name": "databricksprivate", + "addressPrefix": "10.3.7.0/25" + }, + "privateEndpoints": { + "comments": "Private Endpoints Subnet", + "name": "privateendpoints", + "addressPrefix": "10.3.8.0/25" + }, + "aks": { + "comments": "AKS Subnet", + "name": "aks", + "addressPrefix": "10.3.9.0/25" + }, + "appService": { + "comments": "App Service Subnet", + "name": "appService", + "addressPrefix": "10.3.10.0/25" + }, + "optional": [] + } + } + } + } +} diff --git a/config/subscriptions/cdssnc-main/DevTest/1f519216-5e39-4b51-a9b6-10cc2b79b6c7_healthcare_canadacentral.json b/config/subscriptions/cdssnc-main/DevTest/1f519216-5e39-4b51-a9b6-10cc2b79b6c7_healthcare_canadacentral.json new file mode 100644 index 00000000..33ad6983 --- /dev/null +++ b/config/subscriptions/cdssnc-main/DevTest/1f519216-5e39-4b51-a9b6-10cc2b79b6c7_healthcare_canadacentral.json @@ -0,0 +1,200 @@ +{ + "$schema": "https://raw.githubusercontent.com/Azure/CanadaPubSecALZ/main/schemas/latest/landingzones/lz-healthcare.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "serviceHealthAlerts": { + "value": { + "alertRuleName": "Subscription Owners Alerts", + "receivers": { + "app": [ + "subscription-owners@example.com" + ], + "sms": [ + { + "countryCode": "1", + "phoneNumber": "6135555555" + } + ], + "email": [ + "subscription-owners@example.com" + ], + "voice": [ + { + "countryCode": "1", + "phoneNumber": "6135555555" + } + ] + }, + "regions": [ + "Global", + "Canada Central", + "Canada East" + ], + "resourceGroupName": "service-health-alerts-rg", + "actionGroupName": "Subscription Owners Alerts", + "actionGroupShortName": "sub-own-ag", + "incidentTypes": [ + "Incident", + "Security" + ], + "alertRuleDescription": "Subscription Owners Alerts for Incidents and Security" + } + }, + "securityCenter": { + "value": { + "email": "security@example.com", + "phone": "6135555555" + } + }, + "subscriptionRoleAssignments": { + "value": [ + { + "comments": "Built-in Contributor Role", + "securityGroupObjectIds": [ + "49f9256a-d77a-43ba-8cc5-957eb40dedee" + ], + "roleDefinitionId": "b24988ac-6180-42a0-ab88-20f7382dd24c" + }, + { + "comments": "Custom Role: Landing Zone Application Owner", + "securityGroupObjectIds": [ + "43d97b7e-27b8-4fa7-a339-c935f7752bb9" + ], + "roleDefinitionId": "b4c87314-c1a1-5320-9c43-779585186bcc" + } + ] + }, + "subscriptionBudget": { + "value": { + "createBudget": false + } + }, + "subscriptionTags": { + "value": { + "ISSO": "isso-tag" + } + }, + "resourceTags": { + "value": { + "ClientOrganization": "client-organization-tag", + "CostCenter": "cost-center-tag", + "DataSensitivity": "data-sensitivity-tag", + "ProjectContact": "project-contact-tag", + "ProjectName": "project-name-tag", + "TechnicalContact": "technical-contact-tag" + } + }, + "resourceGroups": { + "value": { + "automation": "health-automation", + "compute": "health-compute", + "monitor": "health-monitor", + "networking": "health-network", + "networkWatcher": "NetworkWatcherRG", + "security": "health-security", + "storage": "health-storage" + } + }, + "useCMK": { + "value": true + }, + "keyVault": { + "value": { + "secretExpiryInDays": 3650 + } + }, + "automation": { + "value": { + "name": "automation" + } + }, + "sqldb": { + "value": { + "enabled": true, + "sqlAuthenticationUsername": "azadmin", + "aadAuthenticationOnly": false + } + }, + "synapse": { + "value": { + "aadAuthenticationOnly": true, + "aadLoginName": "az.admins", + "aadLoginObjectID": "e0357d81-55d8-44e9-9d9c-ab09dc710785", + "aadLoginType": "Group" + } + }, + "hubNetwork": { + "value": { + "virtualNetworkId": "/subscriptions/4fd845de-f6c8-4e6d-9a87-c21c4ebf7edd/resourceGroups/pubsec-hub-networking/providers/Microsoft.Network/virtualNetworks/hub-vnet", + "rfc1918IPRange": "10.18.0.0/22", + "rfc6598IPRange": "100.60.0.0/16", + "egressVirtualApplianceIp": "10.18.1.4", + "privateDnsManagedByHub": true, + "privateDnsManagedByHubSubscriptionId": "4fd845de-f6c8-4e6d-9a87-c21c4ebf7edd", + "privateDnsManagedByHubResourceGroupName": "private-dns-rg" + } + }, + "network": { + "value": { + "peerToHubVirtualNetwork": true, + "useRemoteGateway": false, + "name": "health-vnet", + "dnsServers": [ + "10.18.1.4" + ], + "addressPrefixes": [ + "10.5.0.0/16" + ], + "subnets": { + "databricksPublic": { + "comments": "Databricks Public Delegated Subnet", + "name": "databrickspublic", + "addressPrefix": "10.5.5.0/25" + }, + "databricksPrivate": { + "comments": "Databricks Private Delegated Subnet", + "name": "databricksprivate", + "addressPrefix": "10.5.6.0/25" + }, + "privateEndpoints": { + "comments": "Private Endpoints Subnet", + "name": "privateendpoints", + "addressPrefix": "10.5.7.0/25" + }, + "web": { + "comments": "Azure Web App Delegated Subnet", + "name": "webapp", + "addressPrefix": "10.5.8.0/25" + }, + "optional": [ + { + "comments": "Optional Subnet 1", + "name": "virtualMachines", + "addressPrefix": "10.5.9.0/25", + "nsg": { + "enabled": true + }, + "udr": { + "enabled": true + } + }, + { + "comments": "Optional Subnet 2 with delegation for NetApp Volumes", + "name": "NetappVolumes", + "addressPrefix": "10.5.10.0/25", + "nsg": { + "enabled": false + }, + "udr": { + "enabled": false + }, + "delegations": { + "serviceName": "Microsoft.NetApp/volumes" + } + } + ] + } + } + } + } +} diff --git a/config/subscriptions/cdssnc-main/DevTest/8422552f-3840-4934-a971-6ee349ffbb05_generic-subscription_canadacentral.json b/config/subscriptions/cdssnc-main/DevTest/8422552f-3840-4934-a971-6ee349ffbb05_generic-subscription_canadacentral.json new file mode 100644 index 00000000..f7cd93c6 --- /dev/null +++ b/config/subscriptions/cdssnc-main/DevTest/8422552f-3840-4934-a971-6ee349ffbb05_generic-subscription_canadacentral.json @@ -0,0 +1,192 @@ +{ + "$schema": "https://raw.githubusercontent.com/Azure/CanadaPubSecALZ/main/schemas/latest/landingzones/lz-generic-subscription.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "location": { + "value": "canadacentral" + }, + "serviceHealthAlerts": { + "value": { + "alertRuleName": "Subscription Owners Alerts", + "receivers": { + "app": [ + "subscription-owners@example.com" + ], + "sms": [ + { + "countryCode": "1", + "phoneNumber": "6135555555" + } + ], + "email": [ + "subscription-owners@example.com" + ], + "voice": [ + { + "countryCode": "1", + "phoneNumber": "6135555555" + } + ] + }, + "regions": [ + "Global", + "Canada Central", + "Canada East" + ], + "resourceGroupName": "service-health-alerts-rg", + "actionGroupName": "Subscription Owners Alerts", + "actionGroupShortName": "sub-own-ag", + "incidentTypes": [ + "Incident", + "Security" + ], + "alertRuleDescription": "Subscription Owners Alerts for Incidents and Security" + } + }, + "securityCenter": { + "value": { + "email": "security@example.com", + "phone": "6135555555" + } + }, + "subscriptionRoleAssignments": { + "value": [ + { + "comments": "Built-in Contributor Role", + "securityGroupObjectIds": [ + "49f9256a-d77a-43ba-8cc5-957eb40dedee" + ], + "roleDefinitionId": "b24988ac-6180-42a0-ab88-20f7382dd24c" + }, + { + "comments": "Custom Role: Landing Zone Application Owner", + "securityGroupObjectIds": [ + "43d97b7e-27b8-4fa7-a339-c935f7752bb9" + ], + "roleDefinitionId": "b4c87314-c1a1-5320-9c43-779585186bcc" + } + ] + }, + "subscriptionBudget": { + "value": { + "createBudget": false + } + }, + "subscriptionTags": { + "value": { + "ISSO": "isso-tag" + } + }, + "resourceTags": { + "value": { + "ClientOrganization": "client-organization-tag", + "CostCenter": "cost-center-tag", + "DataSensitivity": "data-sensitivity-tag", + "ProjectContact": "project-contact-tag", + "ProjectName": "project-name-tag", + "TechnicalContact": "technical-contact-tag" + } + }, + "resourceGroups": { + "value": { + "automation": "automation", + "networking": "networking", + "networkWatcher": "NetworkWatcherRG", + "backupRecoveryVault": "backup" + } + }, + "automation": { + "value": { + "name": "automation" + } + }, + "backupRecoveryVault": { + "value": { + "enabled": true, + "name": "backup-vault" + } + }, + "hubNetwork": { + "value": { + "virtualNetworkId": "/subscriptions/4fd845de-f6c8-4e6d-9a87-c21c4ebf7edd/resourceGroups/pubsec-hub-networking/providers/Microsoft.Network/virtualNetworks/hub-vnet", + "rfc1918IPRange": "10.18.0.0/22", + "rfc6598IPRange": "100.60.0.0/16", + "egressVirtualApplianceIp": "10.18.1.4" + } + }, + "network": { + "value": { + "deployVnet": true, + "peerToHubVirtualNetwork": true, + "useRemoteGateway": false, + "name": "vnet", + "dnsServers": [ + "10.18.1.4" + ], + "addressPrefixes": [ + "10.2.0.0/16" + ], + "subnets": [ + { + "comments": "App Management Zone (OZ)", + "name": "appManagement", + "addressPrefix": "10.2.1.0/25", + "nsg": { + "enabled": true + }, + "udr": { + "enabled": true + } + }, + { + "comments": "Presentation Zone (PAZ)", + "name": "web", + "addressPrefix": "10.2.2.0/25", + "nsg": { + "enabled": true + }, + "udr": { + "enabled": true + } + }, + { + "comments": "Application Zone (RZ)", + "name": "app", + "addressPrefix": "10.2.3.0/25", + "nsg": { + "enabled": true + }, + "udr": { + "enabled": true + } + }, + { + "comments": "Data Zone (HRZ)", + "name": "data", + "addressPrefix": "10.2.4.0/25", + "nsg": { + "enabled": true + }, + "udr": { + "enabled": true + } + }, + { + "comments": "App Service", + "name": "appservice", + "addressPrefix": "10.2.5.0/25", + "nsg": { + "enabled": false + }, + "udr": { + "enabled": false + }, + "delegations": { + "serviceName": "Microsoft.Web/serverFarms" + } + } + ] + } + } + } +} diff --git a/config/subscriptions/cdssnc-main/DevTest/9d9817f5-c218-4553-b686-58be8d9ea82c_machinelearning_canadacentral.json b/config/subscriptions/cdssnc-main/DevTest/9d9817f5-c218-4553-b686-58be8d9ea82c_machinelearning_canadacentral.json new file mode 100644 index 00000000..e13ce6b6 --- /dev/null +++ b/config/subscriptions/cdssnc-main/DevTest/9d9817f5-c218-4553-b686-58be8d9ea82c_machinelearning_canadacentral.json @@ -0,0 +1,206 @@ +{ + "$schema": "https://raw.githubusercontent.com/Azure/CanadaPubSecALZ/main/schemas/latest/landingzones/lz-machinelearning.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "serviceHealthAlerts": { + "value": { + "alertRuleName": "Subscription Owners Alerts", + "receivers": { + "app": [ + "subscription-owners@example.com" + ], + "sms": [ + { + "countryCode": "1", + "phoneNumber": "6135555555" + } + ], + "email": [ + "subscription-owners@example.com" + ], + "voice": [ + { + "countryCode": "1", + "phoneNumber": "6135555555" + } + ] + }, + "regions": [ + "Global", + "Canada Central", + "Canada East" + ], + "resourceGroupName": "service-health-alerts-rg", + "actionGroupName": "Subscription Owners Alerts", + "actionGroupShortName": "sub-own-ag", + "incidentTypes": [ + "Incident", + "Security" + ], + "alertRuleDescription": "Subscription Owners Alerts for Incidents and Security" + } + }, + "securityCenter": { + "value": { + "email": "security@example.com", + "phone": "6135555555" + } + }, + "subscriptionRoleAssignments": { + "value": [ + { + "comments": "Built-in Contributor Role", + "securityGroupObjectIds": [ + "49f9256a-d77a-43ba-8cc5-957eb40dedee" + ], + "roleDefinitionId": "b24988ac-6180-42a0-ab88-20f7382dd24c" + }, + { + "comments": "Custom Role: Landing Zone Application Owner", + "securityGroupObjectIds": [ + "43d97b7e-27b8-4fa7-a339-c935f7752bb9" + ], + "roleDefinitionId": "b4c87314-c1a1-5320-9c43-779585186bcc" + } + ] + }, + "subscriptionBudget": { + "value": { + "createBudget": false + } + }, + "subscriptionTags": { + "value": { + "ISSO": "isso-tag" + } + }, + "resourceTags": { + "value": { + "ClientOrganization": "client-organization-tag", + "CostCenter": "cost-center-tag", + "DataSensitivity": "data-sensitivity-tag", + "ProjectContact": "project-contact-tag", + "ProjectName": "project-name-tag", + "TechnicalContact": "technical-contact-tag" + } + }, + "resourceGroups": { + "value": { + "automation": "azmlcmk-automation", + "compute": "azmlcmk-compute", + "monitor": "azmlcmk-monitor", + "networking": "azmlcmk-networking", + "networkWatcher": "NetworkWatcherRG", + "security": "azmlcmk-security", + "storage": "azmlcmk-storage" + } + }, + "useCMK": { + "value": true + }, + "automation": { + "value": { + "name": "automation" + } + }, + "keyVault": { + "value": { + "secretExpiryInDays": 3650 + } + }, + "aks": { + "value": { + "version": "1.25.5", + "enabled": true, + "networkPlugin": "kubenet", + "networkPolicy": "calico", + "podCidr": "11.0.0.0/16", + "serviceCidr": "20.0.0.0/16", + "dnsServiceIP": "20.0.0.10", + "dockerBridgeCidr": "30.0.0.1/16" + } + }, + "appServiceLinuxContainer": { + "value": { + "enabled": true, + "skuName": "P1V2", + "skuTier": "Premium", + "enablePrivateEndpoint": true + } + }, + "sqldb": { + "value": { + "enabled": true, + "sqlAuthenticationUsername": "azadmin", + "aadAuthenticationOnly": false + } + }, + "sqlmi": { + "value": { + "enabled": false + } + }, + "aml": { + "value": { + "enableHbiWorkspace": false + } + }, + "hubNetwork": { + "value": { + "virtualNetworkId": "/subscriptions/4fd845de-f6c8-4e6d-9a87-c21c4ebf7edd/resourceGroups/pubsec-hub-networking/providers/Microsoft.Network/virtualNetworks/hub-vnet", + "rfc1918IPRange": "10.18.0.0/22", + "rfc6598IPRange": "100.60.0.0/16", + "egressVirtualApplianceIp": "10.18.1.4", + "privateDnsManagedByHub": true, + "privateDnsManagedByHubSubscriptionId": "4fd845de-f6c8-4e6d-9a87-c21c4ebf7edd", + "privateDnsManagedByHubResourceGroupName": "private-dns-rg" + } + }, + "network": { + "value": { + "peerToHubVirtualNetwork": true, + "useRemoteGateway": false, + "name": "azmlcmk-vnet", + "dnsServers": [ + "10.18.1.4" + ], + "addressPrefixes": [ + "10.1.0.0/16" + ], + "subnets": { + "sqlmi": { + "comments": "SQL Managed Instances Delegated Subnet", + "name": "sqlmi", + "addressPrefix": "10.1.5.0/25" + }, + "databricksPublic": { + "comments": "Databricks Public Delegated Subnet", + "name": "databrickspublic", + "addressPrefix": "10.1.6.0/25" + }, + "databricksPrivate": { + "comments": "Databricks Private Delegated Subnet", + "name": "databricksprivate", + "addressPrefix": "10.1.7.0/25" + }, + "privateEndpoints": { + "comments": "Private Endpoints Subnet", + "name": "privateendpoints", + "addressPrefix": "10.1.8.0/25" + }, + "aks": { + "comments": "AKS Subnet", + "name": "aks", + "addressPrefix": "10.1.9.0/25" + }, + "appService": { + "comments": "App Service Subnet", + "name": "appService", + "addressPrefix": "10.1.10.0/25" + }, + "optional": [] + } + } + } + } +} \ No newline at end of file diff --git a/config/subscriptions/cdssnc-main/DevTest/bbe30f1a-fda5-4873-b51b-c838cf3f1a61_machinelearning_canadacentral.json b/config/subscriptions/cdssnc-main/DevTest/bbe30f1a-fda5-4873-b51b-c838cf3f1a61_machinelearning_canadacentral.json new file mode 100644 index 00000000..e6c64226 --- /dev/null +++ b/config/subscriptions/cdssnc-main/DevTest/bbe30f1a-fda5-4873-b51b-c838cf3f1a61_machinelearning_canadacentral.json @@ -0,0 +1,207 @@ +{ + "$schema": "https://raw.githubusercontent.com/Azure/CanadaPubSecALZ/main/schemas/latest/landingzones/lz-machinelearning.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "serviceHealthAlerts": { + "value": { + "alertRuleName": "Subscription Owners Alerts", + "receivers": { + "app": [ + "subscription-owners@example.com" + ], + "sms": [ + { + "countryCode": "1", + "phoneNumber": "6135555555" + } + ], + "email": [ + "subscription-owners@example.com" + ], + "voice": [ + { + "countryCode": "1", + "phoneNumber": "6135555555" + } + ] + }, + "regions": [ + "Global", + "Canada Central", + "Canada East" + ], + "resourceGroupName": "service-health-alerts-rg", + "actionGroupName": "Subscription Owners Alerts", + "actionGroupShortName": "sub-own-ag", + "incidentTypes": [ + "Incident", + "Security" + ], + "alertRuleDescription": "Subscription Owners Alerts for Incidents and Security" + } + }, + "securityCenter": { + "value": { + "email": "security@example.com", + "phone": "6135555555" + } + }, + "subscriptionRoleAssignments": { + "value": [ + { + "comments": "Built-in Contributor Role", + "securityGroupObjectIds": [ + "49f9256a-d77a-43ba-8cc5-957eb40dedee" + ], + "roleDefinitionId": "b24988ac-6180-42a0-ab88-20f7382dd24c" + }, + { + "comments": "Custom Role: Landing Zone Application Owner", + "securityGroupObjectIds": [ + "43d97b7e-27b8-4fa7-a339-c935f7752bb9" + ], + "roleDefinitionId": "b4c87314-c1a1-5320-9c43-779585186bcc" + } + ] + }, + "subscriptionBudget": { + "value": { + "createBudget": false + } + }, + "subscriptionTags": { + "value": { + "ISSO": "isso-tag" + } + }, + "resourceTags": { + "value": { + "ClientOrganization": "client-organization-tag", + "CostCenter": "cost-center-tag", + "DataSensitivity": "data-sensitivity-tag", + "ProjectContact": "project-contact-tag", + "ProjectName": "project-name-tag", + "TechnicalContact": "technical-contact-tag" + } + }, + "resourceGroups": { + "value": { + "automation": "azmlcmksqlmi-automation", + "compute": "azmlcmksqlmi-compute", + "monitor": "azmlcmksqlmi-monitor", + "networking": "azmlcmksqlmi-networking", + "networkWatcher": "NetworkWatcherRG", + "security": "azmlcmksqlmi-security", + "storage": "azmlcmksqlmi-storage" + } + }, + "useCMK": { + "value": true + }, + "automation": { + "value": { + "name": "automation" + } + }, + "keyVault": { + "value": { + "secretExpiryInDays": 3650 + } + }, + "aks": { + "value": { + "version": "1.25.5", + "enabled": true, + "networkPlugin": "kubenet", + "networkPolicy": "calico", + "podCidr": "11.0.0.0/16", + "serviceCidr": "20.0.0.0/16", + "dnsServiceIP": "20.0.0.10", + "dockerBridgeCidr": "30.0.0.1/16" + } + }, + "appServiceLinuxContainer": { + "value": { + "enabled": true, + "skuName": "P1V2", + "skuTier": "Premium", + "enablePrivateEndpoint": true + } + }, + "sqldb": { + "value": { + "enabled": true, + "sqlAuthenticationUsername": "azadmin", + "aadAuthenticationOnly": false + } + }, + "sqlmi": { + "value": { + "enabled": true, + "username": "azadmin" + } + }, + "aml": { + "value": { + "enableHbiWorkspace": false + } + }, + "hubNetwork": { + "value": { + "virtualNetworkId": "/subscriptions/4fd845de-f6c8-4e6d-9a87-c21c4ebf7edd/resourceGroups/pubsec-hub-networking/providers/Microsoft.Network/virtualNetworks/hub-vnet", + "rfc1918IPRange": "10.18.0.0/22", + "rfc6598IPRange": "100.60.0.0/16", + "egressVirtualApplianceIp": "10.18.1.4", + "privateDnsManagedByHub": true, + "privateDnsManagedByHubSubscriptionId": "4fd845de-f6c8-4e6d-9a87-c21c4ebf7edd", + "privateDnsManagedByHubResourceGroupName": "private-dns-rg" + } + }, + "network": { + "value": { + "peerToHubVirtualNetwork": true, + "useRemoteGateway": false, + "name": "azmlcmksqlmi-vnet", + "dnsServers": [ + "10.18.1.4" + ], + "addressPrefixes": [ + "10.4.0.0/16" + ], + "subnets": { + "sqlmi": { + "comments": "SQL Managed Instances Delegated Subnet", + "name": "sqlmi", + "addressPrefix": "10.4.5.0/25" + }, + "databricksPublic": { + "comments": "Databricks Public Delegated Subnet", + "name": "databrickspublic", + "addressPrefix": "10.4.6.0/25" + }, + "databricksPrivate": { + "comments": "Databricks Private Delegated Subnet", + "name": "databricksprivate", + "addressPrefix": "10.4.7.0/25" + }, + "privateEndpoints": { + "comments": "Private Endpoints Subnet", + "name": "privateendpoints", + "addressPrefix": "10.4.8.0/25" + }, + "aks": { + "comments": "AKS Subnet", + "name": "aks", + "addressPrefix": "10.4.9.0/25" + }, + "appService": { + "comments": "App Service Subnet", + "name": "appService", + "addressPrefix": "10.4.10.0/25" + }, + "optional": [] + } + } + } + } +} diff --git a/config/subscriptions/cdssnc-main/DevTest/f881fccb-2598-4b9c-b87c-b392f5e16f12_machinelearning_canadacentral.json b/config/subscriptions/cdssnc-main/DevTest/f881fccb-2598-4b9c-b87c-b392f5e16f12_machinelearning_canadacentral.json new file mode 100644 index 00000000..3be3347c --- /dev/null +++ b/config/subscriptions/cdssnc-main/DevTest/f881fccb-2598-4b9c-b87c-b392f5e16f12_machinelearning_canadacentral.json @@ -0,0 +1,235 @@ +{ + "$schema": "https://raw.githubusercontent.com/Azure/CanadaPubSecALZ/main/schemas/latest/landingzones/lz-machinelearning.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "serviceHealthAlerts": { + "value": { + "alertRuleName": "Subscription Owners Alerts", + "receivers": { + "app": [ + "subscription-owners@example.com" + ], + "sms": [ + { + "countryCode": "1", + "phoneNumber": "6135555555" + } + ], + "email": [ + "subscription-owners@example.com" + ], + "voice": [ + { + "countryCode": "1", + "phoneNumber": "6135555555" + } + ] + }, + "regions": [ + "Global", + "Canada Central", + "Canada East" + ], + "resourceGroupName": "service-health-alerts-rg", + "actionGroupName": "Subscription Owners Alerts", + "actionGroupShortName": "sub-own-ag", + "incidentTypes": [ + "Incident", + "Security" + ], + "alertRuleDescription": "Subscription Owners Alerts for Incidents and Security" + } + }, + "securityCenter": { + "value": { + "email": "security@example.com", + "phone": "6135555555" + } + }, + "subscriptionRoleAssignments": { + "value": [ + { + "comments": "Built-in Contributor Role", + "securityGroupObjectIds": [ + "49f9256a-d77a-43ba-8cc5-957eb40dedee" + ], + "roleDefinitionId": "b24988ac-6180-42a0-ab88-20f7382dd24c" + }, + { + "comments": "Custom Role: Landing Zone Application Owner", + "securityGroupObjectIds": [ + "43d97b7e-27b8-4fa7-a339-c935f7752bb9" + ], + "roleDefinitionId": "b4c87314-c1a1-5320-9c43-779585186bcc" + } + ] + }, + "subscriptionBudget": { + "value": { + "createBudget": false + } + }, + "subscriptionTags": { + "value": { + "ISSO": "isso-tag" + } + }, + "resourceTags": { + "value": { + "ClientOrganization": "client-organization-tag", + "CostCenter": "cost-center-tag", + "DataSensitivity": "data-sensitivity-tag", + "ProjectContact": "project-contact-tag", + "ProjectName": "project-name-tag", + "TechnicalContact": "technical-contact-tag" + } + }, + "resourceGroups": { + "value": { + "automation": "azmlsqlauth-automation", + "compute": "azmlsqlauth-compute", + "monitor": "azmlsqlauth-monitor", + "networking": "azmlsqlauth-networking", + "networkWatcher": "NetworkWatcherRG", + "security": "azmlsqlauth-security", + "storage": "azmlsqlauth-storage" + } + }, + "useCMK": { + "value": false + }, + "automation": { + "value": { + "name": "automation" + } + }, + "keyVault": { + "value": { + "secretExpiryInDays": 3650 + } + }, + "aks": { + "value": { + "version": "1.25.5", + "enabled": true, + "networkPlugin": "kubenet", + "networkPolicy": "calico", + "podCidr": "11.0.0.0/16", + "serviceCidr": "20.0.0.0/16", + "dnsServiceIP": "20.0.0.10", + "dockerBridgeCidr": "30.0.0.1/16" + } + }, + "appServiceLinuxContainer": { + "value": { + "enabled": true, + "skuName": "P1V2", + "skuTier": "Premium", + "enablePrivateEndpoint": true + } + }, + "sqldb": { + "value": { + "enabled": true, + "sqlAuthenticationUsername": "azadmin", + "aadAuthenticationOnly": false, + "aadLoginName": "DBA Security Group", + "aadLoginObjectID": "e0357d81-55d8-44e9-9d9c-ab09dc710785", + "aadLoginType": "Group" + } + }, + "sqlmi": { + "value": { + "enabled": false + } + }, + "aml": { + "value": { + "enableHbiWorkspace": false + } + }, + "hubNetwork": { + "value": { + "virtualNetworkId": "/subscriptions/4fd845de-f6c8-4e6d-9a87-c21c4ebf7edd/resourceGroups/pubsec-hub-networking/providers/Microsoft.Network/virtualNetworks/hub-vnet", + "rfc1918IPRange": "10.18.0.0/22", + "rfc6598IPRange": "100.60.0.0/16", + "egressVirtualApplianceIp": "10.18.1.4", + "privateDnsManagedByHub": true, + "privateDnsManagedByHubSubscriptionId": "4fd845de-f6c8-4e6d-9a87-c21c4ebf7edd", + "privateDnsManagedByHubResourceGroupName": "private-dns-rg" + } + }, + "network": { + "value": { + "peerToHubVirtualNetwork": true, + "useRemoteGateway": false, + "name": "azmlsqlauth-vnet", + "dnsServers": [ + "10.18.1.4" + ], + "addressPrefixes": [ + "10.6.0.0/16" + ], + "subnets": { + "sqlmi": { + "comments": "SQL Managed Instances Delegated Subnet", + "name": "sqlmi", + "addressPrefix": "10.6.5.0/25" + }, + "databricksPublic": { + "comments": "Databricks Public Delegated Subnet", + "name": "databrickspublic", + "addressPrefix": "10.6.6.0/25" + }, + "databricksPrivate": { + "comments": "Databricks Private Delegated Subnet", + "name": "databricksprivate", + "addressPrefix": "10.6.7.0/25" + }, + "privateEndpoints": { + "comments": "Private Endpoints Subnet", + "name": "privateendpoints", + "addressPrefix": "10.6.8.0/25" + }, + "aks": { + "comments": "AKS Subnet", + "name": "aks", + "addressPrefix": "10.6.9.0/25" + }, + "appService": { + "comments": "App Service Subnet", + "name": "appService", + "addressPrefix": "10.6.10.0/25" + }, + "optional": [ + { + "comments": "Optional Subnet 1", + "name": "virtualMachines", + "addressPrefix": "10.6.11.0/25", + "nsg": { + "enabled": true + }, + "udr": { + "enabled": true + } + }, + { + "comments": "Optional Subnet 2 with delegation for NetApp Volumes", + "name": "NetappVolumes", + "addressPrefix": "10.6.12.0/25", + "nsg": { + "enabled": false + }, + "udr": { + "enabled": false + }, + "delegations": { + "serviceName": "Microsoft.NetApp/volumes" + } + } + ] + } + } + } + } +} diff --git a/config/variables/CanadaESLZ-main.yml b/config/variables/CanadaESLZ-main.yml deleted file mode 100644 index 2e020d24..00000000 --- a/config/variables/CanadaESLZ-main.yml +++ /dev/null @@ -1,86 +0,0 @@ -# ---------------------------------------------------------------------------------- -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT license. -# -# THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, -# EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES -# OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. -# ---------------------------------------------------------------------------------- - -# Environment YAML files can be used to supplement -# the variables specified in 'config/variables/common.yml'. You can: -# * Override existing common-vars.yml variable value settings, and -# * Create new variable values not present in common-vars.yml -# -# The naming convention for these YAML files is: -# {organization}-{branch}.yml -# -# where {organization} is the organization variable from the -# common.yml file -# and {branch} is the Azure Repos branch name used by the -# currently executing pipeline. - -variables: - deploymentRegion: canadacentral - - # Management Groups - var-managementgroup-hierarchy: > - { - "name": "Tenant Root Group", - "id": "343ddfdb-bef5-46d9-99cf-ed67d5948783", - "children": [ - { - "name": "Azure Landing Zones for Canadian Public Sector", - "id": "pubsec", - "children": [ - { - "name": "Platform", "id": "pubsecPlatform", - "children": [ - { "name": "Identity", "id": "pubsecPlatformIdentity", "children": [] }, - { "name": "Connectivity", "id": "pubsecPlatformConnectivity", "children": [] }, - { "name": "Management", "id": "pubsecPlatformManagement", "children": [] } - ] - }, - { - "name": "LandingZones", "id": "pubsecLandingZones", - "children": [ - { "name": "DevTest", "id": "pubsecLandingZonesDevTest", "children": [] }, - { "name": "QA", "id": "pubsecLandingZonesQA", "children": [] }, - { "name": "Prod", "id": "pubsecLandingZonesProd", "children": [] } - ] - }, - { - "name": "Sandbox", "id": "pubsecSandbox", - "children": [] - } - ] - } - ] - } - - # Logging - var-logging-region: canadacentral - var-logging-managementGroupId: pubsecPlatformManagement - var-logging-subscriptionId: bc0a4f9f-07fa-4284-b1bd-fbad38578d3a - var-logging-configurationFileName: logging.parameters.json - - ## This parameter is only used for HIPAA/HITRUST Policy Assignment - var-logging-diagnosticSettingsforNetworkSecurityGroupsStoragePrefix: pubsecnsg - - # Platform Identity - var-identity-region: canadacentral - var-identity-managementGroupId: pubsecPlatformIdentity - var-identity-subscriptionId: b357bf7b-3328-4d21-b94b-4bfa84af97b1 - var-identity-configurationFileName: identity.parameters.json - - # Hub Networking - var-hubnetwork-region: canadacentral - var-hubnetwork-managementGroupId: pubsecPlatformConnectivity - var-hubnetwork-subscriptionId: ed7f4eed-9010-4227-b115-2a5e37728f27 - - ## Hub Network configuration using Azure Firewall - required when Azure Firewall is used - var-hubnetwork-azfwPolicy-configurationFileName: hub-azfw-policy/azure-firewall-policy.parameters.json - var-hubnetwork-azfw-configurationFileName: hub-azfw/hub-network.parameters.json - - ## Hub Network configuration using Network Virtual Appliance (NVA) - required when Network Virtual Appliance (NVA) like Fortigate Firewalls are used - var-hubnetwork-nva-configurationFileName: hub-nva/hub-network.parameters.json \ No newline at end of file diff --git a/config/variables/CanadaPubSecALZ-main.yml b/config/variables/CanadaPubSecALZ-main.yml new file mode 100644 index 00000000..010a4503 --- /dev/null +++ b/config/variables/CanadaPubSecALZ-main.yml @@ -0,0 +1,78 @@ +variables: + var-hubnetwork-region: canadacentral + var-hubnetwork-managementGroupId: Connectivity + var-hubnetwork-azfw-configurationFileName: hub-azfw/hub-network.parameters.json + var-hubnetwork-nva-configurationFileName: hub-nva/hub-network.parameters.json + var-hubnetwork-subscriptionId: 4fd845de-f6c8-4e6d-9a87-c21c4ebf7edd + var-hubnetwork-azfwPolicy-configurationFileName: hub-azfw-policy/azure-firewall-policy.parameters.json + var-logging-managementGroupId: Management + var-logging-subscriptionId: 91e1aaa2-a0a0-4770-8d90-02daa39bf57a + deploymentRegion: canadacentral + var-identity-managementGroupId: Identity + var-logging-diagnosticSettingsforNetworkSecurityGroupsStoragePrefix: pubsecnsg + var-logging-configurationFileName: logging.parameters.json + var-managementgroup-hierarchy: |- + { + "id": "0d466ba2-7ea1-420f-9820-2583fc040733", + "name": "Tenant Root Group", + "children": [ + { + "id": "pubsec", + "name": "Canadian Public Sector Azure Landing Zones", + "children": [ + { + "id": "Platform", + "name": "Platform", + "children": [ + { + "id": "Management", + "name": "Management", + "children": [] + }, + { + "id": "Connectivity", + "name": "Connectivity", + "children": [] + }, + { + "id": "Identity", + "name": "Identity", + "children": [] + } + ] + }, + { + "id": "LandingZones", + "name": "LandingZones", + "children": [ + { + "id": "DevTest", + "name": "DevTest", + "children": [] + }, + { + "id": "QA", + "name": "QA", + "children": [] + }, + { + "id": "Prod", + "name": "Prod", + "children": [] + } + ] + }, + { + "id": "Sandbox", + "name": "Sandbox", + "children": [] + } + ] + } + ] + } + var-logging-region: canadacentral + var-identity-configurationFileName: identity.parameters.json + var-identity-region: canadacentral + var-identity-subscriptionId: 2987c7a3-1e43-4b28-b983-ac0925e37d03 + diff --git a/config/variables/cdssnc-main.yml b/config/variables/cdssnc-main.yml index e3139446..7278697c 100644 --- a/config/variables/cdssnc-main.yml +++ b/config/variables/cdssnc-main.yml @@ -1,80 +1,78 @@ -# ---------------------------------------------------------------------------------- -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT license. -# -# THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, -# EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES -# OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. -# ---------------------------------------------------------------------------------- - -# Environment YAML files can be used to supplement -# the variables specified in 'config/variables/common.yml'. You can: -# * Override existing common-vars.yml variable value settings, and -# * Create new variable values not present in common-vars.yml -# -# The naming convention for these YAML files is: -# {organization}-{branch}.yml -# -# where {organization} is the organization variable from the -# common.yml file -# and {branch} is the Azure Repos branch name used by the -# currently executing pipeline. - variables: + var-hubnetwork-region: canadacentral + var-hubnetwork-managementGroupId: Connectivity + var-hubnetwork-azfw-configurationFileName: hub-azfw/hub-network.parameters.json + var-hubnetwork-nva-configurationFileName: hub-nva/hub-network.parameters.json + var-hubnetwork-subscriptionId: 4fd845de-f6c8-4e6d-9a87-c21c4ebf7edd + var-hubnetwork-azfwPolicy-configurationFileName: hub-azfw-policy/azure-firewall-policy.parameters.json + var-logging-managementGroupId: Management + var-logging-subscriptionId: f27b081a-aa54-4ab4-9f26-a4c5375dc8fa deploymentRegion: canadacentral - - # Management Groups - var-managementgroup-hierarchy: > + var-identity-managementGroupId: Identity + var-logging-diagnosticSettingsforNetworkSecurityGroupsStoragePrefix: pubsecnsg + var-logging-configurationFileName: logging.parameters.json + var-managementgroup-hierarchy: |- { - "name": "Tenant Root Group", "id": "221ca1d3-b3f2-4346-8abc-88f802495c7d", + "name": "Tenant Root Group", "children": [ { - "name": "pubsec", "id": "pubsec", + "name": "Canadian Public Sector Azure Landing Zones", "children": [ { - "name": "pubsecPlatform", "id": "pubsecPlatform", + "id": "Platform", + "name": "Platform", "children": [ - { "name": "pubsecPlatformIdentity", "id": "pubsecPlatformIdentity", "children": [] }, - { "name": "pubsecPlatformConnectivity", "id": "pubsecPlatformConnectivity", "children": [] }, - { "name": "pubsecPlatformManagement", "id": "pubsecPlatformManagement", "children": [] } + { + "id": "Management", + "name": "Management", + "children": [] + }, + { + "id": "Connectivity", + "name": "Connectivity", + "children": [] + }, + { + "id": "Identity", + "name": "Identity", + "children": [] + } ] }, { - "name": "LandingZones", "id": "pubsecLandingZones", + "id": "LandingZones", + "name": "LandingZones", "children": [ - { "name": "pubsecLandingZonesDevTest", "id": "pubsecLandingZonesDevTest", "children": [] }, - { "name": "pubsecLandingZonesQA", "id": "pubsecLandingZonesQA", "children": [] }, - { "name": "pubsecLandingZonesProd", "id": "pubsecLandingZonesProd", "children": [] } + { + "id": "DevTest", + "name": "DevTest", + "children": [] + }, + { + "id": "QA", + "name": "QA", + "children": [] + }, + { + "id": "Prod", + "name": "Prod", + "children": [] + } ] }, { - "name": "pubsecSandbox", "id": "pubsecSandbox", + "id": "Sandbox", + "name": "Sandbox", "children": [] } ] } ] } - - # Logging var-logging-region: canadacentral - var-logging-managementGroupId: pubsecPlatform - var-logging-subscriptionId: f27b081a-aa54-4ab4-9f26-a4c5375dc8fa - var-logging-configurationFileName: logging.parameters.json - - ## This parameter is only used for HIPAA/HITRUST Policy Assignment - var-logging-diagnosticSettingsforNetworkSecurityGroupsStoragePrefix: pubsecnsg - - # # Hub Networking - # var-hubnetwork-region: canadacentral - # var-hubnetwork-managementGroupId: pubsecPlatformConnectivity - # var-hubnetwork-subscriptionId: ed7f4eed-9010-4227-b115-2a5e37728f27 - - # ## Hub Network configuration using Azure Firewall - required when Azure Firewall is used - # var-hubnetwork-azfwPolicy-configurationFileName: hub-azfw-policy/azure-firewall-policy.parameters.json - # var-hubnetwork-azfw-configurationFileName: hub-azfw/hub-network.parameters.json + # var-identity-configurationFileName: identity.parameters.json + # var-identity-region: canadacentral + # var-identity-subscriptionId: 2987c7a3-1e43-4b28-b983-ac0925e37d03 - # ## Hub Network configuration using Network Virtual Appliance (NVA) - required when Network Virtual Appliance (NVA) like Fortigate Firewalls are used - # var-hubnetwork-nva-configurationFileName: hub-nva/hub-network.parameters.json \ No newline at end of file diff --git a/docs/archetypes/authoring-guide.md b/docs/archetypes/authoring-guide.md index 8a01d27a..612e2fbe 100644 --- a/docs/archetypes/authoring-guide.md +++ b/docs/archetypes/authoring-guide.md @@ -339,24 +339,24 @@ Azure Resource Manager (ARM) parameters files provide deployment information to These parameter files are located in [config/subscription](../../config/subscriptions) folder. This folder is configurable in `common.yml` and you can override in environment configuration files using the `subscriptionsPathFromRoot` setting. By default it is set to `config/subscriptions`. -Immediate subfolder defines the environment which is based on Azure DevOps Organization (i.e. `CanadaESLZ`) & Git branch name (i.e. `main`), for example the subfolder will be called `CanadaESLZ-main`. You can have many environments based on Git branch names such as `CanadaESLZ-feature-1`, `CanadaESLZ-dev`, etc. +Immediate subfolder defines the environment which is based on Azure DevOps Organization (i.e. `CanadaPubSecALZ`) & Git branch name (i.e. `main`), for example the subfolder will be called `CanadaPubSecALZ-main`. You can have many environments based on Git branch names such as `CanadaPubSecALZ-feature-1`, `CanadaPubSecALZ-dev`, etc. ARM parameter files are used by `subscriptions-ci` Azure DevOps Pipeline when configuring subscriptions with Azure resources. The pipeline will detect environment, management group, subscription, deployment location and deployment parameters using the folder hierarchy, file name and file content. For example when the file path is: -`config/subscriptions/CanadaESLZ-main/pubsec/LandingZones/DevTest/8c6e48a4-4c73-4a1f-9f95-9447804f2c98_machinelearning_canadacentral.json` +`config/subscriptions/CanadaPubSecALZ-main/pubsec/LandingZones/DevTest/8c6e48a4-4c73-4a1f-9f95-9447804f2c98_machinelearning_canadacentral.json` -- **Folder hierarchy:** config/subscriptions/CanadaESLZ-main/pubsec/LandingZones/DevTest/ +- **Folder hierarchy:** config/subscriptions/CanadaPubSecALZ-main/pubsec/LandingZones/DevTest/ - **File name:** 8c6e48a4-4c73-4a1f-9f95-9447804f2c98_machinelearning_canadacentral.json | Deployment Information | Approach | Example | |:---------------------- |:-------- |:------- | -| Environment | DevOps organization name & Git branch name | `CanadaESLZ-main` | -| Management Group | Calculated based on concatenating the folder hierarchy under `config/subscription/CanadaESLZ-main` | pubsecLandingZonesDevTest (without the `/`). [See below for details](#management-group-id-detection). +| Environment | DevOps organization name & Git branch name | `CanadaPubSecALZ-main` | +| Management Group | Calculated based on concatenating the folder hierarchy under `config/subscription/CanadaPubSecALZ-main` | pubsecLandingZonesDevTest (without the `/`). [See below for details](#management-group-id-detection). | Subscription | Part of the file name | `8c6e48a4-4c73-4a1f-9f95-9447804f2c98` | | Deployment location | Part of the file name | `canadacentral` | -| Deployment parameters | Content of the file | [See file content](../../config/subscriptions/CanadaESLZ-main/pubsec/LandingZones/DevTest/8c6e48a4-4c73-4a1f-9f95-9447804f2c98_machinelearning_canadacentral.json) | +| Deployment parameters | Content of the file | [See file content](../../config/subscriptions/CanadaPubSecALZ-main/pubsec/LandingZones/DevTest/8c6e48a4-4c73-4a1f-9f95-9447804f2c98_machinelearning_canadacentral.json) | The ARM parameter file name can be in one of two formats: @@ -402,7 +402,7 @@ The `subscriptions-ci` management group detection logic is built to accommodate - Folder structure in `config/subscription/` is created without including the prefixes. For example: ```none - config/subscription/CanadaESLZ-main + config/subscription/CanadaPubSecALZ-main - pubsec - LandingZones - DevTest @@ -415,7 +415,7 @@ The `subscriptions-ci` management group detection logic is built to accommodate - Folder structure in `config/subscription/` should be flat. For example: ```none - config/subscription/CanadaESLZ-main + config/subscription/CanadaPubSecALZ-main - pubsec - LandingZones - DevTest diff --git a/docs/onboarding/azure-devops-pipelines.md b/docs/onboarding/azure-devops-pipelines.md index 4f71e426..fc17f7e0 100644 --- a/docs/onboarding/azure-devops-pipelines.md +++ b/docs/onboarding/azure-devops-pipelines.md @@ -4,6 +4,8 @@ This document provides steps required to onboard to the Azure Landing Zones desi > There are scripts available to help simplify the onboarding process to Azure Landing Zones design using Azure DevOps Pipelines. The [Azure DevOps Scripts](./azure-devops-scripts.md) document contains more detailed information on the those scripts. +> There are scripts available to help simplify the configuration process of the Azure Landing Zones design. The [Configuration Scripts](./configuration-scripts.md) document contains more detailed information on the those scripts. + **All steps will need to be repeated per Azure AD tenant.** --- @@ -201,6 +203,8 @@ This deployment diagram describes the steps for deploying one, many or all modul * [Migrate Logging configuration from Azure DevOps variables to JSON parameters file](#migrate-logging-configuration-from-azure-devops-variables-to-json-parameters-file) * [Migrate Hub Networking configuration from Azure DevOps variables to JSON parameters file](#migrate-hub-networking-configuration-from-azure-devops-variables-to-json-parameters-file) +>Note: For steps #3 - #9 above, there are scripts available to automate generating the JSON and YAML configuration files for environments. Refer to the [Configuration Scripts](./configuration-scripts.md) documentation for more information. + --- ## Step 1 - Create Service Principal Account & Assign RBAC @@ -342,7 +346,7 @@ Instructions: >**Note**: The ID of the default parent management group 'Tenant Root Group' is the same as the Azure Active Directory (AAD) Tenant ID (GUID). -2. Create/edit `./config/variables/-.yml` in Git (i.e. CanadaESLZ-main.yml). This file name is automatically inferred by the pipeline based on the Azure DevOps organization name and the branch name. +2. Create/edit `./config/variables/-.yml` in Git (i.e. CanadaPubSecALZ-main.yml). This file name is automatically inferred by the pipeline based on the Azure DevOps organization name and the branch name. **Sample environment YAML (v0.9.0 or later)** @@ -403,7 +407,7 @@ Instructions: * Specify the `id` and `name` of your existing Azure AD tenant for the topmost management group definition. The `id` attribute for this element is mapped into the `var-parentManagementGroupId` pipeline variable for backward compatibility. * Specify only 1 child management group definition for the topmost management group definition. You can specify more than 1 child of the topmost management group definition, but it is the first child of the topmost level that will be considered the root of of your management group hierarchy, and is the scope that the `policy-ci` pipeline will use to deploy built-in and custom policies. The `id` attribute for this element is mapped into the `var-topLevelManagementGroupName` pipeline variable for backward compatibility. - * The `id` attribute for management group elements can only be an ASCII letter, digit, `-`, `_`, `(`, `)`, `.` and cannot end with a period. In the sample environment configuration file (`CanadaESLZ-main.yml`), we illustrate a convention that prepends the id of the parent management group to the id of each child management group. This is an example only and not a requirement. You are welcome to choose any management group id convention that best suits your needs. + * The `id` attribute for management group elements can only be an ASCII letter, digit, `-`, `_`, `(`, `)`, `.` and cannot end with a period. In the sample environment configuration file (`CanadaPubSecALZ-main.yml`), we illustrate a convention that prepends the id of the parent management group to the id of each child management group. This is an example only and not a requirement. You are welcome to choose any management group id convention that best suits your needs. * If you are using **CanadaPubSecALZ v0.9.0 or later** and **do not** include a `var-managementgroup-hierarchy` variable setting in your configuration, it will fallback to using the pipeline variables `var-parentManagementGroupId` and `var-topLevelManagementGroupName`. This is to ensure backward compatibility, enabling newer versions of the code to run with older environment configurations. * If you are using **CanadaPubSecALZ v0.9.0** or later and **do** include a `var-managementgroup-hierarchy` variable setting in your configuration, it will override any pipeline variables `var-parentManagementGroupId` and `var-topLevelManagementGroupName` also present. @@ -485,8 +489,8 @@ This role assignment is used to grant users access to the logging subscription b > **The deployment automation will update the existing resources instead of creating new.** 1. Create directory `./config/logging`. -2. Create subdirectory based on the syntax: `-` (e.g. `CanadaESLZ-main` to create path `./config/logging/CanadaESLZ-main/`). -3. Create JSON parameters file with name `logging.parameters.json` (any name can be used) in directory created on step 2 (i.e. `./config/logging/CanadaESLZ-main/logging.parameters.json`). +2. Create subdirectory based on the syntax: `-` (e.g. `CanadaPubSecALZ-main` to create path `./config/logging/CanadaPubSecALZ-main/`). +3. Create JSON parameters file with name `logging.parameters.json` (any name can be used) in directory created on step 2 (i.e. `./config/logging/CanadaPubSecALZ-main/logging.parameters.json`). 4. Define deployment parameters based on example below. * Set valid contact information for the Azure Service Health Alerts: email and phone number. @@ -782,11 +786,11 @@ In order to configure audit stream for Azure Monitor, identify the following inf > * [Hub Networking with Fortigate Firewall (NVA)](../../docs/archetypes/hubnetwork-nva-fortigate.md) 1. Create directory `./config/networking`. -1. Create subdirectory based on the syntax: `-` (i.e. `CanadaESLZ-main` to create path `./config/networking/CanadaESLZ-main/`). +1. Create subdirectory based on the syntax: `-` (i.e. `CanadaPubSecALZ-main` to create path `./config/networking/CanadaPubSecALZ-main/`). 1. When using Hub Networking with Azure Firewall - 1. Create subdirectory: `hub-azfw-policy` (i.e. `./config/networking/CanadaESLZ-main/hub-azfw-policy`) - 1. Create JSON parameters file with name `azure-firewall-policy.parameters.json` (any name can be used) in the directory (i.e. `./config/networking/CanadaESLZ-main/hub-azfw-policy/azure-firewall-policy.parameters.json`). + 1. Create subdirectory: `hub-azfw-policy` (i.e. `./config/networking/CanadaPubSecALZ-main/hub-azfw-policy`) + 1. Create JSON parameters file with name `azure-firewall-policy.parameters.json` (any name can be used) in the directory (i.e. `./config/networking/CanadaPubSecALZ-main/hub-azfw-policy/azure-firewall-policy.parameters.json`). 1. Define deployment parameters based on example below. * Set the values for the Azure tags that would be applied to the logging resources. @@ -820,8 +824,8 @@ In order to configure audit stream for Azure Monitor, identify the following inf } ``` - 1. Create subdirectory: `hub-azfw` (i.e. `./config/networking/CanadaESLZ-main/hub-azfw`) - 1. Create JSON parameters file with name `hub-network.parameters.json` (any name can be used) in the directory (i.e. `./config/networking/CanadaESLZ-main/hub-azfw/hub-network.json`). + 1. Create subdirectory: `hub-azfw` (i.e. `./config/networking/CanadaPubSecALZ-main/hub-azfw`) + 1. Create JSON parameters file with name `hub-network.parameters.json` (any name can be used) in the directory (i.e. `./config/networking/CanadaPubSecALZ-main/hub-azfw/hub-network.json`). 1. Define deployment parameters based on example below. * Set valid contact information for the Azure Service Health Alerts: email and phone number. @@ -1058,8 +1062,8 @@ In order to configure audit stream for Azure Monitor, identify the following inf 1. When using Hub Networking with Fortigate Firewall (NVA) - 1. Create subdirectory: `hub-nva` (i.e. `./config/networking/CanadaESLZ-main/hub-nva`) - 1. Create JSON parameters file with name `hub-network.parameters.json` (any name can be used) in the directory (i.e. `./config/networking/CanadaESLZ-main/hub-nva/hub-network.parameters.json`). + 1. Create subdirectory: `hub-nva` (i.e. `./config/networking/CanadaPubSecALZ-main/hub-nva`) + 1. Create JSON parameters file with name `hub-network.parameters.json` (any name can be used) in the directory (i.e. `./config/networking/CanadaPubSecALZ-main/hub-nva/hub-network.parameters.json`). 1. Define deployment parameters based on example below. * Set valid contact information for the Azure Service Health Alerts: email and phone number. @@ -1515,9 +1519,9 @@ In order to configure audit stream for Azure Monitor, identify the following inf 1. Create directory ./config/identity. - 1. Create subdirectory based on the syntax: `-` (i.e. `CanadaESLZ-main` to create path `./config/identity/CanadaESLZ-main/`). + 1. Create subdirectory based on the syntax: `-` (i.e. `CanadaPubSecALZ-main` to create path `./config/identity/CanadaPubSecALZ-main/`). - 1. Make a copy of an existing subscription configuration file under `config/identity/CanadaESLZ-main` as a starting point + 1. Make a copy of an existing subscription configuration file under `config/identity/CanadaPubSecALZ-main` as a starting point 1. Define deployment parameters based on example below. @@ -1676,7 +1680,7 @@ In order to configure audit stream for Azure Monitor, identify the following inf *Review the [README.md under `/config/subscriptions`](../../config/subscriptions/README.md) to create the folder structure required for subscriptions deployments.* - 1. Make a copy of an existing subscription configuration file under `config/subscriptions/CanadaESLZ-main` as a starting point + 1. Make a copy of an existing subscription configuration file under `config/subscriptions/CanadaPubSecALZ-main` as a starting point 2. Be sure to rename the file in one of the following formats: * `[GUID]_[TYPE].json` @@ -1867,7 +1871,7 @@ As of `v0.10.0`, logging configuration have been migrated to JSON parameters fil * Separates Azure DevOps pipeline variables from ARM deployment parameters. * Simplifies support for multiple Log Analytics Workspaces in an Azure tenant (i.e. LAWs deployed by region or workload) -We added a new parameter to `common.yml` to set the folder for logging configuration. This folder is used by Azure DevOps Pipelines to create a fully qualified file path for logging configuration. A fully qualified path will have the following structure: ``/`-`/`logging.parameters.json`. For example: `config/logging/CanadaESLZ-main/logging.parameters.json` +We added a new parameter to `common.yml` to set the folder for logging configuration. This folder is used by Azure DevOps Pipelines to create a fully qualified file path for logging configuration. A fully qualified path will have the following structure: ``/`-`/`logging.parameters.json`. For example: `config/logging/CanadaPubSecALZ-main/logging.parameters.json` ```yaml loggingPathFromRoot: 'config/logging' @@ -1876,8 +1880,8 @@ We added a new parameter to `common.yml` to set the folder for logging configura Migration process: 1. Create directory `./config/logging`. -2. Create subdirectory based on the syntax: `-` (i.e. `CanadaESLZ-main` to create path `./config/logging/CanadaESLZ-main/`). -3. Create JSON parameters file with name `logging.parameters.json` (any name can be used) in the directory (i.e. `./config/logging/CanadaESLZ-main/logging.parameters.json`). +2. Create subdirectory based on the syntax: `-` (i.e. `CanadaPubSecALZ-main` to create path `./config/logging/CanadaPubSecALZ-main/`). +3. Create JSON parameters file with name `logging.parameters.json` (any name can be used) in the directory (i.e. `./config/logging/CanadaPubSecALZ-main/logging.parameters.json`). 4. Define deployment parameters based on example below. **Template to use for logging.parameters.json** @@ -2021,7 +2025,7 @@ As of `v0.10.0`, hub networking configuration have been migrated to JSON paramet * Separates Azure DevOps pipeline variables from ARM deployment parameters. * Simplifies support for multiple Hub Networks in an Azure tenant (i.e. Hub Network deployed by region) -We added a new parameter to `common.yml` to set the folder for networking configuration. This folder is used by Azure DevOps Pipelines to create a fully qualified file path for networking configuration. A fully qualified path will have the following structure: ``/`-`/`hub-capability`/`hub-network.parameters.json`. For example: `config/networking/CanadaESLZ-main/hub-azfw/hub-network.parameters.json` +We added a new parameter to `common.yml` to set the folder for networking configuration. This folder is used by Azure DevOps Pipelines to create a fully qualified file path for networking configuration. A fully qualified path will have the following structure: ``/`-`/`hub-capability`/`hub-network.parameters.json`. For example: `config/networking/CanadaPubSecALZ-main/hub-azfw/hub-network.parameters.json` ```yaml networkPathFromRoot: 'config/networking' @@ -2030,11 +2034,11 @@ We added a new parameter to `common.yml` to set the folder for networking config Migration process: 1. Create directory `./config/networking`. -2. Create subdirectory based on the syntax: `-` (i.e. `CanadaESLZ-main` to create path `./config/networking/CanadaESLZ-main/`). +2. Create subdirectory based on the syntax: `-` (i.e. `CanadaPubSecALZ-main` to create path `./config/networking/CanadaPubSecALZ-main/`). 3. When using Hub Networking with Azure Firewall - 1. Create subdirectory: `hub-azfw-policy` (i.e. `./config/networking/CanadaESLZ-main/hub-azfw-policy`) - 1. Create JSON parameters file with name `azure-firewall-policy.parameters.json` (any name can be used) in the directory (i.e. `./config/networking/CanadaESLZ-main/hub-azfw-policy/azure-firewall-policy.parameters.json`). + 1. Create subdirectory: `hub-azfw-policy` (i.e. `./config/networking/CanadaPubSecALZ-main/hub-azfw-policy`) + 1. Create JSON parameters file with name `azure-firewall-policy.parameters.json` (any name can be used) in the directory (i.e. `./config/networking/CanadaPubSecALZ-main/hub-azfw-policy/azure-firewall-policy.parameters.json`). 1. Define deployment parameters based on example below. **Template to use for azure-firewall-policy.parameters.json** @@ -2057,8 +2061,8 @@ Migration process: } ``` - 1. Create subdirectory: `hub-azfw` (i.e. `./config/networking/CanadaESLZ-main/hub-azfw`) - 1. Create JSON parameters file with name `hub-network.parameters.json` (any name can be used) in the directory (i.e. `./config/networking/CanadaESLZ-main/hub-azfw/hub-network.json`). + 1. Create subdirectory: `hub-azfw` (i.e. `./config/networking/CanadaPubSecALZ-main/hub-azfw`) + 1. Create JSON parameters file with name `hub-network.parameters.json` (any name can be used) in the directory (i.e. `./config/networking/CanadaPubSecALZ-main/hub-azfw/hub-network.json`). 1. Define deployment parameters based on example below. **Template to use for hub-network.parameters.json** @@ -2243,8 +2247,8 @@ Migration process: 4. When using Hub Networking with Network Virtual Appliance - 1. Create subdirectory: `hub-nva` (i.e. `./config/networking/CanadaESLZ-main/hub-nva`) - 1. Create JSON parameters file with name `hub-network.parameters.json` (any name can be used) in the directory (i.e. `./config/networking/CanadaESLZ-main/hub-nva/hub-network.parameters.json`). + 1. Create subdirectory: `hub-nva` (i.e. `./config/networking/CanadaPubSecALZ-main/hub-nva`) + 1. Create JSON parameters file with name `hub-network.parameters.json` (any name can be used) in the directory (i.e. `./config/networking/CanadaPubSecALZ-main/hub-nva/hub-network.parameters.json`). 1. Define deployment parameters based on example below. **Template to use for hub-network.parameters.json** diff --git a/docs/onboarding/configuration-scripts.md b/docs/onboarding/configuration-scripts.md new file mode 100644 index 00000000..e92fbe92 --- /dev/null +++ b/docs/onboarding/configuration-scripts.md @@ -0,0 +1,663 @@ +# Configuration Scripts + +## Introduction + +This document discusses the scripts available to help simplify creating and using configuration files for a CanadaPubSecALZ deployment. + +## Table of Contents + +- [Prerequisites](#prerequisites) +- [Creating the Service Principal](#creating-the-service-principal) +- [Working with Configuration Files](#working-with-configuration-files) +- [Working with Deployments](#working-with-deployments) + +--- + +## Prerequisites + +The instructions in this document and scripts in the `/scripts/configuration` folder have a number of prerequisites. Please review the prerequisites below and complete any missing prerequisites before proceeding. + +### Azure PowerShell + +Install the latest version of the Azure PowerShell module. Review the [Azure PowerShell documentation](https://docs.microsoft.com/powershell/azure/install-az-ps) for installation instructions. + +### Azure CLI + +Install the latest version of the Azure CLI. Review the [Azure CLI documentation](https://docs.microsoft.com/cli/azure/install-azure-cli) for installation instructions. + +### Required Permissions + +Review the [Required Permissions](./azure-devops-scripts.md#required-permissions) section of the [Azure DevOps Scripts](./azure-devops-scripts.md) document for the required permissions to run the scripts in the `/scripts/configuration` folder. + +--- + +## Overview + +The scripts in the `/scripts/configuration` folder can be used to simplify part of the Azure Landing Zones onboarding process related to creating the configuration files (`.yml` and `.json`) for your environment. + +Using these scripts is optional.If you choose not to use them, you can still follow the manual steps in the [Azure DevOps Pipelines Onboarding Guide](./azure-devops-pipelines.md) document to create the configuration files. + +These scripts consolidate most, but not all, of the common settings available in the configuration files used to for a CanadaPubSecALZ deployment. Notable examples of configuration values you will need to update directly in the finished configuration files include network settings such as IP addresses and CIDR ranges. Therefore, you will still need to review and update the configuration files after they are created by these scripts. + +Benefits of using these scripts: + +- Simplifies the process of creating a new service principal and credential file. +- Simplifies the process of creating a new set of configuration files based on an existing set of configuration files. +- Automatically copies an existing set of configuration files to a new set of configuration files, putting the new files in their correct folder locations, retaining common configuration settings, and overriding select configuration settings using a single YAML file stored outside of the repository. +- Provide detailed logging for all credential, configuration, and deployment operations in datetime-stamped log files located in your home directory for easier troubleshooting. +- Provide a foundation for automating the creation and management of configuration files using Azure DevOps pipelines or GitHub Actions. + +The following scripts are available: + +Script | Category | Description +---- | -------- | ------------ +Connect-AlzCredential.ps1 | Credentials | Connects to Azure using one of the following methods: Credential file, Service Principal, or Interactive login. +Get-AlzConfiguration.ps1 | Configuration | Gets the ALZ configuration file. Used primarily by other scripts in this folder. +Get-AlzSubscriptions.ps1 | Configuration | Gets an array of ALZ subscription identifiers. Used primarily by other scripts in this folder. +Install-Prerequisites.ps1 | Prerequisites | Installs the PowerShell module prerequisites. +New-AlzConfiguration.ps1 | Configuration | Creates the ALZ configuration files in a specified Target Environment from existing configuration files in a specified Source Environment. +New-AlzCredential.ps1 | Credentials | Creates an ALZ credential file in your home directory. +New-AlzDeployment.ps1 | Deployment | Deploys the ALZ configuration files to the specified Target Environment. Uses the `../deployments/RunWorkflows.ps1` script to deploy the configuration files. +Remove-AlzConfiguration.ps1 | Configuration | Removes the ALZ configuration file. +Remove-AlzCredential.ps1 | Credentials | Removes all elements of an ALZ credential created using the `New-AlzCredential.ps1` script. This includes: the credential file, the service principal, and the app registration. +Test-AlzCredential.ps1 | Credentials | Tests the ALZ credential file. + +>Note: The scripts in this folder are designed to be run from the folder they are located in (`/scripts/configuration`). Running them from any other location may result in errors. + +The configuration scripts take some common parameters. These parameters are used to specify the location of the ALZ configuration files. The default values for these parameters are as follows: + +```powershell +[string]$UserRootPath = "$HOME" +[string]$UserLogsPath = "$UserRootPath/ALZ/logs" +[string]$UserCredsPath = "$UserRootPath/ALZ/credentials" +[string]$UserConfigPath = "$UserRootPath/ALZ/config" +``` + +These parameters can be overridden by specifying the parameters when running the scripts. By default, they are set to the current user's home directory, which is usually outside of the repository. This is done to prevent the ALZ configuration files from being committed to the repository since some of these configuration files contain sensitive information such as credentials that should not be shared. + +The `logs` folder contains log output from the scripts. The `credentials` folder contains the ALZ credential files. The `config` folder contains the ALZ configuration input files. + +The following sections of this document will outline the end-to-end process of creating the ALZ credentials, creating the ALZ configuration files, and then using the ALZ configuration files to deploy the Azure Landing Zones design using either PowerShell or the Azure DevOps pipelines. + +--- + +## Creating the Service Principal + +This section deals with creating the ALZ credential, which is used by the CanadaPubSecALZ configuration scripts to authenticate to Azure during deployment. + +You must be signed in to Azure via the Azure PowerShell SDK before running the scripts in this section. You can do this by either running `Connect-AzAccount` or by using the `Connect-AlzCredential.ps1` script with the `-TenantId` parameter. + +For example: + +```powershell +PS> $TenantId = '10000000-0000-0000-0000-000000000000' +PS> .\Connect-AlzCredential.ps1 -TenantId $TenantId +``` + +You will need certain permissions to run the scripts in this section. Review the [Required Permissions](./azure-devops-scripts.md#required-permissions) section of the [Azure DevOps Scripts](./azure-devops-scripts.md) document for the required permissions to run the scripts in this folder. + +### The ALZ Credential + +The ALZ credential file is a JSON file that contains the following information: `appId`, `displayName`, `password`, and `tenant`. The `appId` and `password` are used to authenticate to Azure, and the `tenant` is used to identify the tenant to which the service principal belongs. The `displayName` is used to identify the service principal. + +### Generate the Credential + +The first step is to generate the credential. This is done by running the `New-AlzCredential.ps1` script. This script will create a service principal in the tenant specified by the `TenantId` parameter. The service principal will be created with the `Owner` role in the tenant. The script will also create the ALZ credential file in the `$HOME/ALZ/credentials` folder. The name of the ALZ credential file will be the same as the name of the environment specified by the `Environment` parameter. + +```powershell +PS> $Environment = 'MyAzureDevOpsOrg-main' +PS> .\New-AlzCredential.ps1 -Environment $Environment +``` + +```text +Creating Service Principal for environment (MyAzureDevOpsOrg-main) in tenant (domain.onmicrosoft.com) + appId: 20000000-0000-0000-0000-000000000000 + displayName: MyAzureDevOpsOrg-main + password: ********** + tenant: 10000000-0000-0000-0000-000000000000 + +Saving Service Principal to file (C:\Users\username\ALZ\credentials/MyAzureDevOpsOrg-main.json) + +Elapsed time: 00:00:05.3650544 +``` + +### Check Credential File Creation + +The next step is to check that the credential file was created successfully. The credential file will be located in the `$HOME/ALZ/credentials` folder. The name of the credential file will be the same as the name of the environment specified by the `Environment` parameter. + +```powershell +PS> $Environment = 'MyAzureDevOpsOrg-main' +PS> Get-ChildItem -Path $HOME/ALZ/credentials +``` + +```text + Directory: C:\Users\username\ALZ\credentials + +Mode LastWriteTime Length Name +---- ------------- ------ ---- +-a--- 7/1/2023 10:40 AM 206 MyAzureDevOpsOrg-main.json +``` + +### Check Credential File Contents + +The next step is to check that the credential file contains the correct information. The credential file will be a JSON file that contains the following information: `appId`, `displayName`, `password`, and `tenant`. The `appId` and `password` are used to authenticate to Azure, and the `tenant` is used to identify the tenant to which the service principal belongs. The `displayName` is used to identify the service principal. + +```powershell +PS> $Environment = 'MyAzureDevOpsOrg-main' +PS> Get-Content -Raw -Path $HOME/ALZ/credentials/$Environment.json +``` + +```text +{ + "appId": "20000000-0000-0000-0000-000000000000", + "displayName": "MyAzureDevOpsOrg-main", + "password": "this-is-not-a-real-password", + "tenant": "10000000-0000-0000-0000-000000000000" +} +``` + +### Test Credentials + +The next step is to test the credentials. This is done by running the `Test-AlzCredential.ps1` script. This script will test the credentials by logging in to Azure using the service principal specified by the `Environment` parameter. The script will check the following: + +- the service principal has the `Owner` role in the tenant +- the service principal can be used to log in to Azure +- the Azure context is set to the correct environment + +```powershell +PS> $Environment = 'MyAzureDevOpsOrg-main' +PS> .\Test-AlzCredential.ps1 -Environment $Environment +``` + +```text +Service Principal (MyAzureDevOpsOrg-main) for environment (MyAzureDevOpsOrg-main) from tenant (10000000-0000-0000-0000-000000000000) is an Owner of the tenant. + +Current Azure context: + +Name Account SubscriptionName Environment TenantId +---- ------- ---------------- ----------- -------- +ALZ-Workload (00000000-… user@domain ALZ-Workload AzureCloud 10000000-0000-0000-0000-000… + +Logging in to Azure using service principal... + +Service Principal Azure context: + +Id : 00000000-0000-0000-0000-000000000000 +Type : ServicePrincipal +Tenants : {10000000-0000-0000-0000-000000000000} +AccessToken : +Credential : +TenantMap : {} +CertificateThumbprint : + +Original Azure context: + +Name Account SubscriptionName Environment TenantId +---- ------- ---------------- ----------- -------- +ALZ-Workload (00000000-… user@domain ALZ-Workload AzureCloud 10000000-0000-0000-0000-000… + +Elapsed time: 00:00:04.9138939 +``` + +--- + +## Working with Configuration Files + +### Configuration File Structure + +Configurations for the CanadaPubSecALZ implementation are stored under the `config` folder in the root of the repository. There are four subfolders under the `config` folder: + +- The `logging` subfolder contains the configuration files for the logging and monitoring components of the implementation. +- The `networking` subfolder contains the configuration files for the networking components of the implementation. +- The `identity` subfolder contains the configuration files for the identity components of the implementation. +- The `subscriptions` subfolder contains the configuration files for the subscriptions used by the implementation. +- The `variables` subfolder contains the configuration files for the variables used by the implementation. + +The `logging`, `networking`, `identity`, and `subscriptions` subfolders contain JSON configuration files for each environment. An environment is named using the following convention: `-`. For example, the `CanadaPubSecALZ` environment corresponding to the `CanadaPubSecALZ` organization name (for Azure DevOps) or repository name (for GitHub) and the `main` branch of the repository is named `CanadaPubSecALZ-main`. + +The `variables` subfolder contains a YAML configuration file for each environment. An environment is named using the following convention: `-`. For example, the `CanadaPubSecALZ` environment corresponding to the `CanadaPubSecALZ` organization name (for Azure DevOps) or repository name (for GitHub) and the `main` branch of the repository is named `CanadaPubSecALZ-main`. + +Take a moment to familiarize yourself with the contents of the `config` folder, its subfolders, and the JSON and YAML configuration files therein. The configuration files in the main repository are provided as a starting point for your implementation. You will need to make copies of and modify the configuration files to suit your implementation. + +In order to streamline the process of creating configuration files tailored for your environment(s), the `New-AlzConfiguration.ps1` script has been provided. This script will create the configuration files for your implementation. It uses configuration files for an existing environment in the main repository as a starting point, combining information from a YAML file you create in your `$HOME/ALZ/config` folder that contains a subset of the most commonly updated configuration values. The script will then create the configuration files for your environment(s) in the correct location. + +### Using a Configuration Template + +Create a YAML file in your `$HOME/ALZ/config` folder that contains the configuration values for your implementation. The file name should be the name of your environment, followed by the `.yml` extension. For example, if your environment is named `MyAzureDevOpsOrg-main`, the file name should be `MyAzureDevOpsOrg-main.yml`. + +Some notes about the values shown in the sample YAML template below: + +- Some sections in the sample YAML file are commented out. You can uncomment these sections and provide values for them if you need to override the default values. + +- You may comment out sections that you do not need to override the existing values from the source environment configuration. + +- Most of the values you are likely to change are represented in the YAML template, with the exception of the network CIDR blocks. These are defined in the `networking` configuration files, and are discussed in more detail in the [Azure DevOps Pipelines Onboarding Guide](./azure-devops-pipelines.md). + +- The `Source` attribute is the name of the environment you are copying the configuration from. This environment must already exist in your repository's `config` folder. + +- The `Target` attribute is empty in the sample YAML file. When no value is specified, the base name of the YAML template file will be used to form your new environment name. For example, if your YAML template file is named `MyAzureDevOpsOrg-main.yml`, the `Target` attribute will be set to `MyAzureDevOpsOrg-main` by default. + +- The following GUID is provided as a placeholder for the Azure AD tenant identifier. You must replace them with the actual GUID value of the Azure AD tenant in your environment: + - `10000000-0000-0000-0000-000000000000`: Tenant + +- The following GUIDs are provided as placeholders for Azure subscription identifiers. You must replace them with the actual GUID values of the subscriptions in your environment: + - `20000000-0000-0000-0000-000000000000`: Logging subscription + - `30000000-0000-0000-0000-000000000000`: Network Hub subscription + - `40000000-0000-0000-0000-000000000000`: Identity subscription + - `70000000-0000-0000-0000-000000000000`: Generic subscription + - `80000000-0000-0000-0000-000000000000`: Machine Learning subscription + - `90000000-0000-0000-0000-000000000000`: Healthcare subscription + + Note that the last 3 subscriptions correspond to each of the 3 archetypes provided in the reference implementation: Generic, Machine Learning, and Healthcare. These are optional and one or more of these can be removed if not needed. + +- The following GUIDs are provided as placeholders for Azure AD security group identifiers. You must replace them with the actual GUID values of the security groups in your environment: + - `00000000-1000-0000-0000-000000000000`: Azure AD group to assign Contributor role in Logging subscription + - `00000000-2000-0000-0000-000000000000`: Azure AD group to assign Contributor role in Network subscription + - `00000000-3000-0000-0000-000000000000`: Azure AD group to assign Contributor role in Identity subscription + - `00000000-4000-0000-0000-000000000000`: Azure AD group to assign Contributor role in Generic subscription + - `00000000-5000-0000-0000-000000000000`: Azure AD group to assign custom landing zone application owners role in Generic subscription + - `00000000-6000-0000-0000-000000000000`: Azure AD group to assign Contributor role in Machine Learning subscription + - `00000000-7000-0000-0000-000000000000`: Azure AD group to assign custom landing zone application owners role in Machine Learning subscription + - `00000000-8000-0000-0000-000000000000`: Azure AD group to assign Contributor role in Healthcare subscription + - `00000000-9000-0000-0000-000000000000`: Azure AD group to assign custom landing zone application owners role in Healthcare subscription + +- The following partial GUIDs (8-character prefix) are provided as placeholders for the Azure subscription identifiers for 3 of the archetype subscriptions in the `CanadaPubSecALZ-main` configuration: Generic, Machine Learning, and Healthcare. You can replace them with partial GUIDs of alternate subscription configurations from a different source environment, or you can leave them as-is to use the subscription configurations provided in the `CanadaPubSecALZ-main` configuration: + - `8422552f`: The Generic subscription from the `CanadaPubSecALZ-main` configuration + - `f881fccb`: One of the Machine Learning subscriptions from the `CanadaPubSecALZ-main` configuration + - `1f519216`: The Healthcare subscription from the `CanadaPubSecALZ-main` configuration + +- The `Subscriptions:` element in the YAML template is a list of subscriptions from an existing source environment that will be used to create corresponding subscriptions in your target (new) environment. You may add or remove (delete or comment out) items in this list as needed. + +Copy the following sample into your YAML file, and update the values to suit your implementation. The values you provide will be used to create the configuration files for your environment(s). + +```yaml +Environment: + Source: CanadaPubSecALZ-main + Target: + +DeployRegion: canadacentral + +ManagementGroupHierarchy: + name: Tenant Root Group + id: 10000000-0000-0000-0000-000000000000 + children: + - name: Azure Landing Zones for Canadian Public Sector + id: pubsec + children: + - name: Platform + id: Platform + children: + - name: Management + id: Management + children: [] + - name: Connectivity + id: Connectivity + children: [] + - name: Identity + id: Identity + children: [] + - name: LandingZones + id: LandingZones + children: + - name: DevTest + id: DevTest + children: [] + - name: QA + id: QA + children: [] + - name: Prod + id: Prod + children: [] + - name: Sandbox + id: Sandbox + children: [] + +Logging: + SubscriptionId: 20000000-0000-0000-0000-000000000000 + ManagementGroupId: Management + SecurityCenter: + email: 'security@example.com' + phone: '6135555555' + ServiceHealthAlerts: + resourceGroupName: service-health-alerts-rg + incidentTypes: ['Incident', 'Security'] + regions: ['Global', 'Canada Central', 'Canada East'] + receivers: + app: ['logging@example.com'] + email: ['logging@example.com'] + sms: [{ countryCode: '1', phoneNumber: '6135555555' }] + voice: [{ countryCode: '1', phoneNumber: '6135555555' }] + actionGroupName: 'Logging Alerts' + actionGroupShortName: 'logging-ag' + alertRuleName: 'Logging Alerts' + alertRuleDescription: 'Logging Alerts for Incidents and Security' + RoleAssignments: + - comments: 'Built-in Contributor Role' + roleDefinitionId: 'b24988ac-6180-42a0-ab88-20f7382dd24c' + securityGroupObjectIds: ['00000000-1000-0000-0000-000000000000'] + # SubscriptionTags: + # ISSO: isso-tag + # ResourceTags: + # ClientOrganization: client-organization-tag + # CostCenter: cost-center-tag + # DataSensitivity: data-sensitivity-tag + # ProjectContact: project-contact-tag + # ProjectName: project-name-tag + # TechnicalContact: technical-contact-tag + DataCollectionRule: + Enabled: false + +HubNetwork: + SubscriptionId: 30000000-0000-0000-0000-000000000000 + ManagementGroupId: Connectivity + SecurityCenter: + email: 'security@example.com' + phone: '6135555555' + ServiceHealthAlerts: + resourceGroupName: service-health-alerts-rg + incidentTypes: ['Incident', 'Security'] + regions: ['Global', 'Canada Central', 'Canada East'] + receivers: + app: ['networking@example.com'] + email: ['networking@example.com'] + sms: [{ countryCode: '1', phoneNumber: '6135555555' }] + voice: [{ countryCode: '1', phoneNumber: '6135555555' }] + actionGroupName: 'Networking Alerts' + actionGroupShortName: 'network-ag' + alertRuleName: 'Networking Alerts' + alertRuleDescription: 'Networking Alerts for Incidents and Security' + RoleAssignments: + - comments: 'Built-in Contributor Role' + roleDefinitionId: 'b24988ac-6180-42a0-ab88-20f7382dd24c' + securityGroupObjectIds: ['00000000-2000-0000-0000-000000000000'] + # SubscriptionTags: + # ISSO: isso-tag + # ResourceTags: + # ClientOrganization: client-organization-tag + # CostCenter: cost-center-tag + # DataSensitivity: data-sensitivity-tag + # ProjectContact: project-contact-tag + # ProjectName: project-name-tag + # TechnicalContact: technical-contact-tag + PrivateDNS: + enabled: true + resourceGroupName: private-dns-rg + DDoS: + # https://learn.microsoft.com/azure/ddos-protection/ddos-faq#are-services-unsafe-in-azure-without-the-service- + enabled: false + resourceGroupName: ddos-rg + planName: ddos-plan + +Identity: + SubscriptionId: 40000000-0000-0000-0000-000000000000 + ManagementGroupId: Identity + SecurityCenter: + email: 'security@example.com' + phone: '6135555555' + ServiceHealthAlerts: + resourceGroupName: service-health-alerts-rg + incidentTypes: ['Incident', 'Security'] + regions: ['Global', 'Canada Central', 'Canada East'] + receivers: + app: ['identity@example.com'] + email: ['identity@example.com'] + sms: [{ countryCode: '1', phoneNumber: '6135555555' }] + voice: [{ countryCode: '1', phoneNumber: '6135555555' }] + actionGroupName: 'Identity Alerts' + actionGroupShortName: 'identity-ag' + alertRuleName: 'Identity Alerts' + alertRuleDescription: 'Identity Alerts for Incidents and Security' + RoleAssignments: + - comments: 'Built-in Contributor Role' + roleDefinitionId: 'b24988ac-6180-42a0-ab88-20f7382dd24c' + securityGroupObjectIds: ['00000000-3000-0000-0000-000000000000'] + # SubscriptionTags: + # ISSO: isso-tag + # ResourceTags: + # ClientOrganization: client-organization-tag + # CostCenter: cost-center-tag + # DataSensitivity: data-sensitivity-tag + # ProjectContact: project-contact-tag + # ProjectName: project-name-tag + # TechnicalContact: technical-contact-tag + +Subscriptions: +- '8422552f': # Generic subscription ID prefix from {$Environment.Source} + SubscriptionId: 70000000-0000-0000-0000-000000000000 + ManagementGroupId: DevTest + Location: canadacentral + SecurityCenter: + email: 'security@example.com' + phone: '6135555555' + ServiceHealthAlerts: + resourceGroupName: service-health-alerts-rg + incidentTypes: ['Incident', 'Security'] + regions: ['Global', 'Canada Central', 'Canada East'] + receivers: + app: ['subscription-owners@example.com'] + email: ['subscription-owners@example.com'] + sms: [{ countryCode: '1', phoneNumber: '6135555555' }] + voice: [{ countryCode: '1', phoneNumber: '6135555555' }] + actionGroupName: 'Subscription Owners Alerts' + actionGroupShortName: 'sub-own-ag' + alertRuleName: 'Subscription Owners Alerts' + alertRuleDescription: 'Subscription Owners Alerts for Incidents and Security' + RoleAssignments: + - comments: 'Built-in Contributor Role' + roleDefinitionId: 'b24988ac-6180-42a0-ab88-20f7382dd24c' + securityGroupObjectIds: ['00000000-4000-0000-0000-000000000000'] + - comments: 'Custom Role: Landing Zone Application Owner' + roleDefinitionId: 'b4c87314-c1a1-5320-9c43-779585186bcc' + securityGroupObjectIds: ['00000000-5000-0000-0000-000000000000'] + # SubscriptionTags: + # ISSO: isso-tag + # ResourceTags: + # ClientOrganization: client-organization-tag + # CostCenter: cost-center-tag + # DataSensitivity: data-sensitivity-tag + # ProjectContact: project-contact-tag + # ProjectName: project-name-tag + # TechnicalContact: technical-contact-tag + +- 'f881fccb': # Machine Learning 1 subscription ID prefix from {$Environment.Source} + SubscriptionId: 80000000-0000-0000-0000-000000000000 + ManagementGroupId: DevTest + Location: canadacentral + SecurityCenter: + email: 'security@example.com' + phone: '6135555555' + ServiceHealthAlerts: + resourceGroupName: service-health-alerts-rg + incidentTypes: ['Incident', 'Security'] + regions: ['Global', 'Canada Central', 'Canada East'] + receivers: + app: ['subscription-owners@example.com'] + email: ['subscription-owners@example.com'] + sms: [{ countryCode: '1', phoneNumber: '6135555555' }] + voice: [{ countryCode: '1', phoneNumber: '6135555555' }] + actionGroupName: 'Subscription Owners Alerts' + actionGroupShortName: 'sub-own-ag' + alertRuleName: 'Subscription Owners Alerts' + alertRuleDescription: 'Subscription Owners Alerts for Incidents and Security' + RoleAssignments: + - comments: 'Built-in Contributor Role' + roleDefinitionId: 'b24988ac-6180-42a0-ab88-20f7382dd24c' + securityGroupObjectIds: ['00000000-6000-0000-0000-000000000000'] + - comments: 'Custom Role: Landing Zone Application Owner' + roleDefinitionId: 'b4c87314-c1a1-5320-9c43-779585186bcc' + securityGroupObjectIds: ['00000000-7000-0000-0000-000000000000'] + # SubscriptionTags: + # ISSO: isso-tag + # ResourceTags: + # ClientOrganization: client-organization-tag + # CostCenter: cost-center-tag + # DataSensitivity: data-sensitivity-tag + # ProjectContact: project-contact-tag + # ProjectName: project-name-tag + # TechnicalContact: technical-contact-tag + +- '1f519216': # Healthcare subscription ID prefix from {$Environment.Source} + SubscriptionId: 90000000-0000-0000-0000-000000000000 + ManagementGroupId: DevTest + Location: canadacentral + SecurityCenter: + email: 'security@example.com' + phone: '6135555555' + ServiceHealthAlerts: + resourceGroupName: service-health-alerts-rg + incidentTypes: ['Incident', 'Security'] + regions: ['Global', 'Canada Central', 'Canada East'] + receivers: + app: ['subscription-owners@example.com'] + email: ['subscription-owners@example.com'] + sms: [{ countryCode: '1', phoneNumber: '6135555555' }] + voice: [{ countryCode: '1', phoneNumber: '6135555555' }] + actionGroupName: 'Subscription Owners Alerts' + actionGroupShortName: 'sub-own-ag' + alertRuleName: 'Subscription Owners Alerts' + alertRuleDescription: 'Subscription Owners Alerts for Incidents and Security' + RoleAssignments: + - comments: 'Built-in Contributor Role' + roleDefinitionId: 'b24988ac-6180-42a0-ab88-20f7382dd24c' + securityGroupObjectIds: ['00000000-8000-0000-0000-000000000000'] + - comments: 'Custom Role: Landing Zone Application Owner' + roleDefinitionId: 'b4c87314-c1a1-5320-9c43-779585186bcc' + securityGroupObjectIds: ['00000000-9000-0000-0000-000000000000'] + # SubscriptionTags: + # ISSO: isso-tag + # ResourceTags: + # ClientOrganization: client-organization-tag + # CostCenter: cost-center-tag + # DataSensitivity: data-sensitivity-tag + # ProjectContact: project-contact-tag + # ProjectName: project-name-tag + # TechnicalContact: technical-contact-tag +``` + +### Creating Configuration Files from a Template + +The next step is to create the configuration files for the target environment. The following command will create a new set of configuration files in the `config` folder, based on the settings in the YAML template file created in the previous section. + +```powershell +PS> $Environment = 'MyAzureDevOpsOrg-main' +PS> .\New-AlzConfiguration.ps1 -Environment $Environment +``` + +Running the `New-AlzConfiguration.ps1` script as shown above will create the new set of configuration files and produce output similar to the following: + +```text +This script creates a new set of configuration files, using an existing CanadaPubSecALZ configuration. Select configuration elements are replaced with values specific to the target environment. + +Reading parameters from file (C:\Users\username\ALZ\config\MyAzureDevOpsOrg-main.yml) +Checking configuration path (P:\CanadaPubSecALZ\CanadaPubSecALZ\config) + Source environment: CanadaPubSecALZ-main + Target environment: MyAzureDevOpsOrg-main + +Generating Variables configurations + + Updating variables configuration + Writing variables configuration file: P:\CanadaPubSecALZ\CanadaPubSecALZ\config/variables/MyAzureDevOpsOrg-main.yml + +Generating Logging configurations + + Reading source environment logging configuration file: P:\CanadaPubSecALZ\CanadaPubSecALZ\config/logging/CanadaPubSecALZ-main/logging.parameters.json + Updating logging configuration + Writing logging configuration file: P:\CanadaPubSecALZ\CanadaPubSecALZ\config/logging/MyAzureDevOpsOrg-main/logging.parameters.json + +Generating Network Azure Firewall configurations + + Reading source environment network Azure Firewall configuration file: P:\CanadaPubSecALZ\CanadaPubSecALZ\config/networking/CanadaPubSecALZ-main/hub-azfw/hub-network.parameters.json + Updating network Azure Firewall configuration + Writing network Azure Firewall configuration file: P:\CanadaPubSecALZ\CanadaPubSecALZ\config/networking/MyAzureDevOpsOrg-main/hub-azfw/hub-network.parameters.json + +Generating Network Azure Firewall Policy configurations + + Reading source environment network Azure Firewall Policy configuration file: P:\CanadaPubSecALZ\CanadaPubSecALZ\config/networking/CanadaPubSecALZ-main/hub-azfw-policy/azure-firewall-policy.parameters.json + Updating network Azure Firewall Policy configuration + Writing network Azure Firewall Policy configuration file: P:\CanadaPubSecALZ\CanadaPubSecALZ\config/networking/MyAzureDevOpsOrg-main/hub-azfw-policy/azure-firewall-policy.parameters.json + +Generating Network NVA configurations + + Reading source environment network NVA configuration file: P:\CanadaPubSecALZ\CanadaPubSecALZ\config/networking/CanadaPubSecALZ-main/hub-nva/hub-network.parameters.json + Updating network NVA configuration + Writing network NVA configuration file: P:\CanadaPubSecALZ\CanadaPubSecALZ\config/networking/MyAzureDevOpsOrg-main/hub-nva/hub-network.parameters.json + +Generating Identity configurations + + Reading source environment identity configuration file: P:\CanadaPubSecALZ\CanadaPubSecALZ\config/identity/CanadaPubSecALZ-main/identity.parameters.json + Updating identity configuration + Writing identity configuration file: P:\CanadaPubSecALZ\CanadaPubSecALZ\config/identity/MyAzureDevOpsOrg-main/identity.parameters.json + +Generating subscription configurations + + Looking for source environment subscription configuration file(s) matching specified pattern (8422552f) + Reading subscription configuration (8422552f-3840-4934-a971-6ee349ffbb05_generic-subscription_canadacentral.json) + Updating subscription configuration + Writing new subscription configuration (P:\CanadaPubSecALZ\CanadaPubSecALZ\config/subscriptions/MyAzureDevOpsOrg-main/DevTest/70000000-0000-0000-0000-000000000000_generic-subscription_canadacentral.json) + + Looking for source environment subscription configuration file(s) matching specified pattern (f881fccb) + Reading subscription configuration (f881fccb-2598-4b9c-b87c-b392f5e16f12_machinelearning_canadacentral.json) + Updating subscription configuration + Writing new subscription configuration (P:\CanadaPubSecALZ\CanadaPubSecALZ\config/subscriptions/MyAzureDevOpsOrg-main/DevTest/80000000-0000-0000-0000-000000000000_machinelearning_canadacentral.json) + + Looking for source environment subscription configuration file(s) matching specified pattern (1f519216) + Reading subscription configuration (1f519216-5e39-4b51-a9b6-10cc2b79b6c7_healthcare_canadacentral.json) + Updating subscription configuration + Writing new subscription configuration (P:\CanadaPubSecALZ\CanadaPubSecALZ\config/subscriptions/MyAzureDevOpsOrg-main/DevTest/90000000-0000-0000-0000-000000000000_healthcare_canadacentral.json) + +Elapsed time: 00:00:00.5295725 +``` + +### Deleting Configuration Files + +If you create a set of configuration files and decide you no longer need them, you can delete them using the `Remove-AlzConfiguration.ps1` script. The following command will delete the configuration files for the target environment. + +```powershell +PS> $Environment = 'MyAzureDevOpsOrg-main' +PS> .\Remove-AlzConfiguration.ps1 -Environment $Environment +``` + +Running the `Remove-AlzConfiguration.ps1` script as shown above will delete the configuration files for the target environment and produce output similar to the following: + +```text +This script removes an existing set of configuration files. + +Checking configuration path (P:\CanadaPubSecALZ\CanadaPubSecALZ\config) +Removing variables configuration file: P:\CanadaPubSecALZ\CanadaPubSecALZ\config/variables/MyAzureDevOpsOrg-main.yml +Removing logging configuration directory: P:\CanadaPubSecALZ\CanadaPubSecALZ\config/logging/MyAzureDevOpsOrg-main +Removing network configuration directory: P:\CanadaPubSecALZ\CanadaPubSecALZ\config/networking/MyAzureDevOpsOrg-main +Removing identity configuration directory: P:\CanadaPubSecALZ\CanadaPubSecALZ\config/identity/MyAzureDevOpsOrg-main +Removing subscription configuration directory: P:\CanadaPubSecALZ\CanadaPubSecALZ\config/subscriptions/MyAzureDevOpsOrg-main + +Elapsed time: 00:00:00.1053294 +``` + +If you have deleted the configuration files for an environment and want to recreate them, you can do so by running the `New-AlzConfiguration.ps1` script as described in the previous section, assuming you have not deleted the source environment configuration files and the YAML template file is still available. + +--- + +## Working with Deployments + +### Deploying a Configuration + +Once you have created a set of configuration files for an environment, you can deploy the configuration using the `New-AlzDeployment.ps1` script. + +>Note: The `New-AlzDeployment.ps1` script will deploy all stages of the specified environment configuration, including: management groups, logging, policies, networking, identity, and subscriptions. If you only want to deploy a subset of the configuration, you can use the `/scripts/deployments/RunWorkflows.ps1` script or invoke the individual Azure DevOps pipelines / GitHub workflows for each stage. + +The following invocation of the `New-AlzDeployment.ps1` script will deploy all stages of the configuration files for the target environment using the previously created credential file and the `AzFW` (Azure Firewall) network hub type: + +```powershell +PS> $Environment = 'MyAzureDevOpsOrg-main' +PS> .\New-AlzDeployment.ps1 -Environment $Environment -CredentialFile $Environment -NetworkType 'AzFW' +``` + +The following invocation of the `New-AlzDeployment.ps1` script will deploy all stages of the configuration files for the target environment using the previously created credential file and the `NVA` (Network Virtual Appliance) network hub type: + +```powershell +PS> $Environment = 'MyAzureDevOpsOrg-main' +PS> .\New-AlzDeployment.ps1 -Environment $Environment -CredentialFile $Environment -NetworkType 'NVA' +``` + +The `.\New-AlzDeployment.ps1` script also provides for alternate authentication methods to the credential file. You may also use a service principal or interactive authentication. + +When you deploy from local configuration files, remember that detailed log output is available in `$HOME/ALZ/logs` (by default) and the log files generated for deployment operations can be very useful for troubleshooting. diff --git a/docs/policy/readme.md b/docs/policy/readme.md index 3524a4e9..9fdeeba0 100644 --- a/docs/policy/readme.md +++ b/docs/policy/readme.md @@ -154,12 +154,12 @@ Parameters can be templated using the syntax `{{PARAMETER_NAME}}`. Following pa | Templated Parameter | Source Value | Example | | --- | --- | --- | -| {{var-topLevelManagementGroupName}} | Environment configuration file such as [config/variables/CanadaESLZ-main.yml](../../config/variables/CanadaESLZ-main.yml) | `pubsec` -| {{var-logging-logAnalyticsWorkspaceResourceId}} | Resource ID is inferred using Log Analytics settings in environment configuration file such as [config/variables/CanadaESLZ-main.yml](../../config/variables/CanadaESLZ-main.yml) | `/subscriptions/bc0a4f9f-07fa-4284-b1bd-fbad38578d3a/resourcegroups/pubsec-central-logging/providers/microsoft.operationalinsights/workspaces/log-analytics-workspace` -| {{var-logging-logAnalyticsWorkspaceId}} | Workspace ID is inferred using Log Analytics settings in environment configuration file such as [config/variables/CanadaESLZ-main.yml](../../config/variables/CanadaESLZ-main.yml) | `fcce3f30-158a-4561-a714-361623f42168` -| {{var-logging-logAnalyticsResourceGroupName}} | Environment configuration file such as [config/variables/CanadaESLZ-main.yml](../../config/variables/CanadaESLZ-main.yml) | `pubsec-central-logging` -| {{var-logging-logAnalyticsRetentionInDays}} | Environment configuration file such as [config/variables/CanadaESLZ-main.yml](../../config/variables/CanadaESLZ-main.yml) | `730` -| {{var-logging-diagnosticSettingsforNetworkSecurityGroupsStoragePrefix}} | Environment configuration file such as [config/variables/CanadaESLZ-main.yml](../../config/variables/CanadaESLZ-main.yml) | `pubsecnsg` +| {{var-topLevelManagementGroupName}} | Environment configuration file such as [config/variables/CanadaPubSecALZ-main.yml](../../config/variables/CanadaPubSecALZ-main.yml) | `pubsec` +| {{var-logging-logAnalyticsWorkspaceResourceId}} | Resource ID is inferred using Log Analytics settings in environment configuration file such as [config/variables/CanadaPubSecALZ-main.yml](../../config/variables/CanadaPubSecALZ-main.yml) | `/subscriptions/bc0a4f9f-07fa-4284-b1bd-fbad38578d3a/resourcegroups/pubsec-central-logging/providers/microsoft.operationalinsights/workspaces/log-analytics-workspace` +| {{var-logging-logAnalyticsWorkspaceId}} | Workspace ID is inferred using Log Analytics settings in environment configuration file such as [config/variables/CanadaPubSecALZ-main.yml](../../config/variables/CanadaPubSecALZ-main.yml) | `fcce3f30-158a-4561-a714-361623f42168` +| {{var-logging-logAnalyticsResourceGroupName}} | Environment configuration file such as [config/variables/CanadaPubSecALZ-main.yml](../../config/variables/CanadaPubSecALZ-main.yml) | `pubsec-central-logging` +| {{var-logging-logAnalyticsRetentionInDays}} | Environment configuration file such as [config/variables/CanadaPubSecALZ-main.yml](../../config/variables/CanadaPubSecALZ-main.yml) | `730` +| {{var-logging-diagnosticSettingsforNetworkSecurityGroupsStoragePrefix}} | Environment configuration file such as [config/variables/CanadaPubSecALZ-main.yml](../../config/variables/CanadaPubSecALZ-main.yml) | `pubsecnsg` | {{var-policyAssignmentManagementGroupId}} | The management group scope for policy assignment. | `pubsec` --- diff --git a/roles/la-vminsights-readonly.bicep b/roles/la-vminsights-readonly.bicep index ab466460..ce892a7c 100644 --- a/roles/la-vminsights-readonly.bicep +++ b/roles/la-vminsights-readonly.bicep @@ -34,7 +34,7 @@ resource roleDefn 'Microsoft.Authorization/roleDefinitions@2018-01-01-preview' = actions: [ 'Microsoft.operationalinsights/workspaces/features/generateMap/read' 'Microsoft.operationalinsights/workspaces/features/servergroups/members/read' - 'Microsoft.operationalinsights/workspaces/features/clientgroups/memebers/read' + 'Microsoft.operationalinsights/workspaces/features/clientgroups/members/read' 'Microsoft.operationalinsights/workspaces/features/machineGroups/read' 'Microsoft.OperationalInsights/workspaces/query/VMBoundPort/read' 'Microsoft.OperationalInsights/workspaces/query/VMComputer/read' diff --git a/scripts/configuration/Connect-AlzCredential.ps1 b/scripts/configuration/Connect-AlzCredential.ps1 new file mode 100644 index 00000000..277b6958 --- /dev/null +++ b/scripts/configuration/Connect-AlzCredential.ps1 @@ -0,0 +1,70 @@ +<# +---------------------------------------------------------------------------------- +Copyright (c) Microsoft Corporation. +Licensed under the MIT license. + +THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, +EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. +---------------------------------------------------------------------------------- +#> + +<# + .SYNOPSIS + This script connects to Azure using a service principal stored in a credential file, a service principal stored in a SecureString, or interactively. + + .DESCRIPTION + This script connects to Azure using a service principal stored in a credential file, a service principal stored in a SecureString, or interactively. + + .PARAMETER CredentialFile + The path to the credential file to use for login. + + .PARAMETER SecureServicePrincipal + The service principal to use for login. + + .PARAMETER TenantId + The tenant ID to use for interactive login. + + .EXAMPLE + PS> .\Connect-AlzCredential.ps1 -CredentialFile '$HOME/CanadaALZ.json' + + .EXAMPLE + PS> .\Connect-AlzCredential.ps1 -SecureServicePrincipal $SecureSP + + .EXAMPLE + PS> .\Connect-AlzCredential.ps1 -TenantId '00000000-0000-0000-0000-000000000000' +#> + +[CmdletBinding()] +Param( + [Parameter(Mandatory = $true, ParameterSetName = "CredentialFile")] + [string]$CredentialFile, + + [Parameter(Mandatory = $true, ParameterSetName = "ServicePrincipal")] + [SecureString]$SecureServicePrincipal, + + [Parameter(Mandatory = $true, ParameterSetName = "Interactive")] + [string]$TenantId +) + +switch ($PSCmdlet.ParameterSetName) { + "CredentialFile" { + $ServicePrincipalCredentials = Get-Content -Raw -Path $CredentialFile + $SecureSP = ConvertTo-SecureString -String $ServicePrincipalCredentials -AsPlainText -Force + .\Connect-AlzCredential.ps1 -SecureServicePrincipal $SecureSP + } + "ServicePrincipal" { + Write-Output "Logging in to Azure using service principal..." + $ServicePrincipal = ($SecureServicePrincipal | ConvertFrom-SecureString -AsPlainText) | ConvertFrom-Json + $Password = ConvertTo-SecureString $ServicePrincipal.password -AsPlainText -Force + $Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $ServicePrincipal.appId, $Password + Connect-AzAccount -ServicePrincipal -TenantId $ServicePrincipal.tenant -Credential $Credential + } + "Interactive" { + $context = Get-AzContext + if ($context -eq $null) { + Write-Output "Logging in to Azure using interactive login..." + Connect-AzAccount -Tenant $TenantId + } + } +} diff --git a/scripts/configuration/Get-AlzConfiguration.ps1 b/scripts/configuration/Get-AlzConfiguration.ps1 new file mode 100644 index 00000000..301c63ef --- /dev/null +++ b/scripts/configuration/Get-AlzConfiguration.ps1 @@ -0,0 +1,55 @@ +<# +---------------------------------------------------------------------------------- +Copyright (c) Microsoft Corporation. +Licensed under the MIT license. + +THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, +EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. +---------------------------------------------------------------------------------- +#> + +<# + .SYNOPSIS + This script gets the main YAML configuration for a CanadaPubSecALZ deployment. + + .DESCRIPTION + This script gets the main YAML configuration for a CanadaPubSecALZ deployment. + + .PARAMETER Environment + The name of the environment. + + .PARAMETER RepoRootPath + The path to the repository directory. + + .PARAMETER ConfigVariablesByRef + The reference to the configuration variables hashtable. + + .EXAMPLE + PS> $ConfigVariablesYaml = @{} + PS> .\Get-AlzConfiguration.ps1 -Environment 'CanadaALZ-main' -ConfigVariablesByRef ([ref]$ConfigVariablesYaml) +#> + +[CmdletBinding()] +Param( + [Parameter(Mandatory = $true)] + [string]$Environment, + + [string]$RepoRootPath = "../..", + + [ref]$ConfigVariablesByRef +) + +#Requires -Modules powershell-yaml + +$ErrorActionPreference = "Stop" + +$RepoConfigPath = (Resolve-Path -Path "$RepoRootPath/config/variables/$Environment.yml").Path + +Write-Output "Getting environment configuration ($RepoConfigPath)" + +if (Test-Path -PathType Leaf -Path $RepoConfigPath) { + $ConfigVariablesByRef.value = Get-Content -Path $RepoConfigPath -Raw | ConvertFrom-Yaml +} else { + throw "Environment file not found ($RepoConfigPath)" +} diff --git a/scripts/configuration/Get-AlzSubscriptions.ps1 b/scripts/configuration/Get-AlzSubscriptions.ps1 new file mode 100644 index 00000000..0e9f9c9d --- /dev/null +++ b/scripts/configuration/Get-AlzSubscriptions.ps1 @@ -0,0 +1,55 @@ +<# +---------------------------------------------------------------------------------- +Copyright (c) Microsoft Corporation. +Licensed under the MIT license. + +THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, +EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. +---------------------------------------------------------------------------------- +#> + +<# + .SYNOPSIS + This script gets an array of subscription ids for a CanadaPubSecALZ deployment. + + .DESCRIPTION + This script gets an array of subscription ids for a CanadaPubSecALZ deployment. + + .PARAMETER Environment + The name of the environment. + + .PARAMETER RepoRootPath + The path to the repository directory. + + .PARAMETER SubscriptionIdsByRef + The reference to the subscription IDs array. + + .EXAMPLE + PS> $SubscriptionIds = @() + PS> .\Get-AlzSubscriptions.ps1 -Environment 'CanadaALZ-main' -SubscriptionIdsByRef ([ref]$SubscriptionIds) +#> + +[CmdletBinding()] +Param( + [Parameter(Mandatory = $true)] + [string]$Environment, + + [string]$RepoRootPath = "../..", + + [ref]$SubscriptionIdsByRef +) + +$ErrorActionPreference = "Stop" + +Write-Output "Getting subscription configurations for environment ($Environment)" + +$SubscriptionIdsByRef.value = @() + +$Pattern = "^[\da-fA-F]{8}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{12}(_.*)(_.*)?\.json" + +$Subscriptions = @(Get-ChildItem -Path "$RepoRootPath/config/subscriptions/$Environment" -File -Recurse | ? { $_.Name -match $Pattern }) + +foreach ($Subscription in $Subscriptions) { + $SubscriptionIdsByRef.value += $Subscription.Name.Split('_')[0] +} diff --git a/scripts/configuration/Install-Prerequisites.ps1 b/scripts/configuration/Install-Prerequisites.ps1 new file mode 100644 index 00000000..aef06f5e --- /dev/null +++ b/scripts/configuration/Install-Prerequisites.ps1 @@ -0,0 +1,14 @@ +<# +---------------------------------------------------------------------------------- +Copyright (c) Microsoft Corporation. +Licensed under the MIT license. + +THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, +EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. +---------------------------------------------------------------------------------- +#> + +Install-Module Az -Repository PSGallery -Force +Install-Module powershell-yaml -Repository PSGallery -Force +Install-Module PSPasswordGenerator -Repository PSGallery -Force diff --git a/scripts/configuration/New-AlzConfiguration.ps1 b/scripts/configuration/New-AlzConfiguration.ps1 new file mode 100644 index 00000000..d6089dec --- /dev/null +++ b/scripts/configuration/New-AlzConfiguration.ps1 @@ -0,0 +1,475 @@ +<# +---------------------------------------------------------------------------------- +Copyright (c) Microsoft Corporation. +Licensed under the MIT license. + +THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, +EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. +---------------------------------------------------------------------------------- +#> + +<# + .SYNOPSIS + Creates a new configuration for the CanadaPubSecALZ deployment. + + .DESCRIPTION + This script creates a new set of configuration files, using an existing CanadaPubSecALZ configuration. Select configuration elements are replaced with values specific to the target environment. + + .PARAMETER Environment + The base name of the YAML environment configuration file. + + .PARAMETER SourceEnvironment + The name of the source environment. If not specified, the source environment attribute in the environment configuration file is used. If the environment configuration file does not specify a source environment, the environment configuration file base name is used. + + .PARAMETER TargetEnvironment + The name of the target environment. If not specified, the target environment attribute in the environment configuration file is used. If the environment configuration file does not specify a target environment, the environment configuration file base name is used. + + .PARAMETER RepoRootPath + The path to the repository directory. Defaults to ../.. + + .PARAMETER Force + If specified, the script will overwrite existing configuration files. + + .PARAMETER UserRootPath + The path to the user directory. Defaults to $HOME. + + .PARAMETER UserLogsPath + The path to the user logs directory. Defaults to $UserRootPath/ALZ/logs. + + .PARAMETER UserCredsPath + The path to the user credentials directory. Defaults to $UserRootPath/ALZ/credentials. + + .PARAMETER UserConfigPath + The path to the user configuration directory. Defaults to $UserRootPath/ALZ/config. + + .EXAMPLE + PS> .\New-AlzConfiguration.ps1 -Environment 'CanadaALZ-main' + + .EXAMPLE + PS> .\New-AlzConfiguration.ps1 -Environment 'CanadaALZ-main' -Force +#> + +[CmdletBinding()] +Param( + [Parameter(Mandatory = $true)] + [string]$Environment, + + [string]$SourceEnvironment = $null, + + [string]$TargetEnvironment = $null, + + [string]$RepoRootPath = "../..", + + [switch]$Force = $false, + + [string]$UserRootPath = "$HOME", + + [string]$UserLogsPath = "$UserRootPath/ALZ/logs", + + [string]$UserCredsPath = "$UserRootPath/ALZ/credentials", + + [string]$UserConfigPath = "$UserRootPath/ALZ/config" +) + +#Requires -Modules powershell-yaml + +$ErrorActionPreference = "Stop" + +function ValidateParameters { + param ( + [Parameter(Mandatory = $true)] + [object]$Parameters, + [Parameter(Mandatory = $true)] + [string]$ParameterFile + ) + Write-Output "Checking configuration path ($RepoConfigPath)" + if (-not (Test-Path -PathType Container -Path $RepoConfigPath)) { + throw "Configuration path does not exist." + } + + # How we determine the source environment name: + # 1. Use the '$SourceEnvironment' parameter if specified + # 2. Otherwise, use the 'Environment.Source' attribute in the parameter file if specified + # 3. Otherwise, use the parameter file (base) name + if (-not ([string]::IsNullOrEmpty($SourceEnvironment))) { + $Parameters.Environment.Source = $SourceEnvironment + } elseif (-not ([string]::IsNullOrEmpty($Parameters.Environment.Source))) { + $Parameters.Environment.Source = $Parameters.Environment.Source + } else { + $Parameters.Environment.Source = $ParameterFile | Split-Path -LeafBase + } + + # How we determine the target environment name: + # 1. Use the '$TargetEnvironment' parameter if specified + # 2. Otherwise, use the 'Environment.Target' attribute in the parameter file if specified + # 3. Otherwise, use the parameter file (base) name + if (-not ([string]::IsNullOrEmpty($TargetEnvironment))) { + $Parameters.Environment.Target = $TargetEnvironment + } elseif (-not ([string]::IsNullOrEmpty($Parameters.Environment.Target))) { + $Parameters.Environment.Target = $Parameters.Environment.Target + } else { + $Parameters.Environment.Target = $ParameterFile | Split-Path -LeafBase + } + + if ($Parameters.Environment.Source -eq $Parameters.Environment.Target) { + throw "Source ($Parameters.Environment.Source) and target ($Parameters.Environment.Target) environments cannot be the same." + } + + if (-not (Test-Path -PathType Leaf -Path "$RepoConfigPath/variables/$($Parameters.Environment.Source).yml")) { + throw "Source environment does not exist ($($Parameters.Environment.Source))" + } else { + Write-Output " Source environment: $($Parameters.Environment.Source)" + } + + if ((Test-Path -PathType Leaf -Path "$RepoConfigPath/variables/$($Parameters.Environment.Target).yml") -and (-not $Force)) { + throw "Target environment already exists ($($Parameters.Environment.Target)). Use the '-Force' parameter to overwrite it." + } else { + Write-Output " Target environment: $($Parameters.Environment.Target)" + } +} + +function VariablesConfiguration { + param ( + [Parameter(Mandatory = $true)] + [object]$Parameters, + [ref]$ConfigVariablesByRef + ) + Write-Output "" + Write-Output "Generating Variables configurations" + Write-Output "" + + $file = "$RepoConfigPath/variables/$($Parameters.Environment.Source).yml" + if (Test-Path -PathType Leaf -Path $file) { + $ConfigVariablesByRef.value = Get-Content -Path $file -Raw | ConvertFrom-Yaml + } else { + throw "Source environment file not found ($file)" + } + + Write-Output " Updating variables configuration" + + # Deployment variables + $ConfigVariablesByRef.value.variables['deploymentRegion'] = $Parameters.DeployRegion ?? $ConfigVariablesByRef.value.variables['deploymentRegion'] + + # Management Group Hierarchy variables + $ConfigVariablesByRef.value.variables['var-managementgroup-hierarchy'] = ($Parameters.ManagementGroupHierarchy | ConvertTo-Json -Depth 100) ?? $ConfigVariablesByRef.value.variables['var-managementgroup-hierarchy'] + + # Logging variables + $ConfigVariablesByRef.value.variables['var-logging-region'] = $Parameters.DeployRegion ?? $ConfigVariablesByRef.value.variables['var-logging-region'] + $ConfigVariablesByRef.value.variables['var-logging-managementGroupId'] = $Parameters.Logging.ManagementGroupId ?? $ConfigVariablesByRef.value.variables['var-logging-managementGroupId'] + $ConfigVariablesByRef.value.variables['var-logging-subscriptionId'] = $Parameters.Logging.SubscriptionId ?? $ConfigVariablesByRef.value.variables['var-logging-subscriptionId'] + $ConfigVariablesByRef.value.variables['var-logging-diagnosticSettingsforNetworkSecurityGroupsStoragePrefix'] = $Parameters.ManagementGroupHierarchy.children[0].id + 'nsg' + + # Identity variables + $ConfigVariablesByRef.value.variables['var-identity-region'] = $Parameters.DeployRegion ?? $ConfigVariablesByRef.value.variables['var-identity-region'] + $ConfigVariablesByRef.value.variables['var-identity-managementGroupId'] = $Parameters.Identity.ManagementGroupId ?? $ConfigVariablesByRef.value.variables['var-identity-managementGroupId'] + $ConfigVariablesByRef.value.variables['var-identity-subscriptionId'] = $Parameters.Identity.SubscriptionId ?? $ConfigVariablesByRef.value.variables['var-identity-subscriptionId'] + + # Hub Network variables + $ConfigVariablesByRef.value.variables['var-hubnetwork-region'] = $Parameters.DeployRegion ?? $ConfigVariablesByRef.value.variables['var-hubnetwork-region'] + $ConfigVariablesByRef.value.variables['var-hubnetwork-managementGroupId'] = $Parameters.HubNetwork.ManagementGroupId ?? $ConfigVariablesByRef.value.variables['var-hubnetwork-managementGroupId'] + $ConfigVariablesByRef.value.variables['var-hubnetwork-subscriptionId'] = $Parameters.HubNetwork.SubscriptionId ?? $ConfigVariablesByRef.value.variables['var-hubnetwork-subscriptionId'] + + # Write the variables configuration file + $ConfigVariablesFile = "$RepoConfigPath/variables/$($Parameters.Environment.Target).yml" + Write-Output " Writing variables configuration file: $ConfigVariablesFile" + New-Item -ItemType Directory -Path (Split-Path -Parent -Path $ConfigVariablesFile) -Force | Out-Null + $ConfigVariablesYaml | ConvertTo-Yaml | Set-Content -Path $ConfigVariablesFile | Out-Null +} + +function LoggingConfiguration { + param ( + [Parameter(Mandatory = $true)] + [object]$Parameters, + [Parameter(Mandatory = $true)] + [object]$ConfigVariablesYaml + ) + Write-Output "" + Write-Output "Generating Logging configurations" + Write-Output "" + + $file = "$RepoConfigPath/logging/$($Parameters.Environment.Source)/$($ConfigVariablesYaml.variables['var-logging-configurationFileName'])" + if (Test-Path -PathType Leaf -Path $file) { + Write-Output " Reading source environment logging configuration file: $file" + $ConfigLoggingJson = Get-Content -Path $file -Raw | ConvertFrom-Json + + Write-Output " Updating logging configuration" + $ConfigLoggingJson.{$schema} = 'https://raw.githubusercontent.com/Azure/CanadaPubSecALZ/main/schemas/latest/landingzones/lz-platform-logging.json#' + $ConfigLoggingJson.parameters.securityCenter.value = $Parameters.Logging.SecurityCenter ?? $ConfigLoggingJson.parameters.securityCenter.value + $ConfigLoggingJson.parameters.serviceHealthAlerts.value = $Parameters.Logging.ServiceHealthAlerts ?? $ConfigLoggingJson.parameters.serviceHealthAlerts.value + $ConfigLoggingJson.parameters.subscriptionRoleAssignments.value = $Parameters.Logging.RoleAssignments ?? $ConfigLoggingJson.parameters.subscriptionRoleAssignments.value + $ConfigLoggingJson.parameters.subscriptionTags.value = $Parameters.values.Logging.SubscriptionTags ?? $ConfigLoggingJson.parameters.subscriptionTags.value + $ConfigLoggingJson.parameters.resourceTags.value = $Parameters.values.Logging.ResourceTags ?? $ConfigLoggingJson.parameters.resourceTags.value + $ConfigLoggingJson.parameters.dataCollectionRule.value.enabled = $Parameters.Logging.DataCollectionRule.Enabled ?? $ConfigLoggingJson.parameters.dataCollectionRule.value.enabled + + $ConfigLoggingFile = "$RepoConfigPath/logging/$($Parameters.Environment.Target)/$($ConfigVariablesYaml.variables['var-logging-configurationFileName'])" + Write-Output " Writing logging configuration file: $ConfigLoggingFile" + New-Item -ItemType Directory -Path (Split-Path -Parent -Path $ConfigLoggingFile) -Force | Out-Null + $ConfigLoggingJson | ConvertTo-Json -Depth 100 | Set-Content -Path $ConfigLoggingFile | Out-Null + } else { + Write-Output " Source environment logging configuration file not found: $file" + } +} + +function NetworkAzfwConfiguration { + param ( + [Parameter(Mandatory = $true)] + [object]$Parameters, + [Parameter(Mandatory = $true)] + [object]$ConfigVariablesYaml, + [ref]$ConfigNetworkAzfwByRef + ) + Write-Output "" + Write-Output "Generating Network Azure Firewall configurations" + Write-Output "" + + $file = "$RepoConfigPath/networking/$($Parameters.Environment.Source)/$($ConfigVariablesYaml.variables['var-hubnetwork-azfw-configurationFileName'])" + if (Test-Path -PathType Leaf -Path $file) { + Write-Output " Reading source environment network Azure Firewall configuration file: $file" + $ConfigNetworkAzfwByRef.value = Get-Content -Path $file -Raw | ConvertFrom-Json + + Write-Output " Updating network Azure Firewall configuration" + $ConfigNetworkAzfwByRef.value.{$schema} = 'https://raw.githubusercontent.com/Azure/CanadaPubSecALZ/main/schemas/latest/landingzones/lz-platform-connectivity-hub-azfw.json#' + $ConfigNetworkAzfwByRef.value.parameters.securityCenter.value = $Parameters.HubNetwork.SecurityCenter ?? $ConfigNetworkAzfwByRef.value.parameters.securityCenter.value + $ConfigNetworkAzfwByRef.value.parameters.serviceHealthAlerts.value = $Parameters.HubNetwork.ServiceHealthAlerts ?? $ConfigNetworkAzfwByRef.value.parameters.serviceHealthAlerts.value + $ConfigNetworkAzfwByRef.value.parameters.subscriptionRoleAssignments.value = $Parameters.HubNetwork.RoleAssignments ?? $ConfigNetworkAzfwByRef.value.parameters.subscriptionRoleAssignments.value + $ConfigNetworkAzfwByRef.value.parameters.subscriptionTags.value = $Parameters.values.HubNetwork.SubscriptionTags ?? $ConfigNetworkAzfwByRef.value.parameters.subscriptionTags.value + $ConfigNetworkAzfwByRef.value.parameters.resourceTags.value = $Parameters.values.HubNetwork.ResourceTags ?? $ConfigNetworkAzfwByRef.value.parameters.resourceTags.value + $ConfigNetworkAzfwByRef.value.parameters.privateDnsZones.value = $Parameters.HubNetwork.PrivateDNS ?? $ConfigNetworkAzfwByRef.value.parameters.privateDnsZones.value + $ConfigNetworkAzfwByRef.value.parameters.ddosStandard.value = $Parameters.HubNetwork.DDoS ?? $ConfigNetworkAzfwByRef.value.parameters.ddosStandard.value + + $ConfigNetworkAzfwFile = "$RepoConfigPath/networking/$($Parameters.Environment.Target)/$($ConfigVariablesYaml.variables['var-hubnetwork-azfw-configurationFileName'])" + Write-Output " Writing network Azure Firewall configuration file: $ConfigNetworkAzfwFile" + New-Item -ItemType Directory -Path (Split-Path -Parent -Path $ConfigNetworkAzfwFile) -Force | Out-Null + $ConfigNetworkAzfwByRef.value | ConvertTo-Json -Depth 100 | Set-Content -Path $ConfigNetworkAzfwFile | Out-Null + } else { + Write-Output " Source environment network Azure Firewall configuration file not found: $file" + } +} + +function NetworkAzfwPolicyConfiguration { + param ( + [Parameter(Mandatory = $true)] + [object]$Parameters, + [Parameter(Mandatory = $true)] + [object]$ConfigVariablesYaml + ) + Write-Output "" + Write-Output "Generating Network Azure Firewall Policy configurations" + Write-Output "" + + $file = "$RepoConfigPath/networking/$($Parameters.Environment.Source)/$($ConfigVariablesYaml.variables['var-hubnetwork-azfwPolicy-configurationFileName'])" + if (Test-Path -PathType Leaf -Path $file) { + Write-Output " Reading source environment network Azure Firewall Policy configuration file: $file" + $ConfigNetworkAzfwPolicyJson = Get-Content -Path $file -Raw | ConvertFrom-Json + + Write-Output " Updating network Azure Firewall Policy configuration" + $ConfigNetworkAzfwPolicyJson.{$schema} = 'https://raw.githubusercontent.com/Azure/CanadaPubSecALZ/main/schemas/latest/landingzones/lz-platform-connectivity-hub-azfw-policy.json#' + $ConfigNetworkAzfwPolicyJson.parameters.resourceTags.value = $Parameters.values.HubNetwork.ResourceTags ?? $ConfigNetworkAzfwPolicyJson.parameters.resourceTags.value + + $ConfigNetworkAzfwPolicyFile = "$RepoConfigPath/networking/$($Parameters.Environment.Target)/$($ConfigVariablesYaml.variables['var-hubnetwork-azfwPolicy-configurationFileName'])" + Write-Output " Writing network Azure Firewall Policy configuration file: $ConfigNetworkAzfwPolicyFile" + New-Item -ItemType Directory -Path (Split-Path -Parent -Path $ConfigNetworkAzfwPolicyFile) -Force | Out-Null + $ConfigNetworkAzfwPolicyJson | ConvertTo-Json -Depth 100 | Set-Content -Path $ConfigNetworkAzfwPolicyFile | Out-Null + } else { + Write-Output " Source environment network Azure Firewall Policy configuration file not found: $file" + } +} + +function NetworkNvaConfiguration { + param ( + [Parameter(Mandatory = $true)] + [object]$Parameters, + [Parameter(Mandatory = $true)] + [object]$ConfigVariablesYaml + ) + Write-Output "" + Write-Output "Generating Network NVA configurations" + Write-Output "" + + $file = "$RepoConfigPath/networking/$($Parameters.Environment.Source)/$($ConfigVariablesYaml.variables['var-hubnetwork-nva-configurationFileName'])" + if (Test-Path -PathType Leaf -Path $file) { + Write-Output " Reading source environment network NVA configuration file: $file" + $ConfigNetworkNvaJson = Get-Content -Path $file -Raw | ConvertFrom-Json + + Write-Output " Updating network NVA configuration" + $ConfigNetworkNvaJson.{$schema} = 'https://raw.githubusercontent.com/Azure/CanadaPubSecALZ/main/schemas/latest/landingzones/lz-platform-connectivity-hub-nva.json#' + $ConfigNetworkNvaJson.parameters.securityCenter.value = $Parameters.HubNetwork.SecurityCenter ?? $ConfigNetworkNvaJson.parameters.securityCenter.value + $ConfigNetworkNvaJson.parameters.serviceHealthAlerts.value = $Parameters.HubNetwork.ServiceHealthAlerts ?? $ConfigNetworkNvaJson.parameters.serviceHealthAlerts.value + $ConfigNetworkNvaJson.parameters.subscriptionRoleAssignments.value = $Parameters.HubNetwork.RoleAssignments ?? $ConfigNetworkNvaJson.parameters.subscriptionRoleAssignments.value + $ConfigNetworkNvaJson.parameters.subscriptionTags.value = $Parameters.values.HubNetwork.SubscriptionTags ?? $ConfigNetworkNvaJson.parameters.subscriptionTags.value + $ConfigNetworkNvaJson.parameters.resourceTags.value = $Parameters.values.HubNetwork.ResourceTags ?? $ConfigNetworkNvaJson.parameters.resourceTags.value + $ConfigNetworkNvaJson.parameters.privateDnsZones.value = $Parameters.HubNetwork.PrivateDNS ?? $ConfigNetworkNvaJson.parameters.privateDnsZones.value + $ConfigNetworkNvaJson.parameters.ddosStandard.value = $Parameters.HubNetwork.DDoS ?? $ConfigNetworkNvaJson.parameters.ddosStandard.value + + $ConfigNetworkNvaFile = "$RepoConfigPath/networking/$($Parameters.Environment.Target)/$($ConfigVariablesYaml.variables['var-hubnetwork-nva-configurationFileName'])" + Write-Output " Writing network NVA configuration file: $ConfigNetworkNvaFile" + New-Item -ItemType Directory -Path (Split-Path -Parent -Path $ConfigNetworkNvaFile) -Force | Out-Null + $ConfigNetworkNvaJson | ConvertTo-Json -Depth 100 | Set-Content -Path $ConfigNetworkNvaFile | Out-Null + } else { + Write-Output " Source environment network NVA configuration file not found: $file" + } +} + +function IdentityConfiguration { + param ( + [Parameter(Mandatory = $true)] + [object]$Parameters, + [Parameter(Mandatory = $true)] + [object]$ConfigVariablesYaml + ) + Write-Output "" + Write-Output "Generating Identity configurations" + Write-Output "" + + $file = "$RepoConfigPath/identity/$($Parameters.Environment.Source)/$($ConfigVariablesYaml.variables['var-identity-configurationFileName'])" + if (Test-Path -PathType Leaf -Path $file) { + Write-Output " Reading source environment identity configuration file: $file" + $ConfigIdentityJson = Get-Content -Path $file -Raw | ConvertFrom-Json + + Write-Output " Updating identity configuration" + $ConfigIdentityJson.{$schema} = 'https://raw.githubusercontent.com/Azure/CanadaPubSecALZ/main/schemas/latest/landingzones/lz-platform-identity.json#' + $ConfigIdentityJson.parameters.securityCenter.value = $Parameters.Identity.SecurityCenter ?? $ConfigIdentityJson.parameters.securityCenter.value + $ConfigIdentityJson.parameters.serviceHealthAlerts.value = $Parameters.Identity.ServiceHealthAlerts ?? $ConfigIdentityJson.parameters.serviceHealthAlerts.value + $ConfigIdentityJson.parameters.subscriptionRoleAssignments.value = $Parameters.Identity.RoleAssignments ?? $ConfigIdentityJson.parameters.subscriptionRoleAssignments.value + $ConfigIdentityJson.parameters.subscriptionTags.value = $Parameters.values.Identity.SubscriptionTags ?? $ConfigIdentityJson.parameters.subscriptionTags.value + $ConfigIdentityJson.parameters.resourceTags.value = $Parameters.values.Identity.ResourceTags ?? $ConfigIdentityJson.parameters.resourceTags.value + $ConfigIdentityJson.parameters.hubNetwork.value.virtualNetworkId = "/subscriptions/$($ConfigVariablesYaml.variables['var-hubnetwork-subscriptionId'])/resourceGroups/$($ConfigNetworkAzfwJson.parameters.hub.value.resourceGroupName)/providers/Microsoft.Network/virtualNetworks/$($ConfigNetworkAzfwJson.parameters.hub.value.network.name)" + + $ConfigIdentityFile = "$RepoConfigPath/identity/$($Parameters.Environment.Target)/$($ConfigVariablesYaml.variables['var-identity-configurationFileName'])" + Write-Output " Writing identity configuration file: $ConfigIdentityFile" + New-Item -ItemType Directory -Path (Split-Path -Parent -Path $ConfigIdentityFile) -Force | Out-Null + $ConfigIdentityJson | ConvertTo-Json -Depth 100 | Set-Content -Path $ConfigIdentityFile | Out-Null + } else { + Write-Output " Source environment identity configuration file not found: $file" + } +} + +function SubscriptionConfiguration { + param ( + [Parameter(Mandatory = $true)] + [object]$Parameters, + [object]$ConfigNetworkAzfwJson + ) + Write-Output "" + Write-Output "Generating subscription configurations" + + foreach ($subscription in $Parameters.Subscriptions) { + $pattern = $subscription.keys[0] + + Write-Output "" + Write-Output " Looking for source environment subscription configuration file(s) matching specified pattern ($pattern)" + $templates = @(Get-ChildItem -Path "$RepoConfigPath/subscriptions/$($Parameters.Environment.Source)/*" -File -Recurse | ? { $_.Name -match $pattern }) + if ($templates.Count -gt 0) { + if ($templates.Count -gt 1) { + Write-Output " More than 1 source environment subscription configuration file(s) matching specified pattern found ($pattern); using the first one found" + } + $ConfigSubscriptionFile = $templates[0] + Write-Output " Reading subscription configuration ($($ConfigSubscriptionFile.Name))" + $ConfigSubscriptionJson = Get-Content -Path $ConfigSubscriptionFile.FullName -Raw | ConvertFrom-Json + } else { + Write-Output " Source environment subscription configuration file(s) matching specified pattern not found ($pattern)" + continue + } + + Write-Output " Updating subscription configuration" + $ConfigSubscriptionArchetype = $ConfigSubscriptionFile.Name.Split('_')[1] + $ConfigSubscriptionJson.{$schema} = "https://raw.githubusercontent.com/Azure/CanadaPubSecALZ/main/schemas/latest/landingzones/lz-$($ConfigSubscriptionArchetype).json#" + # Not all subscription configuration files have a location parameter + if ($ConfigSubscriptionJson.parameters.location -ne $null) { + $ConfigSubscriptionJson.parameters.location.value = $subscription.values.Location ?? $ConfigSubscriptionJson.parameters.location.value + } + # Not all subscription configuration files have a privateDnsManagedByHub parameter + if ($ConfigSubscriptionJson.parameters.hubNetwork.value.privateDnsManagedByHub -ne $null) { + $ConfigSubscriptionJson.parameters.hubNetwork.value.privateDnsManagedByHub = $Parameters.HubNetwork.PrivateDNS.Enabled ?? $ConfigSubscriptionJson.parameters.hubNetwork.value.privateDnsManagedByHub + } + # Not all subscription configuration files have a privateDnsManagedByHubSubscriptionId parameter + if ($ConfigSubscriptionJson.parameters.hubNetwork.value.privateDnsManagedByHubSubscriptionId -ne $null) { + $ConfigSubscriptionJson.parameters.hubNetwork.value.privateDnsManagedByHubSubscriptionId = $Parameters.HubNetwork.SubscriptionId ?? $ConfigSubscriptionJson.parameters.hubNetwork.value.privateDnsManagedByHubSubscriptionId + } + # Not all subscription configuration files have a privateDnsManagedByHub parameter + if ($ConfigSubscriptionJson.parameters.hubNetwork.value.privateDnsManagedByHubResourceGroupName -ne $null) { + $ConfigSubscriptionJson.parameters.hubNetwork.value.privateDnsManagedByHubResourceGroupName = $Parameters.HubNetwork.PrivateDNS.ResourceGroupName ?? $ConfigSubscriptionJson.parameters.hubNetwork.value.privateDnsManagedByHubResourceGroupName + } + # All subscription configuration files have the following parameters + $ConfigSubscriptionJson.parameters.securityCenter.value = $subscription.values.SecurityCenter ?? $ConfigSubscriptionJson.parameters.securityCenter.value + $ConfigSubscriptionJson.parameters.serviceHealthAlerts.value = $subscription.values.ServiceHealthAlerts ?? $ConfigSubscriptionJson.parameters.serviceHealthAlerts.value + $ConfigSubscriptionJson.parameters.subscriptionRoleAssignments.value = $subscription.values.RoleAssignments ?? $ConfigSubscriptionJson.parameters.subscriptionRoleAssignments.value + $ConfigSubscriptionJson.parameters.subscriptionTags.value = $subscription.values.SubscriptionTags ?? $ConfigSubscriptionJson.parameters.subscriptionTags.value + $ConfigSubscriptionJson.parameters.resourceTags.value = $subscription.values.ResourceTags ?? $ConfigSubscriptionJson.parameters.resourceTags.value + $ConfigSubscriptionJson.parameters.hubNetwork.value.virtualNetworkId = "/subscriptions/$($ConfigVariablesYaml.variables['var-hubnetwork-subscriptionId'])/resourceGroups/$($ConfigNetworkAzfwJson.parameters.hub.value.resourceGroupName)/providers/Microsoft.Network/virtualNetworks/$($ConfigNetworkAzfwJson.parameters.hub.value.network.name)" + + $NewConfigSubscriptionFile = "$RepoConfigPath/subscriptions/$($Parameters.Environment.Target)/$($subscription.values.ManagementGroupId)/$($subscription.values.SubscriptionId)_$($ConfigSubscriptionArchetype)_$($subscription.values.Location).json" + Write-Output " Writing new subscription configuration ($($NewConfigSubscriptionFile))" + New-Item -ItemType Directory -Path (Split-Path -Parent -Path $NewConfigSubscriptionFile) -Force | Out-Null + $ConfigSubscriptionJson | ConvertTo-Json -Depth 100 | Set-Content -Path $NewConfigSubscriptionFile | Out-Null + } + + Write-Output "" +} + +# Set script variables +$RepoConfigPath = (Resolve-Path -Path "$RepoRootPath/config").Path +$ParameterFile = (Resolve-Path -Path "$UserConfigPath/$Environment.yml").Path + +# Ensure paths exist and are normalized to the OS path format +New-Item -ItemType Directory -Path $UserCredsPath -Force | Out-Null +$UserCredsPath = (Resolve-Path -Path $UserCredsPath).Path +New-Item -ItemType Directory -Path $UserLogsPath -Force | Out-Null +$UserLogsPath = (Resolve-Path -Path $UserLogsPath).Path +New-Item -ItemType Directory -Path $UserConfigPath -Force | Out-Null +$UserConfigPath = (Resolve-Path -Path $UserConfigPath).Path + +# Local variables +$date = Get-Date -Format "yyMMdd-HHmmss-fff" +$script = $(Split-Path -Path $PSCommandPath -LeafBase) +$logFile = "$UserLogsPath/$date-$script-$Environment.log" +$stopWatch = [System.Diagnostics.Stopwatch]::New() + +try { + $stopWatch.Restart() + + Write-Output "" | Tee-Object -FilePath $logFile -Append + Write-Output "This script creates a new set of configuration files, using an existing CanadaPubSecALZ configuration. Select configuration elements are replaced with values specific to the target environment." | Tee-Object -FilePath $logFile -Append + Write-Output "" | Tee-Object -FilePath $logFile -Append + + Write-Output "Reading parameters from file ($ParameterFile)" + if (-not (Test-Path $ParameterFile)) { + throw "Parameter file '$ParameterFile' does not exist." + } + $Parameters = Get-Content $ParameterFile -Raw | ConvertFrom-Yaml + + ValidateParameters -Parameters $Parameters -ParameterFile $ParameterFile ` + | Tee-Object -FilePath $logFile -Append + + $ConfigVariablesYaml = @{} + VariablesConfiguration -Parameters $Parameters -ConfigVariablesByRef ([ref]$ConfigVariablesYaml) ` + | Tee-Object -FilePath $logFile -Append + + LoggingConfiguration -Parameters $Parameters -ConfigVariablesYaml $ConfigVariablesYaml ` + | Tee-Object -FilePath $logFile -Append + + $ConfigNetworkAzfwJson = @{} + NetworkAzfwConfiguration -Parameters $Parameters -ConfigVariablesYaml $ConfigVariablesYaml -ConfigNetworkAzfwByRef ([ref]$ConfigNetworkAzfwJson) ` + | Tee-Object -FilePath $logFile -Append + + NetworkAzfwPolicyConfiguration -Parameters $Parameters -ConfigVariablesYaml $ConfigVariablesYaml ` + | Tee-Object -FilePath $logFile -Append + + NetworkNvaConfiguration -Parameters $Parameters -ConfigVariablesYaml $ConfigVariablesYaml ` + | Tee-Object -FilePath $logFile -Append + + IdentityConfiguration -Parameters $Parameters -ConfigVariablesYaml $ConfigVariablesYaml ` + | Tee-Object -FilePath $logFile -Append + + SubscriptionConfiguration -Parameters $Parameters -ConfigNetworkAzfwJson $ConfigNetworkAzfwJson ` + | Tee-Object -FilePath $logFile -Append + +} catch { + Write-Output $_ | Tee-Object -FilePath $logFile -Append + Write-Output $_.Exception | Tee-Object -FilePath $logFile -Append + throw +} finally { + Write-Output "Elapsed time: $($stopWatch.Elapsed)" ` + | Tee-Object -FilePath $logFile -Append +} diff --git a/scripts/configuration/New-AlzCredential.ps1 b/scripts/configuration/New-AlzCredential.ps1 new file mode 100644 index 00000000..3d9cec56 --- /dev/null +++ b/scripts/configuration/New-AlzCredential.ps1 @@ -0,0 +1,132 @@ +<# +---------------------------------------------------------------------------------- +Copyright (c) Microsoft Corporation. +Licensed under the MIT license. + +THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, +EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. +---------------------------------------------------------------------------------- +#> + +<# + .SYNOPSIS + Creates a Service Principal for the specified environment. + + .DESCRIPTION + Creates a Service Principal for the specified environment. + + .PARAMETER Environment + The name of the environment. This is typically the repo/org name. + + .PARAMETER UserRootPath + The root path for the log, credential, and configuration files. Defaults to $HOME. + + .PARAMETER UserLogsPath + The path for the log files. Defaults to $UserRootPath/ALZ/logs. + + .PARAMETER UserCredsPath + The path for the credential files. Defaults to $UserRootPath/ALZ/credentials. + + .PARAMETER UserConfigPath + The path for the configuration files. Defaults to $UserRootPath/ALZ/config. + + .EXAMPLE + PS> .\New-AlzCredential.ps1 -Environment 'CanadaALZ' + + .EXAMPLE + PS> .\New-AlzCredential.ps1 -Environment 'CanadaALZ' -UserRootPath 'C:\Users\me\ALZ' + + .EXAMPLE + PS> .\New-AlzCredential.ps1 -Environment 'CanadaALZ' -UserLogsPath 'C:\Users\me\ALZ\logs' + + .EXAMPLE + PS> .\New-AlzCredential.ps1 -Environment 'CanadaALZ' -UserCredsPath 'C:\Users\me\ALZ\credentials' + + .EXAMPLE + PS> .\New-AlzCredential.ps1 -Environment 'CanadaALZ' -UserConfigPath 'C:\Users\me\ALZ\config' +#> + +[CmdletBinding()] +Param( + [Parameter(Mandatory = $true)] + [string]$Environment, + + [string]$UserRootPath = "$HOME", + + [string]$UserLogsPath = "$UserRootPath/ALZ/logs", + + [string]$UserCredsPath = "$UserRootPath/ALZ/credentials", + + [string]$UserConfigPath = "$UserRootPath/ALZ/config" +) + +#Requires -Modules Az + +$ErrorActionPreference = "Stop" + +function CreateServicePrincipal { + param( + [string]$Environment = $Environment, + [string]$UserCredsPath = $UserCredsPath + ) + <# Create JSON representation of the service principal using the Azure CLI + if ((az account show) -eq $null) { + throw "You must be logged in to Azure via the Azure CLI to create a service principal." + } + $json = (az ad sp create-for-rbac --name $Environment --role "Owner" --scopes "/") + #> + + # Create JSON representation of the service principal using Azure PowerShell + $context = Get-AzContext + if ($context -eq $null) { + throw "You must be logged in to Azure via Azure PowerShell to create a service principal." + } + + $tenant = Get-AzTenant -TenantId $context.Tenant.Id + Write-Output "Creating Service Principal for environment ($Environment) in tenant ($($tenant.DefaultDomain)))" + $sp = New-AzADServicePrincipal -DisplayName $Environment -Role Owner -Scope "/" + Write-Output " appId: $($sp.AppId)" + Write-Output " displayName: $($sp.DisplayName)" + Write-Output " password: **********" + Write-Output " tenant: $($context.Tenant.Id)" + $json = @{ + appId = $sp.AppId + displayName = $sp.DisplayName + password = $sp.PasswordCredentials.SecretText + tenant = $context.Tenant.Id + } | ConvertTo-Json + + # Save the service principal to a file + $credentialFile = "$UserCredsPath/$Environment.json" + Write-Output "Saving Service Principal to file ($credentialFile)" + Set-Content -Value $json -Path $credentialFile +} + +# Ensure paths exist and are normalized to the OS path format +New-Item -ItemType Directory -Path $UserCredsPath -Force | Out-Null +$UserCredsPath = (Resolve-Path -Path $UserCredsPath).Path +New-Item -ItemType Directory -Path $UserLogsPath -Force | Out-Null +$UserLogsPath = (Resolve-Path -Path $UserLogsPath).Path +New-Item -ItemType Directory -Path $UserConfigPath -Force | Out-Null +$UserConfigPath = (Resolve-Path -Path $UserConfigPath).Path + +# Local variables +$date = Get-Date -Format "yyMMdd-HHmmss-fff" +$script = $(Split-Path -Path $PSCommandPath -LeafBase) +$logFile = "$UserLogsPath/$date-$script-$Environment.log" +$stopWatch = [System.Diagnostics.Stopwatch]::New() + +# Create the service principal +try { + $stopWatch.Restart() + CreateServicePrincipal -Environment $Environment -CredsPath $UserCredsPath ` + | Tee-Object -FilePath $logFile -Append +} catch { + Write-Output $_ | Tee-Object -FilePath $logFile -Append + Write-Output $_.Exception | Tee-Object -FilePath $logFile -Append + throw +} finally { + Write-Output "Elapsed time: $($stopWatch.Elapsed)" ` + | Tee-Object -FilePath $logFile -Append +} diff --git a/scripts/configuration/New-AlzDeployment.ps1 b/scripts/configuration/New-AlzDeployment.ps1 new file mode 100644 index 00000000..6d48ea88 --- /dev/null +++ b/scripts/configuration/New-AlzDeployment.ps1 @@ -0,0 +1,217 @@ +<# +---------------------------------------------------------------------------------- +Copyright (c) Microsoft Corporation. +Licensed under the MIT license. + +THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, +EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. +---------------------------------------------------------------------------------- +#> + +<# + .SYNOPSIS + This script creates a CanadaPubSecALZ deployment, based on information present in the configuration files. + + .DESCRIPTION + This script creates a CanadaPubSecALZ deployment, based on information present in the configuration files. + + .PARAMETER Environment + The name of the environment to deploy. + + .PARAMETER NetworkType + The type of network to deploy. Valid values are "AzFW" and "NVA". Default is "AzFW". + + .PARAMETER CredentialFile + The path to the credential file to use for login. + + .PARAMETER SecureServicePrincipal + The service principal to use for login. + + .PARAMETER TenantId + The tenant ID to use for interactive login. + + .PARAMETER RepoRootPath + The path to the repository directory. + + .PARAMETER UserRootPath + The path to the user directory. + + .PARAMETER UserLogsPath + The path to the user logs directory. + + .PARAMETER UserCredsPath + The path to the user credentials directory. + + .PARAMETER UserConfigPath + The path to the user configuration directory. + + .EXAMPLE + PS> .\New-AlzDeployment.ps1 -Environment 'CanadaALZ-main' -CredentialFile 'CanadaALZ' -NetworkType 'AzFW' + + Deploy the CanadaALZ-main environment with Azure Firewall hub network using a credential file. + + .EXAMPLE + PS> .\New-AlzDeployment.ps1 -Environment 'CanadaALZ-main' -SecureServicePrincipal $SecureSP -NetworkType 'NVA' + + Deploy the CanadaALZ-main environment with NVA hub network using a service principal. +#> + +[CmdletBinding()] +Param( + [Parameter(Mandatory = $true)] + [string]$Environment, + + [Parameter(Mandatory = $true)] + [ValidateSet("AzFW", "NVA")] + [string]$NetworkType, + + [Parameter(Mandatory = $true, ParameterSetName = "CredentialFile")] + [string]$CredentialFile, + + [Parameter(Mandatory = $true, ParameterSetName = "ServicePrincipal")] + [SecureString]$SecureServicePrincipal, + + [Parameter(Mandatory = $true, ParameterSetName = "Interactive")] + [string]$TenantId, + + [string]$RepoRootPath = "../..", + + [string]$UserRootPath = "$HOME", + + [string]$UserLogsPath = "$UserRootPath/ALZ/logs", + + [string]$UserCredsPath = "$UserRootPath/ALZ/credentials", + + [string]$UserConfigPath = "$UserRootPath/ALZ/config" +) + +#Requires -Modules Az, powershell-yaml, PSPasswordGenerator + +$ErrorActionPreference = "Stop" + +#region Functions + +function CreateDeployment { + param( + [string]$Environment, + [string]$RepoRootPath, + [string]$NetworkType, + [string[]]$SubscriptionIds + ) + try { + Push-Location -Path "$RepoRootPath/scripts/deployments" + if ($NetworkType -ieq "AzFW") { + Write-Output "Deploying environment ($Environment) with Azure Firewall" + .\RunWorkflows.ps1 ` + -EnvironmentName $Environment ` + -DeployManagementGroups ` + -DeployRoles ` + -DeployLogging ` + -DeployCustomPolicyDefinitions ` + -DeployCustomPolicySetDefinitions ` + -DeployCustomPolicySetAssignments ` + -DeployBuiltinPolicySetAssignments ` + -DeployAzureFirewallPolicy ` + -DeployHubNetworkWithAzureFirewall ` + -DeployIdentity ` + -DeploySubscriptionIds $SubscriptionIds + } elseif ($NetworkType -ieq "NVA") { + Write-Output "Generating temporary NVA credentials" + $nvaUsername = ConvertTo-SecureString -String ($env:USER ?? $env:USERNAME) -AsPlainText + $nvaPassword = Get-RandomPassword -Length 16 -StartWithLetter + + Write-Output "Deploying environment ($Environment) with NVA firewall" + Write-Output "NVA credentials (save these in a secure location" + Write-Output " Username: $(ConvertFrom-SecureString -SecureString $nvaUsername -AsPlainText)" + Write-Output " Password: $(ConvertFrom-SecureString -SecureString $nvaPassword -AsPlainText)" + + .\RunWorkflows.ps1 ` + -EnvironmentName $Environment ` + -DeployManagementGroups ` + -DeployRoles ` + -DeployLogging ` + -DeployCustomPolicyDefinitions ` + -DeployCustomPolicySetDefinitions ` + -DeployCustomPolicySetAssignments ` + -DeployBuiltinPolicySetAssignments ` + -DeployHubNetworkWithNVA ` + -NvaUserName $nvaUsername ` + -NvaPassword $nvaPassword ` + -DeployIdentity ` + -DeploySubscriptionIds $SubscriptionIds + + } else { + throw "Invalid network type ($NetworkType)" + } + } catch { + throw + } finally { + Pop-Location + } +} + +#endregion Functions + +# Ensure paths exist and are normalized to the OS path format +New-Item -ItemType Directory -Path $UserCredsPath -Force | Out-Null +$UserCredsPath = (Resolve-Path -Path $UserCredsPath).Path +New-Item -ItemType Directory -Path $UserLogsPath -Force | Out-Null +$UserLogsPath = (Resolve-Path -Path $UserLogsPath).Path +New-Item -ItemType Directory -Path $UserConfigPath -Force | Out-Null +$UserConfigPath = (Resolve-Path -Path $UserConfigPath).Path + +# Local variables +$date = Get-Date -Format "yyMMdd-HHmmss-fff" +$script = $(Split-Path -Path $PSCommandPath -LeafBase) +$logFile = "$UserLogsPath/$date-$script-$Environment.log" +$stopWatch = [System.Diagnostics.Stopwatch]::New() + +try { + $stopWatch.Restart() + + Write-Output "" | Tee-Object -FilePath $logFile -Append + Write-Output "This script creates a new deployment, using an existing CanadaPubSecALZ configuration ($Environment)." | Tee-Object -FilePath $logFile -Append + Write-Output "" | Tee-Object -FilePath $logFile -Append + + $ConfigVariablesYaml = @{} + .\Get-AlzConfiguration.ps1 -Environment $Environment -RepoRootPath $RepoRootPath -ConfigVariablesByRef ([ref]$ConfigVariablesYaml) ` + | Tee-Object -FilePath $logFile -Append + + $mgh = ($ConfigVariablesYaml.variables['var-managementgroup-hierarchy'] | ConvertFrom-Json) + + switch ($PSCmdlet.ParameterSetName) { + "CredentialFile" { + .\Connect-AlzCredential.ps1 -CredentialFile "$UserCredsPath/$CredentialFile.json" ` + | Tee-Object -FilePath $logFile -Append + } + "ServicePrincipal" { + .\Connect-AlzCredential.ps1 -SecureServicePrincipal $SecureServicePrincipal ` + | Tee-Object -FilePath $logFile -Append + } + "Interactive" { + .\Connect-AlzCredential.ps1 -TenantId $mgh.id ` + | Tee-Object -FilePath $logFile -Append + } + } + + $context = Get-AzContext + if ($context.Tenant.Id -ne $mgh.id) { + throw "You are not logged in to the correct tenant. You are logged in to $($context.Tenant.Id), but you should be logged in to $($mgh.id)." + } + + $SubscriptionIds = @() + .\Get-AlzSubscriptions.ps1 -Environment $Environment -RepoRootPath $RepoRootPath -SubscriptionIdsByRef ([ref]$SubscriptionIds) ` + | Tee-Object -FilePath $logFile -Append + + CreateDeployment -Environment $Environment -RepoRootPath $RepoRootPath -NetworkType $NetworkType -SubscriptionIds $SubscriptionIds ` + | Tee-Object -FilePath $logFile -Append + +} catch { + Write-Output $_ | Tee-Object -FilePath $logFile -Append + Write-Output $_.Exception | Tee-Object -FilePath $logFile -Append + throw +} finally { + Write-Output "Elapsed time: $($stopWatch.Elapsed)" ` + | Tee-Object -FilePath $logFile -Append +} diff --git a/scripts/configuration/Remove-AlzConfiguration.ps1 b/scripts/configuration/Remove-AlzConfiguration.ps1 new file mode 100644 index 00000000..5fceb8d7 --- /dev/null +++ b/scripts/configuration/Remove-AlzConfiguration.ps1 @@ -0,0 +1,150 @@ +<# +---------------------------------------------------------------------------------- +Copyright (c) Microsoft Corporation. +Licensed under the MIT license. + +THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, +EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. +---------------------------------------------------------------------------------- +#> + +<# + .SYNOPSIS + Removes an existing environment configuration for a CanadaPubSecALZ deployment. + + .DESCRIPTION + This script removes an existing set of environment configuration files. + + .PARAMETER Environment + The name of the environment to remove. + + .PARAMETER RepoRootPath + The path to the repository directory. Defaults to ..\.. + + .PARAMETER UserRootPath + The path to the user directory. Defaults to $HOME. + + .PARAMETER UserLogsPath + The path to the user logs directory. Defaults to $UserRootPath/ALZ/logs. + + .PARAMETER UserCredsPath + The path to the user credentials directory. Defaults to $UserRootPath/ALZ/credentials. + + .PARAMETER UserConfigPath + The path to the user configuration directory. Defaults to $UserRootPath/ALZ/config. + + .EXAMPLE + PS> .\Remove-AlzConfiguration.ps1 -Environment 'DevOpsOrg-branch' +#> + +[CmdletBinding()] +Param( + [Parameter(Mandatory = $true)] + [string]$Environment, + + [string]$RepoRootPath = "../..", + + [string]$UserRootPath = "$HOME", + + [string]$UserLogsPath = "$UserRootPath/ALZ/logs", + + [string]$UserCredsPath = "$UserRootPath/ALZ/credentials", + + [string]$UserConfigPath = "$UserRootPath/ALZ/config" +) + +$ErrorActionPreference = "Stop" + +function RemovePaths { + param( + [string]$Environment, + [string]$RepoRootPath + ) + # Validate Parameters + $RepoConfigPath = (Resolve-Path -Path "$RepoRootPath/config").Path + Write-Output "Checking configuration path ($RepoConfigPath)" + if (-not (Test-Path -PathType Container -Path $RepoConfigPath)) { + throw "Configuration path does not exist." + } + + # Remove variables configuration file + $path = "$RepoConfigPath/variables/$Environment.yml" + if (Test-Path -PathType Leaf -Path $path) { + Write-Output "Removing variables configuration file: $path" + Remove-Item -Path $path + } else { + Write-Output "Variables configuration file not found ($path)" + } + + # Remove logging configuration file(s) + $path = "$RepoConfigPath/logging/$Environment" + if (Test-Path -PathType Container -Path $path) { + Write-Output "Removing logging configuration directory: $path" + Remove-Item -Path $path -Recurse + } else { + Write-Output "Logging configuration directory not found ($path)" + } + + # Remove identity configuration file(s) + $path = "$RepoConfigPath/identity/$Environment" + if (Test-Path -PathType Container -Path $path) { + Write-Output "Removing identity configuration directory: $path" + Remove-Item -Path $path -Recurse + } else { + Write-Output "Identity configuration directory not found ($path)" + } + + # Remove network configuration file(s) + $path = "$RepoConfigPath/networking/$Environment" + if (Test-Path -PathType Container -Path $path) { + Write-Output "Removing network configuration directory: $path" + Remove-Item -Path $path -Recurse + } else { + Write-Output "Network configuration directory not found ($path)" + } + + # Remove subscription configuration file(s) + $path = "$RepoConfigPath/subscriptions/$Environment" + if (Test-Path -PathType Container -Path $path) { + Write-Output "Removing subscription configuration directory: $path" + Remove-Item -Path $path -Recurse + } else { + Write-Output "Subscription configuration directory not found ($path)" + } + + Write-Output "" +} + +# Ensure paths exist and are normalized to the OS path format +New-Item -ItemType Directory -Path $UserCredsPath -Force | Out-Null +$UserCredsPath = (Resolve-Path -Path $UserCredsPath).Path +New-Item -ItemType Directory -Path $UserLogsPath -Force | Out-Null +$UserLogsPath = (Resolve-Path -Path $UserLogsPath).Path +New-Item -ItemType Directory -Path $UserConfigPath -Force | Out-Null +$UserConfigPath = (Resolve-Path -Path $UserConfigPath).Path + +# Local variables +$date = Get-Date -Format "yyMMdd-HHmmss-fff" +$script = $(Split-Path -Path $PSCommandPath -LeafBase) +$logFile = "$UserLogsPath/$date-$script-$Environment.log" +$stopWatch = [System.Diagnostics.Stopwatch]::New() + +try { + $stopWatch.Restart() + + Write-Output "" | Tee-Object -FilePath $logFile -Append + Write-Output "This script removes an existing set of configuration files." | Tee-Object -FilePath $logFile -Append + Write-Output "" | Tee-Object -FilePath $logFile -Append + + RemovePaths -Environment $Environment -RepoRootPath $RepoRootPath ` + | Tee-Object -FilePath $logFile -Append + +} catch { + Write-Output $_ | Tee-Object -FilePath $logFile -Append + Write-Output $_.Exception | Tee-Object -FilePath $logFile -Append + throw +} finally { + Write-Output "Elapsed time: $($stopWatch.Elapsed)" ` + | Tee-Object -FilePath $logFile -Append +} diff --git a/scripts/configuration/Remove-AlzCredential.ps1 b/scripts/configuration/Remove-AlzCredential.ps1 new file mode 100644 index 00000000..387bcf9c --- /dev/null +++ b/scripts/configuration/Remove-AlzCredential.ps1 @@ -0,0 +1,123 @@ +<# +---------------------------------------------------------------------------------- +Copyright (c) Microsoft Corporation. +Licensed under the MIT license. + +THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, +EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. +---------------------------------------------------------------------------------- +#> + +<# + .SYNOPSIS + Removes a Service Principal for the specified environment. + + .DESCRIPTION + Removes a Service Principal for the specified environment. + + .PARAMETER Environment + The name of the environment. This is typically the repo/org name. + + .PARAMETER RootPath + The root path for the log, credential, and configuration files. Defaults to $HOME. + + .PARAMETER LogsPath + The path for the log files. Defaults to $UserRootPath/ALZ/logs. + + .PARAMETER CredsPath + The path for the credential files. Defaults to $UserRootPath/ALZ/credentials. + + .PARAMETER ConfigPath + The path for the configuration files. Defaults to $UserRootPath/ALZ/config. + + .EXAMPLE + PS> .\Remove-AlzCredential.ps1 -Environment 'CanadaALZ' + + .EXAMPLE + PS> .\Remove-AlzCredential.ps1 -Environment 'CanadaALZ' -UserRootPath 'C:\Users\me\ALZ' + + .EXAMPLE + PS> .\Remove-AlzCredential.ps1 -Environment 'CanadaALZ' -UserLogsPath 'C:\Users\me\ALZ\logs' + + .EXAMPLE + PS> .\Remove-AlzCredential.ps1 -Environment 'CanadaALZ' -UserCredsPath 'C:\Users\me\ALZ\credentials' + + .EXAMPLE + PS> .\Remove-AlzCredential.ps1 -Environment 'CanadaALZ' -UserConfigPath 'C:\Users\me\ALZ\config' +#> + +[CmdletBinding()] +Param( + [Parameter(Mandatory = $true)] + [string]$Environment, + + [string]$UserRootPath = "$HOME", + + [string]$UserLogsPath = "$UserRootPath/ALZ/logs", + + [string]$UserCredsPath = "$UserRootPath/ALZ/credentials", + + [string]$UserConfigPath = "$UserRootPath/ALZ/config" +) + +#Requires -Modules Az + +$ErrorActionPreference = "Stop" + +function RemoveServicePrincipal { + param( + [string]$Environment = $Environment, + [string]$UserCredsPath = $UserCredsPath + ) + + $credentialFile = "$UserCredsPath/$Environment.json" + if (!(Test-Path -Path $credentialFile)) { + throw "Service principal file ($credentialFile) does not exist." + } + + $context = Get-AzContext + if ($context -eq $null) { + throw "You must be logged in to Azure via Azure PowerShell to remove a service principal." + } + + try { + $sp = (Get-Content -Raw -Path $credentialFile | ConvertFrom-Json -Depth 100) + Write-Output "Removing Service Principal ($($sp.displayName)) for environment ($Environment) from tenant ($($sp.tenant))))" + Remove-AzADServicePrincipal -ApplicationId $sp.appId + Remove-AzADApplication -DisplayName $sp.displayName + } catch { + throw "Failed to remove Service Principal ($($sp.displayName)) for environment ($Environment) from tenant ($($sp.tenant))): $($_.Exception.Message)" + } + + Write-Output "Removing Service Principal file ($credentialFile)" + Remove-Item -Path $credentialFile -Force +} + +# Ensure paths exist and are normalized to the OS path format +New-Item -ItemType Directory -Path $UserCredsPath -Force | Out-Null +$UserCredsPath = (Resolve-Path -Path $UserCredsPath).Path +New-Item -ItemType Directory -Path $UserLogsPath -Force | Out-Null +$UserLogsPath = (Resolve-Path -Path $UserLogsPath).Path +New-Item -ItemType Directory -Path $UserConfigPath -Force | Out-Null +$UserConfigPath = (Resolve-Path -Path $UserConfigPath).Path + +# Local variables +$date = Get-Date -Format "yyMMdd-HHmmss-fff" +$script = $(Split-Path -Path $PSCommandPath -LeafBase) +$logFile = "$UserLogsPath/$date-$script-$Environment.log" +$stopWatch = [System.Diagnostics.Stopwatch]::New() + +# Create the service principal +try { + $stopWatch.Restart() + RemoveServicePrincipal -Environment $Environment -CredsPath $UserCredsPath ` + | Tee-Object -FilePath $logFile -Append +} catch { + Write-Output $_ | Tee-Object -FilePath $logFile -Append + Write-Output $_.Exception | Tee-Object -FilePath $logFile -Append + throw +} finally { + Write-Output "Elapsed time: $($stopWatch.Elapsed)" ` + | Tee-Object -FilePath $logFile -Append +} diff --git a/scripts/configuration/Test-AlzCredential.ps1 b/scripts/configuration/Test-AlzCredential.ps1 new file mode 100644 index 00000000..cc380a4b --- /dev/null +++ b/scripts/configuration/Test-AlzCredential.ps1 @@ -0,0 +1,138 @@ +<# +---------------------------------------------------------------------------------- +Copyright (c) Microsoft Corporation. +Licensed under the MIT license. + +THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, +EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. +---------------------------------------------------------------------------------- +#> + +<# + .SYNOPSIS + Tests a Service Principal for the specified environment. + + .DESCRIPTION + Tests a Service Principal for the specified environment. + + .PARAMETER Environment + The name of the environment. This is typically the repo/org name. + + .PARAMETER UserRootPath + The root path for the log, credential, and configuration files. Defaults to $HOME. + + .PARAMETER UserLogsPath + The path for the log files. Defaults to $UserRootPath/ALZ/logs. + + .PARAMETER UserCredsPath + The path for the credential files. Defaults to $UserRootPath/ALZ/credentials. + + .PARAMETER UserConfigPath + The path for the configuration files. Defaults to $UserRootPath/ALZ/config. + + .EXAMPLE + PS> .\Test-AlzCredential.ps1 -Environment 'CanadaALZ' + + .EXAMPLE + PS> .\Test-AlzCredential.ps1 -Environment 'CanadaALZ' -UserRootPath 'C:\Users\me\ALZ' + + .EXAMPLE + PS> .\Test-AlzCredential.ps1 -Environment 'CanadaALZ' -UserLogsPath 'C:\Users\me\ALZ\logs' + + .EXAMPLE + PS> .\Test-AlzCredential.ps1 -Environment 'CanadaALZ' -UserCredsPath 'C:\Users\me\ALZ\credentials' + + .EXAMPLE + PS> .\Test-AlzCredential.ps1 -Environment 'CanadaALZ' -UserConfigPath 'C:\Users\me\ALZ\config' +#> + +[CmdletBinding()] +Param( + [Parameter(Mandatory = $true)] + [string]$Environment, + + [string]$UserRootPath = "$HOME", + + [string]$UserLogsPath = "$UserRootPath/ALZ/logs", + + [string]$UserCredsPath = "$UserRootPath/ALZ/credentials", + + [string]$UserConfigPath = "$UserRootPath/ALZ/config" +) + +#Requires -Modules Az + +$ErrorActionPreference = "Stop" + +function TestServicePrincipal { + param( + [string]$Environment = $Environment, + [string]$UserCredsPath = $UserCredsPath + ) + + $credentialFile = "$UserCredsPath/$Environment.json" + if (!(Test-Path -Path $credentialFile)) { + throw "Service principal file ($credentialFile) does not exist." + } + + $context = Get-AzContext + if ($context -eq $null) { + throw "You must be logged in to Azure via Azure PowerShell to test a service principal." + } + + $sp = (Get-Content -Raw -Path $credentialFile | ConvertFrom-Json -Depth 100) + + $role = Get-AzRoleAssignment -ServicePrincipalName $sp.appId + + Write-Output "" + if (($role | where { $_.RoleDefinitionName -eq 'Owner' -and $_.Scope -eq '/' }).Count -lt 1) { + throw "Service Principal ($($sp.displayName)) for environment ($Environment) from tenant ($($sp.tenant)) is not an Owner of the tenant." + } else { + Write-Output "Service Principal ($($sp.displayName)) for environment ($Environment) from tenant ($($sp.tenant)) is an Owner of the tenant." + } + + try { + Write-Output "" + Write-Output "Current Azure context:" + Get-AzContext + .\Connect-AlzCredential.ps1 -CredentialFile $credentialFile + Write-Output "" + Write-Output "Service Principal Azure context:" + Get-AzContext + Disconnect-AzAccount + Write-Output "" + Write-Output "Original Azure context:" + Get-AzContext + } catch { + throw + } +} + +# Ensure paths exist and are normalized to the OS path format +New-Item -ItemType Directory -Path $UserCredsPath -Force | Out-Null +$UserCredsPath = (Resolve-Path -Path $UserCredsPath).Path +New-Item -ItemType Directory -Path $UserLogsPath -Force | Out-Null +$UserLogsPath = (Resolve-Path -Path $UserLogsPath).Path +New-Item -ItemType Directory -Path $UserConfigPath -Force | Out-Null +$UserConfigPath = (Resolve-Path -Path $UserConfigPath).Path + +# Local variables +$date = Get-Date -Format "yyMMdd-HHmmss-fff" +$script = $(Split-Path -Path $PSCommandPath -LeafBase) +$logFile = "$UserLogsPath/$date-$script-$Environment.log" +$stopWatch = [System.Diagnostics.Stopwatch]::New() + +# Create the service principal +try { + $stopWatch.Restart() + TestServicePrincipal -Environment $Environment -CredsPath $UserCredsPath ` + | Tee-Object -FilePath $logFile -Append +} catch { + Write-Output $_ | Tee-Object -FilePath $logFile -Append + Write-Output $_.Exception | Tee-Object -FilePath $logFile -Append + throw +} finally { + Write-Output "Elapsed time: $($stopWatch.Elapsed)" ` + | Tee-Object -FilePath $logFile -Append +} diff --git a/scripts/deployments/Functions/EnvironmentContext.ps1 b/scripts/deployments/Functions/EnvironmentContext.ps1 index f3087232..c7feb483 100644 --- a/scripts/deployments/Functions/EnvironmentContext.ps1 +++ b/scripts/deployments/Functions/EnvironmentContext.ps1 @@ -22,7 +22,7 @@ function New-EnvironmentContext { [string] $Environment ) - $EnvironmentConfigurationYamlFilePath = "$WorkingDirectory/config/variables/$Environment.yml" + $EnvironmentConfigurationYamlFilePath = (Resolve-Path -Path "$WorkingDirectory/config/variables/$Environment.yml").Path # Load main environment variables file as YAML $EnvironmentConfiguration = Get-Content $EnvironmentConfigurationYamlFilePath | ConvertFrom-Yaml @@ -31,25 +31,25 @@ function New-EnvironmentContext { # Retrieve the management group hierarchy variable as JSON $ManagementGroupHierarchy = $Variables['var-managementgroup-hierarchy'] | ConvertFrom-Json - $PolicyDirectory = "$WorkingDirectory/policy" + $PolicyDirectory = (Resolve-Path -Path "$WorkingDirectory/policy").Path # Create a new context object return [PSCustomObject]@{ - WorkingDirectory = $WorkingDirectory + WorkingDirectory = (Resolve-Path -Path $WorkingDirectory).Path - RolesDirectory = "$WorkingDirectory/roles" + RolesDirectory = (Resolve-Path -Path "$WorkingDirectory/roles").Path - PolicyCustomDefinitionDirectory = "$PolicyDirectory/custom/definitions/policy" - PolicySetCustomDefinitionDirectory = "$PolicyDirectory/custom/definitions/policyset" - PolicySetCustomAssignmentsDirectory = "$PolicyDirectory/custom/assignments" - PolicySetBuiltInAssignmentsDirectory = "$PolicyDirectory/builtin/assignments" + PolicyCustomDefinitionDirectory = (Resolve-Path -Path "$PolicyDirectory/custom/definitions/policy").Path + PolicySetCustomDefinitionDirectory = (Resolve-Path -Path "$PolicyDirectory/custom/definitions/policyset").Path + PolicySetCustomAssignmentsDirectory = (Resolve-Path -Path "$PolicyDirectory/custom/assignments").Path + PolicySetBuiltInAssignmentsDirectory = (Resolve-Path -Path "$PolicyDirectory/builtin/assignments").Path - SchemaDirectory = "$WorkingDirectory/schemas/latest" + SchemaDirectory = (Resolve-Path -Path "$WorkingDirectory/schemas/latest").Path - LoggingDirectory = "$WorkingDirectory/config/logging/$Environment" - NetworkingDirectory = "$WorkingDirectory/config/networking/$Environment" - SubscriptionsDirectory = "$WorkingDirectory/config/subscriptions/$Environment" - IdentityDirectory = "$WorkingDirectory/config/identity/$Environment" + LoggingDirectory = (Resolve-Path -Path "$WorkingDirectory/config/logging/$Environment").Path + NetworkingDirectory = (Resolve-Path -Path "$WorkingDirectory/config/networking/$Environment").Path + SubscriptionsDirectory = (Resolve-Path -Path "$WorkingDirectory/config/subscriptions/$Environment").Path + IdentityDirectory = (Resolve-Path -Path "$WorkingDirectory/config/identity/$Environment").Path Variables = $Variables ManagementGroupHierarchy = $ManagementGroupHierarchy diff --git a/scripts/deployments/Functions/HubNetworkWithAzureFirewall.ps1 b/scripts/deployments/Functions/HubNetworkWithAzureFirewall.ps1 index 5cf60bbc..aa1bc444 100644 --- a/scripts/deployments/Functions/HubNetworkWithAzureFirewall.ps1 +++ b/scripts/deployments/Functions/HubNetworkWithAzureFirewall.ps1 @@ -84,7 +84,13 @@ function Set-HubNetwork-With-AzureFirewall { [String]$AzureFirewallPolicyResourceId, [Parameter(Mandatory = $true)] - [String]$LogAnalyticsWorkspaceResourceId + [String]$LogAnalyticsWorkspaceResourceId, + + [Parameter(HelpMessage = "Number of retries to deploy the Hub Network")] + [int]$RetryCount = 5, + + [Parameter(HelpMessage = "Delay, in seconds, between retries to deploy the Hub Network")] + [double]$RetryDelay = 60 ) Set-AzContext -Subscription $SubscriptionId @@ -134,14 +140,36 @@ function Set-HubNetwork-With-AzureFirewall { subscriptionId = $SubscriptionId } - Write-Output "Deploying $PopulatedParametersFilePath to $SubscriptionId in $Region" - New-AzSubscriptionDeployment ` - -Name "main-$Region" ` - -Location $Region ` - -TemplateFile "$($Context.WorkingDirectory)/landingzones/lz-platform-connectivity-hub-azfw/main.bicep" ` - -TemplateParameterFile $PopulatedParametersFilePath ` - -Verbose - + <# This 'New-AzSubscriptionDeployment` command to deploy the hub network has been observed to fail with a transient error condition. It is wrapped in a retry loop to solve for transient errors. #> + $deployAttempt = 1 + $deployed = $false + while (($deployAttempt -le $RetryCount) -and (-not $deployed)) { + if ($deployAttempt -gt 1) { + Write-Output "Waiting $RetryDelay seconds before retrying deployment" + Start-Sleep -Seconds $RetryDelay + } + try { + Write-Output "Deploying $PopulatedParametersFilePath to $SubscriptionId in $Region - Attempt $deployAttempt of $RetryCount" + New-AzSubscriptionDeployment ` + -Name "main-$Region" ` + -Location $Region ` + -TemplateFile "$($Context.WorkingDirectory)/landingzones/lz-platform-connectivity-hub-azfw/main.bicep" ` + -TemplateParameterFile $PopulatedParametersFilePath ` + -Verbose + $deployed = $true + } + catch { + if ($deployAttempt -eq $RetryCount) { + throw + } else { + Write-Output "Error deploying $PopulatedParametersFilePath to $SubscriptionId in $Region" + Write-Output $_.Exception.Message + Write-Output $_.Exception.StackTrace + } + } + $deployAttempt++ + } + #region Check if Private DNS Zones are managed in the Hub. If so, enable Private DNS Zones policy assignment if ($Configuration.parameters.privateDnsZones.value.enabled -eq $true) { $PolicyAssignmentFilePath = "$($Context.PolicySetCustomAssignmentsDirectory)/DNSPrivateEndpoints.bicep" diff --git a/scripts/deployments/Functions/HubNetworkWithNVA.ps1 b/scripts/deployments/Functions/HubNetworkWithNVA.ps1 index ebaff2cf..64d8b648 100644 --- a/scripts/deployments/Functions/HubNetworkWithNVA.ps1 +++ b/scripts/deployments/Functions/HubNetworkWithNVA.ps1 @@ -32,7 +32,13 @@ function Set-HubNetwork-With-NVA { [SecureString]$NvaUsername = $null, [Parameter(Mandatory = $false)] - [SecureString]$NvaPassword = $null + [SecureString]$NvaPassword = $null, + + [Parameter(HelpMessage = "Number of retries to deploy the Hub Network")] + [int]$RetryCount = 5, + + [Parameter(HelpMessage = "Delay, in seconds, between retries to deploy the Hub Network")] + [double]$RetryDelay = 60 ) Set-AzContext -Subscription $SubscriptionId @@ -100,13 +106,35 @@ function Set-HubNetwork-With-NVA { subscriptionId = $SubscriptionId } - Write-Output "Deploying $PopulatedParametersFilePath to $SubscriptionId in $Region" - New-AzSubscriptionDeployment ` - -Name "main-$Region" ` - -Location $Region ` - -TemplateFile "$($Context.WorkingDirectory)/landingzones/lz-platform-connectivity-hub-nva/main.bicep" ` - -TemplateParameterFile $PopulatedParametersFilePath ` - -Verbose + <# This 'New-AzSubscriptionDeployment` command to deploy the hub network has been observed to fail with a transient error condition. It is wrapped in a retry loop to solve for transient errors. #> + $deployAttempt = 1 + $deployed = $false + while (($deployAttempt -le $RetryCount) -and (-not $deployed)) { + if ($deployAttempt -gt 1) { + Write-Output "Waiting $RetryDelay seconds before retrying deployment" + Start-Sleep -Seconds $RetryDelay + } + try { + Write-Output "Deploying $PopulatedParametersFilePath to $SubscriptionId in $Region - Attempt $deployAttempt of $RetryCount" + New-AzSubscriptionDeployment ` + -Name "main-$Region" ` + -Location $Region ` + -TemplateFile "$($Context.WorkingDirectory)/landingzones/lz-platform-connectivity-hub-nva/main.bicep" ` + -TemplateParameterFile $PopulatedParametersFilePath ` + -Verbose + $deployed = $true + } + catch { + if ($deployAttempt -eq $RetryCount) { + throw + } else { + Write-Output "Error deploying $PopulatedParametersFilePath to $SubscriptionId in $Region" + Write-Output $_.Exception.Message + Write-Output $_.Exception.StackTrace + } + } + $deployAttempt++ + } #region Check if Private DNS Zones are managed in the Hub. If so, enable Private DNS Zones policy assignment if ($Configuration.parameters.privateDnsZones.value.enabled -eq $true) { diff --git a/scripts/deployments/Functions/Subscriptions.ps1 b/scripts/deployments/Functions/Subscriptions.ps1 index f257325c..ad33b3a9 100644 --- a/scripts/deployments/Functions/Subscriptions.ps1 +++ b/scripts/deployments/Functions/Subscriptions.ps1 @@ -26,19 +26,21 @@ function Set-Subscriptions { foreach ($subscriptionId in $SubscriptionIds) { # Find the ARM JSON parameters, ensure there's only 1 parameters file for each subscription - $SubscriptonConfigurations = Get-ChildItem -Path $Context.SubscriptionsDirectory -Filter "*$subscriptionId*.json" -Recurse + # $SubscriptionConfigurations = Get-ChildItem -Path $Context.SubscriptionsDirectory -Filter "*$subscriptionId*.json" -Recurse + $pattern = "^$subscriptionId.*(_.*)(_.*)?\.json" + $SubscriptionConfigurations = @(Get-ChildItem -Path $Context.SubscriptionsDirectory -Filter "*$subscriptionId*.json" -File -Recurse | ? { $_.Name -match $pattern }) - if ($SubscriptonConfigurations.Count -eq 0) { - Write-Output "No Subscription JSON paramters files found in $($Context.SubscriptionsDirectory) for $subscriptionId" + if ($SubscriptionConfigurations.Count -eq 0) { + Write-Output "No Subscription JSON parameters files found in $($Context.SubscriptionsDirectory) for $subscriptionId" continue - } elseif ($SubscriptonConfigurations.Count -gt 1) { + } elseif ($SubscriptionConfigurations.Count -gt 1) { Write-Output "Multiple Subscription JSON paramters files found in $($Context.SubscriptionsDirectory) for $subscriptionId. There must only be one." continue } - $DirectoryName = $SubscriptonConfigurations[0].DirectoryName - $FilePath = $SubscriptonConfigurations[0].FullName - $FileName = $SubscriptonConfigurations[0].Name + $DirectoryName = $SubscriptionConfigurations[0].DirectoryName + $FilePath = $SubscriptionConfigurations[0].FullName + $FileName = $SubscriptionConfigurations[0].Name # Parse the file name to get subscription id, archetype and region (optional). # If region is not available in the file name, the use the default region provided @@ -48,8 +50,8 @@ function Set-Subscriptions { $DeploymentRegion = $FileNameParts.Count -eq 3 ? $FileNameParts[2] : $Region # Compute the management group id from the folder structure - $FilePathWithoutBaseDirectory = $DirectoryName -Replace $($Context.SubscriptionsDirectory), "" - $ManagementGroupId = $FilePathWithoutBaseDirectory -Replace [IO.Path]::DirectorySeparatorChar, "" + $FilePathWithoutBaseDirectory = $DirectoryName -Replace [regex]::Escape($Context.SubscriptionsDirectory), "" + $ManagementGroupId = $FilePathWithoutBaseDirectory -Replace [regex]::Escape([IO.Path]::DirectorySeparatorChar.ToString()), "" Write-Output "Deploying Subscription: $SubscriptionId" Write-Output " - Management Group: $ManagementGroupId" @@ -58,10 +60,10 @@ function Set-Subscriptions { Set-AzContext -Subscription $SubscriptionId - $SchemaFilePath = "$($Context.SchemaDirectory)/landingzones/lz-$ArchetypeName.json" + $SchemaFile = (Resolve-Path -Path "$($Context.SchemaDirectory)/landingzones/lz-$ArchetypeName.json").Path Write-Output "Validation JSON parameter configuration using $SchemaFilePath" - Get-Content -Raw $FilePath | Test-Json -SchemaFile $SchemaFilePath + Get-Content -Raw $FilePath | Test-Json -SchemaFile $SchemaFile $Configuration = Get-Content $FilePath | ConvertFrom-Json -Depth 100 @@ -88,11 +90,12 @@ function Set-Subscriptions { $MoveDeploymentName=-join $MoveDeploymentName[0..63] Write-Output "Moving Subscription ($SubscriptionId) to Management Group ($ManagementGroupId)" + $TemplateFile = (Resolve-Path -Path "$($Context.WorkingDirectory)/landingzones/utils/mg-move/move-subscription.bicep").Path New-AzManagementGroupDeployment ` -Name $MoveDeploymentName ` -ManagementGroupId $ManagementGroupId ` -Location $Context.DeploymentRegion ` - -TemplateFile "$($Context.WorkingDirectory)/landingzones/utils/mg-move/move-subscription.bicep" ` + -TemplateFile $TemplateFile ` -TemplateParameterObject @{ managementGroupId = $ManagementGroupId subscriptionId = $SubscriptionId @@ -102,10 +105,11 @@ function Set-Subscriptions { Write-Output "Deploying $PopulatedParametersFilePath to $SubscriptionId in $Region" Set-AzContext -Subscription $SubscriptionId + $TemplateFile = (Resolve-Path -Path "$($Context.WorkingDirectory)/landingzones/lz-$ArchetypeName/main.bicep").Path New-AzSubscriptionDeployment ` -Name "main-$DeploymentRegion" ` -Location $DeploymentRegion ` - -TemplateFile "$($Context.WorkingDirectory)/landingzones/lz-$ArchetypeName/main.bicep" ` + -TemplateFile $TemplateFile ` -TemplateParameterFile $PopulatedParametersFilePath ` -Verbose diff --git a/scripts/deployments/RunWorkflows.ps1 b/scripts/deployments/RunWorkflows.ps1 index bacaa54a..0ece9e5b 100644 --- a/scripts/deployments/RunWorkflows.ps1 +++ b/scripts/deployments/RunWorkflows.ps1 @@ -94,42 +94,42 @@ OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. The firewall password to use for the Hub Network with NVA workflow. .EXAMPLE - PS> .\RunWorkflows.ps1 -EnvironmentName CanadaESLZ-main -LoginInteractiveTenantId '8188040d-6c67-4c5c-b112-36a304b66dad' -DeployManagementGroups + PS> .\RunWorkflows.ps1 -EnvironmentName CanadaPubSecALZ-main -LoginInteractiveTenantId '8188040d-6c67-4c5c-b112-36a304b66dad' -DeployManagementGroups Deploy management groups interactively. .EXAMPLE - PS> .\RunWorkflows.ps1 -EnvironmentName CanadaESLZ-main -LoginInteractiveTenantId '8188040d-6c67-4c5c-b112-36a304b66dad' -DeployManagementGroups -DeployRoles -DeployLogging -DeployCustomPolicyDefinitions -DeployCustomPolicySetDefinitions -DeployCustomPolicySetAssignments -DeployBuiltinPolicySetAssignments -DeployAzureFirewallPolicy -DeployHubNetworkWithAzureFirewall + PS> .\RunWorkflows.ps1 -EnvironmentName CanadaPubSecALZ-main -LoginInteractiveTenantId '8188040d-6c67-4c5c-b112-36a304b66dad' -DeployManagementGroups -DeployRoles -DeployLogging -DeployCustomPolicyDefinitions -DeployCustomPolicySetDefinitions -DeployCustomPolicySetAssignments -DeployBuiltinPolicySetAssignments -DeployAzureFirewallPolicy -DeployHubNetworkWithAzureFirewall Deploy all platform components interactively, with Azure Firewall. .EXAMPLE - PS> .\RunWorkflows.ps1 -EnvironmentName CanadaESLZ-main -LoginInteractiveTenantId '8188040d-6c67-4c5c-b112-36a304b66dad' -DeploySubscriptionIds 'a188040e-6c67-4c5c-b112-36a304b66dad,7188030d-6c67-4c5c-b112-36a304b66dac' + PS> .\RunWorkflows.ps1 -EnvironmentName CanadaPubSecALZ-main -LoginInteractiveTenantId '8188040d-6c67-4c5c-b112-36a304b66dad' -DeploySubscriptionIds 'a188040e-6c67-4c5c-b112-36a304b66dad,7188030d-6c67-4c5c-b112-36a304b66dac' Deploy 2 subscriptions interactively. .EXAMPLE - PS> .\RunWorkflows.ps1 -EnvironmentName CanadaESLZ-main -DeployCustomPolicyDefinitions -DeployCustomPolicySetDefinitions -DeployCustomPolicySetAssignments -DeployBuiltinPolicySetAssignments + PS> .\RunWorkflows.ps1 -EnvironmentName CanadaPubSecALZ-main -DeployCustomPolicyDefinitions -DeployCustomPolicySetDefinitions -DeployCustomPolicySetAssignments -DeployBuiltinPolicySetAssignments Deploy Built-In & Custom Policy Sets, including all default custom policy/policy set definitions. .EXAMPLE - PS> .\RunWorkflows.ps1 -EnvironmentName CanadaESLZ-main -DeployCustomPolicyDefinitions + PS> .\RunWorkflows.ps1 -EnvironmentName CanadaPubSecALZ-main -DeployCustomPolicyDefinitions Deploy Custom Policy Definitions only. .EXAMPLE - PS> .\RunWorkflows.ps1 -EnvironmentName CanadaESLZ-main -DeployCustomPolicySetAssignments -CustomPolicySetAssignmentManagementGroupId pubsec -CustomPolicySetAssignmentNames DefenderForCloud + PS> .\RunWorkflows.ps1 -EnvironmentName CanadaPubSecALZ-main -DeployCustomPolicySetAssignments -CustomPolicySetAssignmentManagementGroupId pubsec -CustomPolicySetAssignmentNames DefenderForCloud Deploy one Custom Policy Set Assignment at management group .EXAMPLE - PS> .\RunWorkflows.ps1 -EnvironmentName CanadaESLZ-main -DeployBuiltinPolicySetAssignments + PS> .\RunWorkflows.ps1 -EnvironmentName CanadaPubSecALZ-main -DeployBuiltinPolicySetAssignments Deploy Built In Policy Assignments .EXAMPLE - PS> .\RunWorkflows.ps1 -EnvironmentName CanadaESLZ-main -DeployBuiltinPolicySetAssignments -BuiltinPolicySetAssignmentManagementGroupId pubsec -BuiltinPolicySetAssignmentNames asb + PS> .\RunWorkflows.ps1 -EnvironmentName CanadaPubSecALZ-main -DeployBuiltinPolicySetAssignments -BuiltinPolicySetAssignmentManagementGroupId pubsec -BuiltinPolicySetAssignmentNames asb Deploy one Built In Policy Assignment at management group diff --git a/scripts/onboarding/create-pipelines.bat b/scripts/onboarding/create-pipelines.bat index f9b12fd6..3b9546d5 100644 --- a/scripts/onboarding/create-pipelines.bat +++ b/scripts/onboarding/create-pipelines.bat @@ -22,7 +22,7 @@ choice /C YN /M "Do you want to proceed?" if errorlevel 2 exit /b 0 REM Process all pipeline definitions -for %%N in (management-groups roles platform-logging policy platform-connectivity-hub-nva platform-connectivity-hub-azfw platform-connectivity-hub-azfw-policy subscriptions) do ( +for %%N in (management-groups roles platform-logging platform-identity policy platform-connectivity-hub-nva platform-connectivity-hub-azfw platform-connectivity-hub-azfw-policy subscriptions) do ( REM Check for pipeline existence set FOUND= diff --git a/scripts/onboarding/set-variables.CanadaPubSecALZ.bat b/scripts/onboarding/set-variables.CanadaPubSecALZ.bat new file mode 100644 index 00000000..d6138892 --- /dev/null +++ b/scripts/onboarding/set-variables.CanadaPubSecALZ.bat @@ -0,0 +1,54 @@ +@echo off +REM // ---------------------------------------------------------------------------------- +REM // Copyright (c) Microsoft Corporation. +REM // Licensed under the MIT license. +REM // +REM // THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, +REM // EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES +REM // OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. +REM // ---------------------------------------------------------------------------------- + +REM Azure AD tenant GUID +set DEVOPS_TENANT_ID=df968f64-5f44-4e42-937b-47fb792ee373 + +REM Azure AD tenant root management group name +set DEVOPS_MGMT_GROUP_NAME=Tenant Root Group + +REM Azure service principal name for 'Owner' RBAC at tenant root scope +set DEVOPS_SP_NAME=spn-azure-platform-ops + +REM Azure security group name for 'Owner` RBAC subscription, network, and logging +set DEVOPS_SG_NAME=alz-owners + +REM Azure DevOps organization URL +set DEVOPS_ORG=https://dev.azure.com/CanadaPubSecALZ + +REM Azure DevOps project name (prefer no spaces) +set DEVOPS_PROJECT_NAME=CanadaPubSecALZ + +REM Repository name or URL +set DEVOPS_REPO_NAME_OR_URL=CanadaPubSecALZ + +REM Repository type: 'tfsgit' or 'github' +set DEVOPS_REPO_TYPE=tfsgit + +REM Repository branch name (default) +set DEVOPS_REPO_BRANCH=skeeler-quicksetup + +REM Azure DevOps pipeline name suffix (default) +set DEVOPS_PIPELINE_NAME_SUFFIX=-ci + +REM Azure DevOps service endpoint name (service connection in project settings) +set DEVOPS_SE_NAME=spn-azure-platform-ops + +REM Azure DevOps service endpoint template file (generated) +set DEVOPS_SE_TEMPLATE=service-endpoint.CanadaPubSecALZ.json + +REM Do not change this value (hard-coded in YAML pipeline definition) +set DEVOPS_VARIABLES_GROUP_NAME=firewall-secrets + +REM Are variables in the firewall-secrets group marked as secret? 'true' or 'false'. +set DEVOPS_VARIABLES_ARE_SECRET=true + +REM Folder path for generated output files +set DEVOPS_OUTPUT_DIR=.\output