diff --git a/03-Azure/01-02 Data/02-SQL_Modernization/Challenges/01-MicroHack-database_assessment_and_migration_with_Azure_Data_Studio.md b/03-Azure/01-02 Data/02-SQL_Modernization/Challenges/01-MicroHack-database_assessment_and_migration_with_Azure_Data_Studio.md index be888903..b804b8d6 100644 --- a/03-Azure/01-02 Data/02-SQL_Modernization/Challenges/01-MicroHack-database_assessment_and_migration_with_Azure_Data_Studio.md +++ b/03-Azure/01-02 Data/02-SQL_Modernization/Challenges/01-MicroHack-database_assessment_and_migration_with_Azure_Data_Studio.md @@ -16,85 +16,90 @@ [4. Confirm application databases have been migrated to Azure SQL Managed Instance](#confirm-application-databases-have-been-migrated-to-azure-sql-managed-instance) -# Migration architecture and Azure components +# Migration architecture and Azure components ![generated](../Images/MigrationArchitecture.png) # Generic Migration Content -| **Narrative** | **Notes** | -|:-----|:-------| -| *Notes for outside of the workshop:* *Familiarise yourself with Microsoft migration tools and the Azure Database Migration Guide* | Azure Database Migration Guide: [https://www.microsoft.com/en-us/download/default.aspx](https://azure.microsoft.com/en-gb/services/database-migration/) DMA & download link: Azure Data Studio and Migration Extension download Links: [Download and install Azure Data Studio - Azure Data Studio \| Microsoft Learn](https://learn.microsoft.com/en-us/sql/azure-data-studio/download-azure-data-studio?view=sql-server-ver16&tabs=redhat-install%2Credhat-uninstall) [Azure SQL migration extension for Azure Data Studio - Azure Data Studio \| Microsoft Learn](https://learn.microsoft.com/en-us/sql/azure-data-studio/extensions/azure-sql-migration-extension?view=sql-server-ver16) Microsoft Migration Portal: [https://datamigration.microsoft.com/](https://www.microsoft.com/en-us/download/default.aspx) Identify the right Azure SQL Database, Azure SQL Managed Instance or SQL Server on Azure VM SKU for your on-premises database | +| **Narrative** | **Notes** | +| :-------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| _Notes for outside of the workshop:_ _Familiarise yourself with Microsoft migration tools and the Azure Database Migration Guide_ | Azure Database Migration Guide: [https://www.microsoft.com/en-us/download/default.aspx](https://azure.microsoft.com/en-gb/services/database-migration/) DMA & download link: Azure Data Studio and Migration Extension download Links: [Download and install Azure Data Studio - Azure Data Studio \| Microsoft Learn](https://learn.microsoft.com/en-us/sql/azure-data-studio/download-azure-data-studio?view=sql-server-ver16&tabs=redhat-install%2Credhat-uninstall) [Azure SQL migration extension for Azure Data Studio - Azure Data Studio \| Microsoft Learn](https://learn.microsoft.com/en-us/sql/azure-data-studio/extensions/azure-sql-migration-extension?view=sql-server-ver16) Microsoft Migration Portal: [https://datamigration.microsoft.com/](https://www.microsoft.com/en-us/download/default.aspx) Identify the right Azure SQL Database, Azure SQL Managed Instance or SQL Server on Azure VM SKU for your on-premises database | # Get the SQL Managed Instance FQDN In this section we'll connect to the Azure Portal and retrieve SQL MI information: FQDN. -|**Narrative**| **Screenshot**| **Notes**| -|:------------|:--------------|:---------| -| On your Win10 VM open Edge browser and got to: [**HTTPS://portal.azure.com**](HTTPS://portal.azure.com) **Username and Password:** *(see your Teams Group)* In the Azure portal, open the **SQLHACK-SHARED** **Resource Group** and locate the **SQL managed instance** and open it. **Note the Host Name (FQDN)** sqlhackmi-xxxxx.xxxxxxx.database.windows.net. All other **details from the "DB Migration Lab and Parameters.pdf"** | ![](../Images/d414d816749bacbe40707d20930a6da5.png)| | +| **Narrative** | **Screenshot** | **Notes** | +| :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | :-------------------------------------------------- | :-------- | +| On your Win10 VM open Edge browser and got to: [**HTTPS://portal.azure.com**](HTTPS://portal.azure.com) **Username and Password:** _(see your Teams Group)_ In the Azure portal, open the **SQLHACK-SHARED** **Resource Group** and locate the **SQL managed instance** and open it. **Note the Host Name (FQDN)** sqlhackmi-xxxxx.xxxxxxx.database.windows.net. All other **details from the "DB Migration Lab and Parameters.pdf"** | ![](../Images/d414d816749bacbe40707d20930a6da5.png) | | # Assess the application databases for Azure SQL Database suitability using the Database Migration Assistant +> **❗Hint:** +> +> Credentials for connecting to the VMs is DemoUser / Demo@pass1234567 + In this section we will use the Data Migration Assistant (DMA) to assess the applications database for suitability for migration to Azure Cloud. -|**Narrative**| **Screenshot**| **Notes**| -|:------------|:--------------|:---------| -|We need to determine the suitability of the database(s) for migration to Azure. This includes checking for compatibility and feature support with Azure Database. You should already have a remote (Bastion) session open to your teams Win10 Management VM**,** if so run DMA from the Start menus or Desktop icon.|![A screen shot of a computer Description automatically generated](../Images/3967dd1b4dd31f5c19623f51ce94d486.png)|Database Migration Assistant (DMA) is a free download from Microsoft. It can be used to assess a number of database migration & upgrade scenarios not just SQL Server to Azure SQL Database.| -|You should see this screenshot to the right. Select the **"+"** to create a new **assessment** project|![](../Images/e2b4706b838049af733fed665f6ada16.png)| -|Select/Enter the following details: **Project name:** **Workshop1**
**Assessment type:** **Database Engine**
**Source server type:** **SQL Server**
**Target server type:** **Azure SQL Database**
Click **'Create'**|![](../Images/f562a7f4e609509f7032a192b15447d3.png)| Our first project assessment assumes we will be migrating to Azure SQL DB, so the options shown in the screenshot need to be selected.| -|Select the assessment checks (Report Type) to be made:
**Check database compatibility**
**Check feature parity**
Click **'Next'**|![](../Images/fec55ffa6e1278f1c5e336de2b67c7ff.png) | DMA can test for both database compatibility and feature parity compliance against the Azure target. As this is the initial evaluation, we are assessing a database(s) we will perform all of these tests.| -|Enter the source/legacy SQL details:
**Server Name:** **LEGACYSQL2012**
**Authentication Type:** **SQL Server Authentication**
**Username:** **_Will be provided during hack_**
**Password:** **_Will be provided during hack_**
**Untick "Encrypt connection"**
Click **'Connect'**
*If you get an error logging in check that the Win10 keyboard language.|![A screenshot of a login box Description automatically generated](../Images/b2f7457ed4a46050afcd18073d4cd96c.png)|When performing this within your own subscription you will enter the host, authentication and connection types according to your company guidelines and practices. *Bear in mind that DMA needs to connect to a source SQL Server using an account that belongs to the* **sysadmin** *role.* As this document is produced within a workshop environment Active Directory, Certificates and encryption has not been setup.| -|Select **only** the 3 databases used by your 'Online Transaction Monitor' app. These will have a **TEAMxx** prefix where XX should be replaced by your team number.
**TEAMxx_LocalMasterDataDb**
**TEAMxx_SharedMasterDb**
**TEAMxx_TenantDataDb**.
Click **'Add'** to add them to the assessment. | ![](../Images/9488ec94afd6312aa62f3d0855683c83.png)|DMA will show all databases located on the Source host and display them so you can decide which ones to include in this assessment project. **Note**: you can assess multiple databases at the same time. -| You should now see the screen on the right with the relevant TEAMxx databases listed. Select '**Start Assessment'**|![](../Images/ace5ff77e60d0379b3856db4497d306b.png)|**Note**: DMA allows you to either 'Add' or 'Remove' additional data sources as needed at this point. Also note that DMA provides some high-level metadata about the databases including their compatibility level the total size of each database. [Using Data Migration Assistant to assess an application's data access layer](https://techcommunity.microsoft.com/t5/microsoft-data-migration/using-data-migration-assistant-to-assess-an-application-s-data/ba-p/990430) | -| DMA will now show the results of the assessment using 2 separate reports:
**'SQL Server feature parity'** which is a server level report highlighting any server settings or components (e.g. MSDTC) that the source DBs are using that isn't supported on the target – in this case Azure SQL Database. In our assessment there are 'Unsupported" or "Partially Supported" features reported (**CLR**, **cross database queries, several trace flags**).

**'Compatibility Issues'** which is a database level report detailing individual objects that have compatibility issues. Select **TEAMxx_TenantDataDb** Note the 'Migration blockers' and 'Breaking Changes' including CLR which the database uses. CLR is not supported on Azure SQL DB but is supported by Azure SQL Database Managed Instance (SQLMI).|![](../Images/b9132f0c444aff5c9af7d4ebe165c543.png)![](../Images/70795f03ccd50ba39f7aafef5e5d2808.png)|**Note**: Toggle the parity and compatibility issues radio button (top left) to switch between the 2 reports. 'SQL Server feature parity' shows what features are not supported in the target data source. Under the 'Details' and 'Databases' sections on the right you will find remedial action that are required and the databases impacted. 'Compatibility Issues' shows, over the compatibility tabs, issues that need to be addressed to permit the database(s) to run, in the chosen compatibility level (e.g. 160, 150, 140, 130, 120, 110, 100). If you have multiple databases, as with the example screenshot, you need to highlight EACH database to see the compatibility issues.| -|| **Because we need to migrate CLR Stored Procs, we need to repeat the assessment with Azure SQL DB Managed Instance as the target to see if it's compatible**|| -|Once you've reviewed the assessment click the back arrow to see a list of current DMA projects. You should see this screenshot to the right. Select the **"+"** to create a new **assessment** project.|![](../Images/26f6da81414339b45fd763f27b58c84f.png)|| -|Select/Enter the following details:
**Project name:** **Workshop2**
**Assessment type:** **Database Engine**
**Source server type:** **SQL Server**
**Target server type:** **Azure SQL Database Managed Instance**
Click **'Create'** | ![](../Images/3b368b382479a605d9cc34179ebc7459.png)| Our 2nd assessment project assumes we will be migrating to Azure SQL DB Managed Instance, so the options shown in the screenshot need to be selected.| -|Select the assessment checks (Report Type) to be made: **Check database compatibility** **Check feature parity**
Click **'Next'** | ![](../Images/1b111d1094432ba5dca382cc10bd4a8b.png)|As we saw previously DMA can test for both database compatibility and feature parity compliance against the chosen target. As before we will assess all the databases against all of the tests.| -| Enter the source/legacy SQL details:
**Server Name:** **LEGACYSQL2012**
**Authentication Type:** **SQL Server Authentication**
**Username:** **_Will be provided during hack_**
**Password:** **_Will be provided during hack_**
**Untick "Encrypt connection"**
Click **'Connect'**|![A screenshot of a login box Description automatically generated](../Images/b2f7457ed4a46050afcd18073d4cd96c.png) | When performing this within your own subscription you will enter the host, authentication and connection types according to your company guidelines and practices. *Bear in mind that DMA needs to connect to a source SQL Server using an account that belongs to the sysadmin role.* As this document is produced within a workshop environment Active Directory, Certificates and encryption has not been setup.| -| You should now see the screen on the right with the relevant TEAMXX databases listed. Select '**Start Assessment'** | ![](../Images/ec0d16f58c29f404b13f9204a9c691e4.png) | **Note**: DMA allows you to either 'Add' or 'Remove' additional data sources as needed at this point. Also note that DMA has identified what compatibility level each source database is running under.| -| As before DMA will now show the results from the assessment as the separate 2 reports. Note the '**SQL Server feature parity**' report will either be clean The '**Compatibility Issues**' report should be clear for all 3 databases showing that they can be migrated to Azure SQLDB Managed Instance without changes.|![](../Images/6d2872ff60eb0f2926900c12e81c352b.png) | Note: Toggle the parity and compatibility Issues radio button (top left) to see how DMA. 'SQL Server feature parity' shows what features are not supported in the target data source. Under 'Details' and 'Databases' you will find remedial action that are required and the databases impacted. 'Compatibility Issues' shows, over the compatibility tabs, issues that need to be addressed to permit the database(s) to run, in the chosen compatibility level (e.g. 160, 150,140, 130, 120, 110,100). If you have multiple databases, as with the example screenshot, you need to highlight **EACH** database to see the compatibility issues. | +| **Narrative** | **Screenshot** | **Notes** | +| :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | :----------------------------------------------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| We need to determine the suitability of the database(s) for migration to Azure. This includes checking for compatibility and feature support with Azure Database. You should already have a remote (Bastion) session open to your teams Win10 Management VM**,** if so run DMA from the Start menus or Desktop icon. | ![A screen shot of a computer Description automatically generated](../Images/3967dd1b4dd31f5c19623f51ce94d486.png) | Database Migration Assistant (DMA) is a free download from Microsoft. It can be used to assess a number of database migration & upgrade scenarios not just SQL Server to Azure SQL Database. | +| You should see this screenshot to the right. Select the **"+"** to create a new **assessment** project | ![](../Images/e2b4706b838049af733fed665f6ada16.png) | +| Select/Enter the following details: **Project name:** **Workshop1**
**Assessment type:** **Database Engine**
**Source server type:** **SQL Server**
**Target server type:** **Azure SQL Database**
Click **'Create'** | ![](../Images/f562a7f4e609509f7032a192b15447d3.png) | Our first project assessment assumes we will be migrating to Azure SQL DB, so the options shown in the screenshot need to be selected. | +| Select the assessment checks (Report Type) to be made:
**Check database compatibility**
**Check feature parity**
Click **'Next'** | ![](../Images/fec55ffa6e1278f1c5e336de2b67c7ff.png) | DMA can test for both database compatibility and feature parity compliance against the Azure target. As this is the initial evaluation, we are assessing a database(s) we will perform all of these tests. | +| Enter the source/legacy SQL details:
**Server Name:** **LEGACYSQL2012**
**Authentication Type:** **SQL Server Authentication**
**Username:** **_Will be provided during hack_**
**Password:** **_Will be provided during hack_**
**Untick "Encrypt connection"**
Click **'Connect'**
\*If you get an error logging in check that the Win10 keyboard language. | ![A screenshot of a login box Description automatically generated](../Images/b2f7457ed4a46050afcd18073d4cd96c.png) | When performing this within your own subscription you will enter the host, authentication and connection types according to your company guidelines and practices. _Bear in mind that DMA needs to connect to a source SQL Server using an account that belongs to the_ **sysadmin** _role._ As this document is produced within a workshop environment Active Directory, Certificates and encryption has not been setup. | +| Select **only** the 3 databases used by your 'Online Transaction Monitor' app. These will have a **TEAMxx** prefix where XX should be replaced by your team number.
**TEAMxx_LocalMasterDataDb**
**TEAMxx_SharedMasterDb**
**TEAMxx_TenantDataDb**.
Click **'Add'** to add them to the assessment. | ![](../Images/9488ec94afd6312aa62f3d0855683c83.png) | DMA will show all databases located on the Source host and display them so you can decide which ones to include in this assessment project. **Note**: you can assess multiple databases at the same time. | +| You should now see the screen on the right with the relevant TEAMxx databases listed. Select '**Start Assessment'** | ![](../Images/ace5ff77e60d0379b3856db4497d306b.png) | **Note**: DMA allows you to either 'Add' or 'Remove' additional data sources as needed at this point. Also note that DMA provides some high-level metadata about the databases including their compatibility level the total size of each database. [Using Data Migration Assistant to assess an application's data access layer](https://techcommunity.microsoft.com/t5/microsoft-data-migration/using-data-migration-assistant-to-assess-an-application-s-data/ba-p/990430) | +| DMA will now show the results of the assessment using 2 separate reports:
**'SQL Server feature parity'** which is a server level report highlighting any server settings or components (e.g. MSDTC) that the source DBs are using that isn't supported on the target – in this case Azure SQL Database. In our assessment there are 'Unsupported" or "Partially Supported" features reported (**CLR**, **cross database queries, several trace flags**).

**'Compatibility Issues'** which is a database level report detailing individual objects that have compatibility issues. Select **TEAMxx_TenantDataDb** Note the 'Migration blockers' and 'Breaking Changes' including CLR which the database uses. CLR is not supported on Azure SQL DB but is supported by Azure SQL Database Managed Instance (SQLMI). | ![](../Images/b9132f0c444aff5c9af7d4ebe165c543.png)![](../Images/70795f03ccd50ba39f7aafef5e5d2808.png) | **Note**: Toggle the parity and compatibility issues radio button (top left) to switch between the 2 reports. 'SQL Server feature parity' shows what features are not supported in the target data source. Under the 'Details' and 'Databases' sections on the right you will find remedial action that are required and the databases impacted. 'Compatibility Issues' shows, over the compatibility tabs, issues that need to be addressed to permit the database(s) to run, in the chosen compatibility level (e.g. 160, 150, 140, 130, 120, 110, 100). If you have multiple databases, as with the example screenshot, you need to highlight EACH database to see the compatibility issues. | +| | **Because we need to migrate CLR Stored Procs, we need to repeat the assessment with Azure SQL DB Managed Instance as the target to see if it's compatible** | | +| Once you've reviewed the assessment click the back arrow to see a list of current DMA projects. You should see this screenshot to the right. Select the **"+"** to create a new **assessment** project. | ![](../Images/26f6da81414339b45fd763f27b58c84f.png) | | +| Select/Enter the following details:
**Project name:** **Workshop2**
**Assessment type:** **Database Engine**
**Source server type:** **SQL Server**
**Target server type:** **Azure SQL Database Managed Instance**
Click **'Create'** | ![](../Images/3b368b382479a605d9cc34179ebc7459.png) | Our 2nd assessment project assumes we will be migrating to Azure SQL DB Managed Instance, so the options shown in the screenshot need to be selected. | +| Select the assessment checks (Report Type) to be made: **Check database compatibility** **Check feature parity**
Click **'Next'** | ![](../Images/1b111d1094432ba5dca382cc10bd4a8b.png) | As we saw previously DMA can test for both database compatibility and feature parity compliance against the chosen target. As before we will assess all the databases against all of the tests. | +| Enter the source/legacy SQL details:
**Server Name:** **LEGACYSQL2012**
**Authentication Type:** **SQL Server Authentication**
**Username:** **_Will be provided during hack_**
**Password:** **_Will be provided during hack_**
**Untick "Encrypt connection"**
Click **'Connect'** | ![A screenshot of a login box Description automatically generated](../Images/b2f7457ed4a46050afcd18073d4cd96c.png) | When performing this within your own subscription you will enter the host, authentication and connection types according to your company guidelines and practices. _Bear in mind that DMA needs to connect to a source SQL Server using an account that belongs to the sysadmin role._ As this document is produced within a workshop environment Active Directory, Certificates and encryption has not been setup. | +| You should now see the screen on the right with the relevant TEAMXX databases listed. Select '**Start Assessment'** | ![](../Images/ec0d16f58c29f404b13f9204a9c691e4.png) | **Note**: DMA allows you to either 'Add' or 'Remove' additional data sources as needed at this point. Also note that DMA has identified what compatibility level each source database is running under. | +| As before DMA will now show the results from the assessment as the separate 2 reports. Note the '**SQL Server feature parity**' report will either be clean The '**Compatibility Issues**' report should be clear for all 3 databases showing that they can be migrated to Azure SQLDB Managed Instance without changes. | ![](../Images/6d2872ff60eb0f2926900c12e81c352b.png) | Note: Toggle the parity and compatibility Issues radio button (top left) to see how DMA. 'SQL Server feature parity' shows what features are not supported in the target data source. Under 'Details' and 'Databases' you will find remedial action that are required and the databases impacted. 'Compatibility Issues' shows, over the compatibility tabs, issues that need to be addressed to permit the database(s) to run, in the chosen compatibility level (e.g. 160, 150,140, 130, 120, 110,100). If you have multiple databases, as with the example screenshot, you need to highlight **EACH** database to see the compatibility issues. | **We are now ready to migrate the application databases to Azure SQL Database Managed Instance** - # Migrate the application databases to Azure SQL Database managed instance using the Azure Data Studio (ADS) with migration extension and identify target Azure SQL SKU -In this section we will use the Azure Data Studio (ADS) to assess the applications database for suitability for migration to Azure Cloud. - -|**Narrative**| **Screenshot**| **Notes**| -|:------------|:--------------|:---------| -|We need to determine the suitability of the database(s) for migration to Azure. This includes checking for compatibility and feature support with Azure Database. You should already have an RDP (or Bastion) session open to your teams Win10 Management VM, if so run Azure Data Studio (ADS) from the Start menus or Desktop icon.|![](../Images/b75f90f39b5b822bc14d18ae2ffb8621.png)| Azure Data Studio (ADS) is a free download from Microsoft. It can be used to perform database administration as well as assess a number of database migration & upgrade scenarios not just SQL Server to Azure SQL Database. [Download and install Azure Data Studio](https://learn.microsoft.com/en-us/sql/azure-data-studio/download-azure-data-studio?view=sql-server-ver16&tabs=redhat-install%2Credhat-uninstall)| -|Select "extensions" icon on the bottom left ( or press : CTRL + Shift + X) and search for: "**Azure SQL migration**" in the extension market and click Install. (If extension is not compatible with the ADS version installed, upgrade ADS under Help \> Check for Updates).|![](../Images/a12dd92f76c6242ff3ff60b275ead646.png)| See also: [Azure SQL migration extension for Azure Data Studio](https://learn.microsoft.com/en-us/sql/azure-data-studio/extensions/azure-sql-migration-extension?view=sql-server-ver16) | -|Open your browser and navigate to Login in with the credential provided Select the Azure Storage Account "sqlhack…" in the Resource Group: "SQLHACK-SHARED" And click: Access Keys on the left.|![](../Images/4ea143728ad4a3ec730760572f785d2e.png)| You can note the Key to the notepad and reuse it in following steps. | -|Create database backup in SSMS: Open SQL Server Management Studio (SSMS) on your Team VM. |![](../Images/286fb2e6d1d6b23789b3d3d16af409f5.png) | | -|In SSMS connect to: **legacysql2012**
Use the credentials:
**User**: **_Will be provided during hack_**
**Password**: **_Will be provided during hack_**|![](../Images/25bce50ae5aedc9358b1c09cddbdd9e5.png)|| -|**DO NOT EXECUTE THIS STEP** This is for reference only, as only a single credential is required! In SSMS open new query and create the credential using the following script: *USE [master]* *GO* *CREATE CREDENTIAL [Azurebackupstorage] WITH IDENTITY = '\'* *,SECRET = '\'*|![](../Images/289bd8ec4d83a70c8290893a42e7c2a3.png)| _**This should be only done only by the trainer.**_| -|Backup your team databases: Select your 3 team databases and create a full back to URL for each database
**TEAMXX_TenantDataDB** **TEAMXX_LocalMasterDataDB**
**TEAMXX_SharedMasterDataDB**|![](../Images/47cdd668bd3f86a4d89336bd93c8eea7.png)| This is the wizard experience in SSMS, you can also take backups using T-SQL scripts. There are some samples below, for this. | -|Backup database: Select Backup to URL Select the credential "Azurebackupstorage" Make sure you enter the Azure container name as follows: **migration/team\_\** e.g. for team01 **migration\\team01_localmasterdatadb**. Repeat this process for the remaining 2 databases: **TEAMXX_LocalMasterDataDB** **TEAMXX_SharedMasterDataDB** Use SSMS like above or use TSQL commands in the right hand side.|![](../Images/c8e2b67d79caf6a59890bee57dba263d.png)![](../Images/50d6aabc1ac11857c2a5ff2f7d6961fb.png) | [**You can also directly use TSQL to BackUp your Databases**](#t-sql-backup-code) | -|Switch to Azure portal on your web browser. Review and check that the **full backup** exists in each folder in the Azure Storage account.| *![](../Images/bc48ffffb341a8f7288bab66aa51c224.png)*|| -|In Azure Data Studio on your Team VM Connect to legacy SQL Server 2012 using "**New Connection**" | ![](../Images/d20118abebd0f983cb4c31db10098012.png)|| -| Enter server name and credentials.
Connection string: legacysql2012
**User**: **_Will be provided during hack_**
**Password**: **_Will be provided during hack_**.
Click Connect |![](../Images/e606818baf281ade6ac7bc84885c904a.png)|| -| Right Click on the SQL Server instance on the left hand side and select "**Manage**".|![](../Images/7accfb1944733173f52473afe3a4bf06.png)|| -| Select Azure SQL migration and choose "**New migration**" |![](../Images/5791f84a179b493d2325f7fef83571c0.png)|| -|Select your team databases:
**TEAMXX_TenantDataDB**
**TEAMXX_LocalMasterDataDB**
**TEAMXX_SharedMasterDataDB**
Click Next |![](../Images/0090bffa2e9bab5fce9ab882913500c0.png)|| -|Run assessment and receive recommendation Select Azure SQL target: **Azure SQL managed instance** Select "**Get Azure Recommendation**" Select the Log path: **C:\\Logs** and start the Performance Collection (If "C:\\Logs" folder doesn't exist, create this folder). You will see that data collection is in progress. Stop the performance collection **after \~10 min** by clicking on "Stop Data Collection" and review the recommended configuration which has now automatically appeared on the upper side.|![](../Images/f224cdfd145b933329a09589fce83717.png)![](../Images/86725ae84d4d19a6a6aab6652c018fe7.png)![](../Images/df840e717b23bd5d951fca011db0e0ba.png)![](../Images/66e97c5183db9f232356cf2a4900e054.png)![](../Images/735183829e72b24d22d8de7544fac0fc.png)|| -|Review the details of the recommended configuration in that you click on "View Details" under Azure SQL Managed Instance Tab.|![](../Images/fd722fca02ec3892686fef5a13273d01.png) | Please note that you can also save the recommendation report| -|Click on View/Select and select the 3 team databases for migration:
**TEAMXX_TenantDataDB**
**TEAMXX_LocalMasterDataDB**
**TEAMXX_SharedMasterDataDB**
Click Next|![](../Images/62bdf7248a303255111fe2dccf27a63b.png)![](../Images/a2c33df0563053cfc72e190908168372.png)![](../Images/b9c6e7783ef5e123c08e2d0c85215430.png)|| -|Select Azure Target (SQL MI). For this, you need to add your account that you use to login to Azure Portal: sqlhackuser**XX**@M365x59576877.onmicrosoft.com \&sqlhack@demo\_**XX**!|![](../Images/5630199a66cc115b379d7a46b1fe34b4.png)|| -| Select the Azure subscription, the Location, Resource Group and Azure SQL MI FDQN Name which are automatically provided from your Account. Click Next.|![](../Images/552e04b9711d318cca4b9b26e1f33664.png)|| -|Step 4: Select database migration service Select "**offline migration**" Select the existing Azure Database Migration Service: **sqlhack-dmsV2**|![](../Images/df0f6c23d4f68e630d11ee175b1fb414.png)| You can also do an Online Migration for mission critical workloads using DMS. There are additional steps that you should take for this. Please use the information in the following tutorial for Online Migration:[Tutorial: Migrate SQL Server to Azure SQL Managed Instance online by using Azure Data Studio - Azure Database Migration Service \| Microsoft Learn](https://learn.microsoft.com/en-us/azure/dms/tutorial-sql-server-managed-instance-online-ads) (You can also create a new Database Migration Service within minutes of you do the exercise in your own subscription. For this you can click on "create new in Step 6")| -|In the data source configuration select the last full backup file and click Next | ![](../Images/6ccfcae25882df567a7b51dcba3ecac5.png)|| -| Review summary and start migration.|![](../Images/ecdb9fede863af06e2ca346a80af669e.png)|| -| Review progress in Azure Data Studio Click on Refresh from time to time to check the latest status of the migration until it succeeds.|![](../Images/4a12363cf88d0a17e353598df4caee28.png)![](../Images/9f8c3cb1370893365f91d97b69a8dc55.png)![](../Images/2991c3b319d8b486cf78d26782d3f740.png)|| +In this section we will use the Azure Data Studio (ADS) to assess the applications database for suitability for migration to Azure Cloud. + +| **Narrative** | **Screenshot** | **Notes** | +| :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| We need to determine the suitability of the database(s) for migration to Azure. This includes checking for compatibility and feature support with Azure Database. You should already have an RDP (or Bastion) session open to your teams Win10 Management VM, if so run Azure Data Studio (ADS) from the Start menus or Desktop icon. | ![](../Images/b75f90f39b5b822bc14d18ae2ffb8621.png) | Azure Data Studio (ADS) is a free download from Microsoft. It can be used to perform database administration as well as assess a number of database migration & upgrade scenarios not just SQL Server to Azure SQL Database. [Download and install Azure Data Studio](https://learn.microsoft.com/en-us/sql/azure-data-studio/download-azure-data-studio?view=sql-server-ver16&tabs=redhat-install%2Credhat-uninstall) | +| Select "extensions" icon on the bottom left ( or press : CTRL + Shift + X) and search for: "**Azure SQL migration**" in the extension market and click Install. (If extension is not compatible with the ADS version installed, upgrade ADS under Help \> Check for Updates). | ![](../Images/a12dd92f76c6242ff3ff60b275ead646.png) | See also: [Azure SQL migration extension for Azure Data Studio](https://learn.microsoft.com/en-us/sql/azure-data-studio/extensions/azure-sql-migration-extension?view=sql-server-ver16) | +| Open your browser and navigate to Login in with the credential provided Select the Azure Storage Account "sqlhack…" in the Resource Group: "SQLHACK-SHARED" And click: Access Keys on the left. | ![](../Images/4ea143728ad4a3ec730760572f785d2e.png) | You can note the Key to the notepad and reuse it in following steps. | +| Create database backup in SSMS: Open SQL Server Management Studio (SSMS) on your Team VM. | ![](../Images/286fb2e6d1d6b23789b3d3d16af409f5.png) | | +| In SSMS connect to: **legacysql2012**
Use the credentials:
**User**: **_Will be provided during hack_**
**Password**: **_Will be provided during hack_** | ![](../Images/25bce50ae5aedc9358b1c09cddbdd9e5.png) | | +| **DO NOT EXECUTE THIS STEP** This is for reference only, as only a single credential is required! In SSMS open new query and create the credential using the following script: _USE [master]_ _GO_ _CREATE CREDENTIAL [Azurebackupstorage] WITH IDENTITY = '\'_ _,SECRET = '\'_ | ![](../Images/289bd8ec4d83a70c8290893a42e7c2a3.png) | _**This should be only done only by the trainer.**_ | +| Backup your team databases: Select your 3 team databases and create a full back to URL for each database
**TEAMXX_TenantDataDB** **TEAMXX_LocalMasterDataDB**
**TEAMXX_SharedMasterDataDB** | ![](../Images/47cdd668bd3f86a4d89336bd93c8eea7.png) | This is the wizard experience in SSMS, you can also take backups using T-SQL scripts. There are some samples below, for this. | +| Backup database: Select Backup to URL Select the credential "Azurebackupstorage" Make sure you enter the Azure container name as follows: **migration/team\\_\** e.g. for team01 **migration\\team01_localmasterdatadb**. Repeat this process for the remaining 2 databases: **TEAMXX_LocalMasterDataDB** **TEAMXX_SharedMasterDataDB** Use SSMS like above or use TSQL commands in the right hand side. | ![](../Images/c8e2b67d79caf6a59890bee57dba263d.png)![](../Images/50d6aabc1ac11857c2a5ff2f7d6961fb.png) | [**You can also directly use TSQL to BackUp your Databases**](#t-sql-backup-code) | +| Switch to Azure portal on your web browser. Review and check that the **full backup** exists in each folder in the Azure Storage account. | _![](../Images/bc48ffffb341a8f7288bab66aa51c224.png)_ | | +| In Azure Data Studio on your Team VM Connect to legacy SQL Server 2012 using "**New Connection**" | ![](../Images/d20118abebd0f983cb4c31db10098012.png) | | +| Enter server name and credentials.
Connection string: legacysql2012
**User**: **_Will be provided during hack_**
**Password**: **_Will be provided during hack_**.
Click Connect | ![](../Images/e606818baf281ade6ac7bc84885c904a.png) | | +| Right Click on the SQL Server instance on the left hand side and select "**Manage**". | ![](../Images/7accfb1944733173f52473afe3a4bf06.png) | | +| Select Azure SQL migration and choose "**New migration**" | ![](../Images/5791f84a179b493d2325f7fef83571c0.png) | | +| Select your team databases:
**TEAMXX_TenantDataDB**
**TEAMXX_LocalMasterDataDB**
**TEAMXX_SharedMasterDataDB**
Click Next | ![](../Images/0090bffa2e9bab5fce9ab882913500c0.png) | | +| Run assessment and receive recommendation Select Azure SQL target: **Azure SQL managed instance** Select "**Get Azure Recommendation**" Select the Log path: **C:\\Logs** and start the Performance Collection (If "C:\\Logs" folder doesn't exist, create this folder). You will see that data collection is in progress. Stop the performance collection **after \~10 min** by clicking on "Stop Data Collection" and review the recommended configuration which has now automatically appeared on the upper side. | ![](../Images/f224cdfd145b933329a09589fce83717.png)![](../Images/86725ae84d4d19a6a6aab6652c018fe7.png)![](../Images/df840e717b23bd5d951fca011db0e0ba.png)![](../Images/66e97c5183db9f232356cf2a4900e054.png)![](../Images/735183829e72b24d22d8de7544fac0fc.png) | | +| Review the details of the recommended configuration in that you click on "View Details" under Azure SQL Managed Instance Tab. | ![](../Images/fd722fca02ec3892686fef5a13273d01.png) | Please note that you can also save the recommendation report | +| Click on View/Select and select the 3 team databases for migration:
**TEAMXX_TenantDataDB**
**TEAMXX_LocalMasterDataDB**
**TEAMXX_SharedMasterDataDB**
Click Next | ![](../Images/62bdf7248a303255111fe2dccf27a63b.png)![](../Images/a2c33df0563053cfc72e190908168372.png)![](../Images/b9c6e7783ef5e123c08e2d0c85215430.png) | | +| Select Azure Target (SQL MI). For this, you need to add your account that you use to login to Azure Portal: sqlhackuser**XX**@M365x59576877.onmicrosoft.com \&sqlhack@demo\_**XX**! | ![](../Images/5630199a66cc115b379d7a46b1fe34b4.png) | | +| Select the Azure subscription, the Location, Resource Group and Azure SQL MI FDQN Name which are automatically provided from your Account. Click Next. | ![](../Images/552e04b9711d318cca4b9b26e1f33664.png) | | +| Step 4: Select database migration service Select "**offline migration**" Select the existing Azure Database Migration Service: **sqlhack-dmsV2** | ![](../Images/df0f6c23d4f68e630d11ee175b1fb414.png) | You can also do an Online Migration for mission critical workloads using DMS. There are additional steps that you should take for this. Please use the information in the following tutorial for Online Migration:[Tutorial: Migrate SQL Server to Azure SQL Managed Instance online by using Azure Data Studio - Azure Database Migration Service \| Microsoft Learn](https://learn.microsoft.com/en-us/azure/dms/tutorial-sql-server-managed-instance-online-ads) (You can also create a new Database Migration Service within minutes of you do the exercise in your own subscription. For this you can click on "create new in Step 6") | +| In the data source configuration select the last full backup file and click Next | ![](../Images/6ccfcae25882df567a7b51dcba3ecac5.png) | | +| Review summary and start migration. | ![](../Images/ecdb9fede863af06e2ca346a80af669e.png) | | +| Review progress in Azure Data Studio Click on Refresh from time to time to check the latest status of the migration until it succeeds. | ![](../Images/4a12363cf88d0a17e353598df4caee28.png)![](../Images/9f8c3cb1370893365f91d97b69a8dc55.png)![](../Images/2991c3b319d8b486cf78d26782d3f740.png) | | # Confirm application databases have been migrated to Azure SQL Managed Instance # Annotations + ### T-SQL Backup Code -``` SQL -BACKUP DATABASE [TEAM01_LocalMasterDataDB] + +```SQL +BACKUP DATABASE [TEAM01_LocalMasterDataDB] TO URL = N'https://].blob.core.windows.net/migration/team01_localmasterdatadb/TEAM01_LocalMasterDataDB.bak' WITH CREDENTIAL = N'Azurebackupstorage', NOFORMAT, NOINIT, @@ -116,4 +121,4 @@ NOFORMAT, NOINIT, NAME = N'TEAM01_TenantDataDB-Full Database Backup', NOSKIP, NOREWIND, NOUNLOAD, STATS = 10 GO -```` \ No newline at end of file +``` diff --git a/03-Azure/01-03-Infrastructure/02_Hybrid_Azure_Arc_Servers/Readme.md b/03-Azure/01-03-Infrastructure/02_Hybrid_Azure_Arc_Servers/Readme.md index 1096a5a3..afa40e9d 100644 --- a/03-Azure/01-03-Infrastructure/02_Hybrid_Azure_Arc_Servers/Readme.md +++ b/03-Azure/01-03-Infrastructure/02_Hybrid_Azure_Arc_Servers/Readme.md @@ -15,7 +15,6 @@ - [Challenge 5 - Best Practices assessment for Windows Server](#challenge-5---best-practices-assessment-for-windows-server) - [Challenge 6 - Activate ESU for Windows Server 2012 R2 via Arc (optional)](#challenge-6---activate-esu-for-windows-server-2012-r2-via-arc---optional) - [Challenge 7 - Azure Automanage Machine Configuration (optional)](#challenge-7---azure-automanage-machine-configuration---optional) - - [**Contributors**](#contributors) ## MicroHack introduction @@ -38,19 +37,19 @@ This MicroHack scenario walks through the use of Azure Arc with a focus on the b Further resources - Thomas Maurer & Lior Kamrat links -* [Azure Arc Overview Documentation](https://learn.microsoft.com/en-us/azure/azure-arc/overview) -* [Azure Arc Blog from Microsoft](https://techcommunity.microsoft.com/t5/azure-arc-blog/bg-p/AzureArcBlog) -* [Azure Arc Enabled Extended Security Updates](https://learn.microsoft.com/en-us/windows-server/get-started/extended-security-updates-deploy) -* [Azure Arc Jumpstart Scenarios](https://azurearcjumpstart.io/azure_arc_jumpstart/) -* [Azure Arc Jumpstart HCIBox](https://azurearcjumpstart.io/azure_jumpstart_hcibox/) -* [Azure Arc Jumpstart ArcBox](https://azurearcjumpstart.io/azure_jumpstart_arcbox/) -* [Azure Arc for Developers](https://techcommunity.microsoft.com/t5/itops-talk-blog/azure-arc-for-developers/ba-p/2561513) -* [Azure Arc for Cloud Solutions Architects](https://techcommunity.microsoft.com/t5/itops-talk-blog/azure-arc-for-cloud-solutions-architects/ba-p/2521928) -* [Azure Arc for IT Pros](https://techcommunity.microsoft.com/t5/itops-talk-blog/azure-arc-for-it-pros/ba-p/2347921) -* [Azure Arc for Security Engineers](https://techcommunity.microsoft.com/t5/itops-talk-blog/azure-arc-for-security-engineers/ba-p/2367830) -* [Learning Path Bring Azure innovation to your hybrid environments with Azure Arc](https://learn.microsoft.com/en-us/training/paths/manage-hybrid-infrastructure-with-azure-arc/) -* [Customer reference: Wüstenrot & Württembergische reduces patching time by 35 percent, leans into hybrid cloud management with Azure Arc](https://customers.microsoft.com/en-us/story/1538266003319018436-ww-azure-banking-and-capital-markets) -* [Introduction to Azure Arc landing zone accelerator for hybrid and multicloud](https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/scenarios/hybrid/enterprise-scale-landing-zone) +- [Azure Arc Overview Documentation](https://learn.microsoft.com/en-us/azure/azure-arc/overview) +- [Azure Arc Blog from Microsoft](https://techcommunity.microsoft.com/t5/azure-arc-blog/bg-p/AzureArcBlog) +- [Azure Arc Enabled Extended Security Updates](https://learn.microsoft.com/en-us/windows-server/get-started/extended-security-updates-deploy) +- [Azure Arc Jumpstart Scenarios](https://azurearcjumpstart.io/azure_arc_jumpstart/) +- [Azure Arc Jumpstart HCIBox](https://azurearcjumpstart.io/azure_jumpstart_hcibox/) +- [Azure Arc Jumpstart ArcBox](https://azurearcjumpstart.io/azure_jumpstart_arcbox/) +- [Azure Arc for Developers](https://techcommunity.microsoft.com/t5/itops-talk-blog/azure-arc-for-developers/ba-p/2561513) +- [Azure Arc for Cloud Solutions Architects](https://techcommunity.microsoft.com/t5/itops-talk-blog/azure-arc-for-cloud-solutions-architects/ba-p/2521928) +- [Azure Arc for IT Pros](https://techcommunity.microsoft.com/t5/itops-talk-blog/azure-arc-for-it-pros/ba-p/2347921) +- [Azure Arc for Security Engineers](https://techcommunity.microsoft.com/t5/itops-talk-blog/azure-arc-for-security-engineers/ba-p/2367830) +- [Learning Path Bring Azure innovation to your hybrid environments with Azure Arc](https://learn.microsoft.com/en-us/training/paths/manage-hybrid-infrastructure-with-azure-arc/) +- [Customer reference: Wüstenrot & Württembergische reduces patching time by 35 percent, leans into hybrid cloud management with Azure Arc](https://customers.microsoft.com/en-us/story/1538266003319018436-ww-azure-banking-and-capital-markets) +- [Introduction to Azure Arc landing zone accelerator for hybrid and multicloud](https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/scenarios/hybrid/enterprise-scale-landing-zone) 💡 Optional: Read this after completing this lab to deepen the learned! @@ -58,9 +57,9 @@ Further resources - Thomas Maurer & Lior Kamrat links After completing this MicroHack you will: -* Know how to use Azure Arc in your environment, on-prem or Multi-cloud -* Understand use cases and possible scenarios in your hybrid world to modernize your infrastructure estate -* Get insights into real world challenges and scenarios +- Know how to use Azure Arc in your environment, on-prem or Multi-cloud +- Understand use cases and possible scenarios in your hybrid world to modernize your infrastructure estate +- Get insights into real world challenges and scenarios ## MicroHack Challenges @@ -68,17 +67,17 @@ After completing this MicroHack you will: This MicroHack has a few but important prerequisites to be understood before starting this lab! -* Your own Azure subscription with Owner RBAC rights at the subscription level - * [Azure Evaluation free account](https://azure.microsoft.com/en-us/free/search/?OCID=AIDcmmzzaokddl_SEM_0fa7acb99db91c1fb85fcfd489e5ca6e:G:s&ef_id=0fa7acb99db91c1fb85fcfd489e5ca6e:G:s&msclkid=0fa7acb99db91c1fb85fcfd489e5ca6e) -* You need to have 3 virtual machines ready and updated. One with a Linux operating system (tested with Ubuntu Server 24.04), one with Windows Server 2025 and one with Windows Server 2012 R2 (optional). You can use machines in Azure for this following this guide: [Azure Arc Jumpstart Servers](https://azurearcjumpstart.io/azure_arc_jumpstart/azure_arc_servers/azure/) - > **Note** - > When using the Jumpstart the virtual machines will already be onboarded to Azure Arc and therefore "Challenge 1 - Azure Arc prerequisites & onboarding" is not needed. -* [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli) (Hint: Make sure to use the lastest version) -* [Azure PowerShell Guest Configuration Cmdlets](https://learn.microsoft.com/en-us/azure/governance/machine-configuration/machine-configuration-create-setup#install-the-module-from-the-powershell-gallery) - * It is not possible to run those commands from Azure Cloud Shell - * Please make sure you have at least Version 3.4.2 installes with the following Command: ```Install-Module -Name GuestConfiguration -RequiredVersion 3.4.2``` -* [Visual Studio Code](https://code.visualstudio.com/) -* [Git SCM](https://git-scm.com/download/) +- Your own Azure subscription with Owner RBAC rights at the subscription level + - [Azure Evaluation free account](https://azure.microsoft.com/en-us/free/search/?OCID=AIDcmmzzaokddl_SEM_0fa7acb99db91c1fb85fcfd489e5ca6e:G:s&ef_id=0fa7acb99db91c1fb85fcfd489e5ca6e:G:s&msclkid=0fa7acb99db91c1fb85fcfd489e5ca6e) +- You need to have 3 virtual machines ready and updated. One with a Linux operating system (tested with Ubuntu Server 24.04), one with Windows Server 2025 and one with Windows Server 2012 R2 (optional). You can use machines in Azure for this following [Evaluate Azure Arc-enabled servers on an Azure virtual machine](https://learn.microsoft.com/en-us/azure/azure-arc/servers/plan-evaluate-on-azure-virtual-machine) or [Azure Arc Jumpstart Servers](https://azurearcjumpstart.io/azure_arc_jumpstart/azure_arc_servers/azure/). + > **Note** + > When using the Jumpstart the **virtual machines will already be onboarded to Azure Arc** and therefore "Challenge 1 - Azure Arc prerequisites & onboarding" is not needed. So if you are looking for running through the onboarding process, you should use the "Evaluate Azure Arc-enabled Servers on an Azure virtual machine" for setting up the machines instead. +- [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli) (Hint: Make sure to use the lastest version) +- [Azure PowerShell Guest Configuration Cmdlets](https://learn.microsoft.com/en-us/azure/governance/machine-configuration/machine-configuration-create-setup#install-the-module-from-the-powershell-gallery) + - It is not possible to run those commands from Azure Cloud Shell + - Please make sure you have at least Version 3.4.2 installes with the following Command: `Install-Module -Name GuestConfiguration -RequiredVersion 3.4.2` +- [Visual Studio Code](https://code.visualstudio.com/) +- [Git SCM](https://git-scm.com/download/) ## Challenge 1 - Azure Arc prerequisites & onboarding @@ -88,26 +87,33 @@ In challenge 1 you will prepare your Azure environemnt for onboarding of existin ### Actions -* Create all necessary Azure resources - * Resource Group (Name: mh-arc-servers-rg) - * Service Principal (Name: mh-arc-servers-sp) -* Enable required Resource Providers -* Prep existing server operating system on-prem -* Onboard existing server to Azure Arc +- Create all necessary Azure resources + + - Resource Group (Name: mh-arc-servers-rg) + - Service Principal (Name: mh-arc-servers-sp) + > **❗Hint:** + > + > If you already have a serice principal provisioned as part of the workshop setup, you can skip the creation step. + +- Enable required Resource Providers +- Prep existing server operating system on-prem +- Onboard existing server to Azure Arc ### Success criteria -* You created an Azure resource group -* You created an service principal with the required role membership -* Prepared successfully an existing Server OS -* Onboarded server is visible in the Azure Arc plane in the Azure Portal +- You created an Azure resource group +- You created an service principal with the required role membership +- Prepared successfully an existing Server OS +- Onboarded server is visible in the Azure Arc plane in the Azure Portal ### Learning resources -* [Plan and deploy Azure Arc-enabled servers](https://learn.microsoft.com/en-us/azure/azure-arc/servers/plan-at-scale-deployment) -* [Prerequisites for Connect hybrid machines with Azure Arc-enabled servers](https://learn.microsoft.com/en-us/azure/azure-arc/servers/learn/quick-enable-hybrid-vm#prerequisites) -* [Connect hybrid machines with Azure Arc-enabled servers](https://learn.microsoft.com/en-us/azure/azure-arc/servers/learn/quick-enable-hybrid-vm#generate-installation-script) -* [Create a service principal for onboarding](https://learn.microsoft.com/en-us/azure/azure-arc/servers/onboard-service-principal#create-a-service-principal-for-onboarding-at-scale) +- [Plan and deploy Azure Arc-enabled servers](https://learn.microsoft.com/en-us/azure/azure-arc/servers/plan-at-scale-deployment) +- [Prerequisites for Connect hybrid machines with Azure Arc-enabled servers](https://learn.microsoft.com/en-us/azure/azure-arc/servers/learn/quick-enable-hybrid-vm#prerequisites) +- [Connect hybrid machines with Azure Arc-enabled servers](https://learn.microsoft.com/en-us/azure/azure-arc/servers/learn/quick-enable-hybrid-vm#generate-installation-script) +- [Create a service principal for onboarding](https://learn.microsoft.com/en-us/azure/azure-arc/servers/onboard-service-principal#create-a-service-principal-for-onboarding-at-scale) +- [Evaluate Azure Arc-enabled servers on an Azure virtual machine](https://learn.microsoft.com/en-us/azure/azure-arc/servers/plan-evaluate-on-azure-virtual-machine) +- [Azure Arc Jumpstart Servers](https://azurearcjumpstart.io/azure_arc_jumpstart/azure_arc_servers/azure/) ### Solution - Spoilerwarning @@ -121,34 +127,32 @@ In challenge 2 you will onboard your Windows and Linux virtual machines to Azure ### Actions -* Create all necessary Azure resources - * Log Analytics workspace (Name: mh-arc-servers-kv-law) -* Configure Data Collection Rules in Log Analytics to collect Windows event logs and Linux syslog -* Enable Azure Monitor for Azure Arc enabled servers with Azure Policy initiative -* Enable and configure Update Management -* Enable Change Tracking and Inventory -* Enable VM Insights - +- Create all necessary Azure resources + - Log Analytics workspace (Name: mh-arc-servers-kv-law) +- Configure Data Collection Rules in Log Analytics to collect Windows event logs and Linux syslog +- Enable Azure Monitor for Azure Arc enabled servers with Azure Policy initiative +- Enable and configure Update Management +- Enable Change Tracking and Inventory +- Enable VM Insights ### Success criteria -* You have a Log Analytics Workspace -* You successfully linked the necessary Azure Policy initiative to the Azure resource group -* You can query the Log Analytics Workspace for events of your virtual machines -* All virtual machines have the latest Windows and Linux updates installed -* You can browse through the software inventory of your virtual machines -* You can use VM Insights to get a detailed view of your virtual machines +- You have a Log Analytics Workspace +- You successfully linked the necessary Azure Policy initiative to the Azure resource group +- You can query the Log Analytics Workspace for events of your virtual machines +- All virtual machines have the latest Windows and Linux updates installed +- You can browse through the software inventory of your virtual machines +- You can use VM Insights to get a detailed view of your virtual machines ### Learning resources -* [Create a Log Analytics workspace in the Azure portal](https://docs.microsoft.com/en-us/azure/azure-monitor/logs/quick-create-workspace) -* [Deployment options for Azure Monitor agent on Azure Arc-enabled servers](https://learn.microsoft.com/en-us/azure/azure-arc/servers/concept-log-analytics-extension-deployment) -* [Data collection rules in Azure Monitor](https://learn.microsoft.com/en-us/azure/azure-monitor/essentials/data-collection-rule-overview) -* [Azure Policy built-in definitions for Azure Arc-enabled servers](https://docs.microsoft.com/en-us/azure/azure-arc/servers/policy-reference) -* [Azure Update Management Center](https://learn.microsoft.com/en-us/azure/update-center/overview) -* [Enable Change Tracking and Inventory using Azure Monitoring Agent (Preview)](https://learn.microsoft.com/en-us/azure/automation/change-tracking/enable-vms-monitoring-agent?tabs=singlevm) -* [Monitor a hybrid machine with VM insights](https://docs.microsoft.com/en-us/azure/azure-arc/servers/learn/tutorial-enable-vm-insights) - +- [Create a Log Analytics workspace in the Azure portal](https://docs.microsoft.com/en-us/azure/azure-monitor/logs/quick-create-workspace) +- [Deployment options for Azure Monitor agent on Azure Arc-enabled servers](https://learn.microsoft.com/en-us/azure/azure-arc/servers/concept-log-analytics-extension-deployment) +- [Data collection rules in Azure Monitor](https://learn.microsoft.com/en-us/azure/azure-monitor/essentials/data-collection-rule-overview) +- [Azure Policy built-in definitions for Azure Arc-enabled servers](https://docs.microsoft.com/en-us/azure/azure-arc/servers/policy-reference) +- [Azure Update Management Center](https://learn.microsoft.com/en-us/azure/update-center/overview) +- [Enable Change Tracking and Inventory using Azure Monitoring Agent (Preview)](https://learn.microsoft.com/en-us/azure/automation/change-tracking/enable-vms-monitoring-agent?tabs=singlevm) +- [Monitor a hybrid machine with VM insights](https://docs.microsoft.com/en-us/azure/azure-arc/servers/learn/tutorial-enable-vm-insights) ### Solution - Spoilerwarning @@ -158,24 +162,24 @@ In challenge 2 you will onboard your Windows and Linux virtual machines to Azure ### Goal -Managing secrets, credentials or certificates to secure communication between different services is a main challenge for developers and administrators. Managed Identities is Azure's answer to all these challenges and eliminates the need to manage and securely store secrets, credentials or certificates on the virtual machine. In challenge 3 you will leverage Managed Identities via Azure Arc to securely access an Azure Key Vault secret from your Azure Arc enabled servers without the need of managing any credential. +Managing secrets, credentials or certificates to secure communication between different services is a main challenge for developers and administrators. Managed Identities is Azure's answer to all these challenges and eliminates the need to manage and securely store secrets, credentials or certificates on the virtual machine. In challenge 3 you will leverage Managed Identities via Azure Arc to securely access an Azure Key Vault secret from your Azure Arc enabled servers without the need of managing any credential. ### Actions -* Create an Azure Key Vault in your Azure resource group -* Create a secret in the Azure Key Vault and assign permissions to your virtual machine vm-linux-mh0 -* Access the secret via bash script +- Create an Azure Key Vault in your Azure resource group +- Create a secret in the Azure Key Vault and assign permissions to your virtual machine vm-linux-mh0 +- Access the secret via bash script ### Success Criteria -* You successfully output the secret in the terminal on your Linux server without providing any credentials (except for your SSH login 😊). +- You successfully output the secret in the terminal on your Linux server without providing any credentials (except for your SSH login 😊). ### Learning resources -* [Create a key vault using the Azure portal](https://docs.microsoft.com/en-us/azure/key-vault/general/quick-create-portal) -* [Set and retrieve a secret from Azure Key Vault using the Azure portal](https://docs.microsoft.com/en-us/azure/key-vault/secrets/quick-create-portal) -* [Use a Linux VM system-assigned managed identity to access Azure Key Vault](https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/tutorial-linux-vm-access-nonaad) -* [Authenticate against Azure resources with Azure Arc-enabled servers](https://docs.microsoft.com/en-us/azure/azure-arc/servers/managed-identity-authentication) +- [Create a key vault using the Azure portal](https://docs.microsoft.com/en-us/azure/key-vault/general/quick-create-portal) +- [Set and retrieve a secret from Azure Key Vault using the Azure portal](https://docs.microsoft.com/en-us/azure/key-vault/secrets/quick-create-portal) +- [Use a Linux VM system-assigned managed identity to access Azure Key Vault](https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/tutorial-linux-vm-access-nonaad) +- [Authenticate against Azure resources with Azure Arc-enabled servers](https://docs.microsoft.com/en-us/azure/azure-arc/servers/managed-identity-authentication) ### Solution - Spoilerwarning @@ -185,24 +189,23 @@ Managing secrets, credentials or certificates to secure communication between di ### Goal -* In this challenge, we will integrate your Azure Arc connected machines with Azure Defender for Cloud. After completing the previous challenges, you should now have an Azure subscription with one or more Azure Arc-enabled servers. You should also have an available Log Analytics workspace and have deployed the Log Analytics agent to your server(s). +- In this challenge, we will integrate your Azure Arc connected machines with Azure Defender for Cloud. After completing the previous challenges, you should now have an Azure subscription with one or more Azure Arc-enabled servers. You should also have an available Log Analytics workspace and have deployed the Log Analytics agent to your server(s). ### Actions -* Enable Microsoft Defender for Cloud on your Azure Arc-enabled machines. +- Enable Microsoft Defender for Cloud on your Azure Arc-enabled machines. ### Success criteria -* Open Microsoft Defender for Cloud and view the Secure Score for your Azure Arc-enabled machine(s). +- Open Microsoft Defender for Cloud and view the Secure Score for your Azure Arc-enabled machine(s). ### Learning resources -* [What is Microsoft Defender for Cloud?](https://learn.microsoft.com/en-us/azure/defender-for-cloud/defender-for-cloud-introduction) -* [Quickstart: Connect your non-Azure machines to Microsoft Defender for Cloud](https://learn.microsoft.com/en-us/azure/defender-for-cloud/quickstart-onboard-machines?pivots=azure-arc) -* [Connect Azure Arc-enabled servers to Microsoft Defender for Cloud](https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/manage/hybrid/server/best-practices/arc-security-center) -* [Protect non-Azure resources using Azure Arc and Microsoft Defender for Cloud](https://techcommunity.microsoft.com/t5/microsoft-defender-for-cloud/protect-non-azure-resources-using-azure-arc-and-microsoft/ba-p/2277215) -* [Deploy the Azure Monitor Agent to protect your servers with Microsoft Defender for Cloud](https://learn.microsoft.com/en-us/azure/defender-for-cloud/auto-deploy-azure-monitoring-agent) - +- [What is Microsoft Defender for Cloud?](https://learn.microsoft.com/en-us/azure/defender-for-cloud/defender-for-cloud-introduction) +- [Quickstart: Connect your non-Azure machines to Microsoft Defender for Cloud](https://learn.microsoft.com/en-us/azure/defender-for-cloud/quickstart-onboard-machines?pivots=azure-arc) +- [Connect Azure Arc-enabled servers to Microsoft Defender for Cloud](https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/manage/hybrid/server/best-practices/arc-security-center) +- [Protect non-Azure resources using Azure Arc and Microsoft Defender for Cloud](https://techcommunity.microsoft.com/t5/microsoft-defender-for-cloud/protect-non-azure-resources-using-azure-arc-and-microsoft/ba-p/2277215) +- [Deploy the Azure Monitor Agent to protect your servers with Microsoft Defender for Cloud](https://learn.microsoft.com/en-us/azure/defender-for-cloud/auto-deploy-azure-monitoring-agent) ### Solution - Spoilerwarning @@ -216,20 +219,19 @@ In this challenge, you will configure and deploy the Best Practices Assessment f ### Actions -* Set Up Best Practices Assessment for one machine -* Run the Best Practices Assessment -* Analyze Results +- Set Up Best Practices Assessment for one machine +- Run the Best Practices Assessment +- Analyze Results ### Success criteria -* Best Practices Assessment is enabled and installed on your Arc-enabled Windows Server -* The Assessment Platform, Windows Server Assessment, and Azure Monitor Agent (AMA) extensions are installed successfully -* The first Best Practices Assessment is run successfully +- Best Practices Assessment is enabled and installed on your Arc-enabled Windows Server +- The Assessment Platform, Windows Server Assessment, and Azure Monitor Agent (AMA) extensions are installed successfully +- The first Best Practices Assessment is run successfully ### Learning resources -* [Configure Best Practices Assessment for Arc-enabled Windows servers](https://learn.microsoft.com/en-us/windows-server/manage/azure-arc/best-practices-assessment-for-windows-server) - +- [Configure Best Practices Assessment for Arc-enabled Windows servers](https://learn.microsoft.com/en-us/windows-server/manage/azure-arc/best-practices-assessment-for-windows-server) ### Solution - Spoilerwarning @@ -243,18 +245,21 @@ In this challenge, you will activate Extended Security Updates (ESU) for Windows ### Actions -* Purchase and activate the ESU license for your Windows Server 2012 R2. -* Apply the ESU license to your server. +- Purchase and activate the ESU license for your Windows Server 2012 R2. +- Apply the ESU license to your server. + +> **:warning: IMPORTANT :warning:** +> In this challenge you will puchase an ESU license which will incur the cost displayed during the process. Please be aware that the overall cost also includes back-billing as per the rules of ESU licensing. While the montly billing will stop once the license is deactivated, the back-billing will be final. ### Success criteria -* The ESU license is purchased and activated. -* The server has an attached ESU license and its ESU status shows as "Enabled" +- The ESU license is purchased and activated. +- The server has an attached ESU license and its ESU status shows as "Enabled" ### Learning resources -* [Extended Security Updates for Windows Server 2012 and 2012 R2](https://learn.microsoft.com/en-us/lifecycle/faq/extended-security-updates) -* [Deploy Extended Security Updates using Azure Arc](https://learn.microsoft.com/en-us/azure/azure-arc/servers/prepare-extended-security-updates?tabs=azure-cloud) +- [Extended Security Updates for Windows Server 2012 and 2012 R2](https://learn.microsoft.com/en-us/lifecycle/faq/extended-security-updates) +- [Deploy Extended Security Updates using Azure Arc](https://learn.microsoft.com/en-us/azure/azure-arc/servers/prepare-extended-security-updates?tabs=azure-cloud) ### Solution - Spoilerwarning @@ -268,23 +273,23 @@ This challenge is about interacting with the client operating system. We will ha ### Actions -* Create all necessary Azure resources - * Azure Storage account -* Setup a Policy that checks if the user "FrodoBaggins" is part of the local administrators group -* Setup a Custom Machine Configuration, for the Windows Server, that creates a registry key in ``` HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment\ ``` +- Create all necessary Azure resources + - Azure Storage account +- Setup a Policy that checks if the user "FrodoBaggins" is part of the local administrators group +- Setup a Custom Machine Configuration, for the Windows Server, that creates a registry key in `HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment\` ### Success criteria -* You can view the compliance state of the Administrator Group Policy -* You can show the registry key being present on the Windows Server +- You can view the compliance state of the Administrator Group Policy +- You can show the registry key being present on the Windows Server ### Learning resources -* [Understand the machine configuration feature of Azure Automanage](https://learn.microsoft.com/en-us/azure/governance/machine-configuration/overview) -* [How to setup a machine configuration authoring environment](https://learn.microsoft.com/en-us/azure/governance/machine-configuration/machine-configuration-create-setup) -* [How to create custom machine configuration package artifacts](https://learn.microsoft.com/en-us/azure/governance/machine-configuration/machine-configuration-create) -* [How to create custom machine configuration policy definitions](https://learn.microsoft.com/en-us/azure/governance/machine-configuration/machine-configuration-create-definition) -* [Create SAS tokens for storage containers](https://learn.microsoft.com/en-us/azure/applied-ai-services/form-recognizer/create-sas-tokens) +- [Understand the machine configuration feature of Azure Automanage](https://learn.microsoft.com/en-us/azure/governance/machine-configuration/overview) +- [How to setup a machine configuration authoring environment](https://learn.microsoft.com/en-us/azure/governance/machine-configuration/machine-configuration-create-setup) +- [How to create custom machine configuration package artifacts](https://learn.microsoft.com/en-us/azure/governance/machine-configuration/machine-configuration-create) +- [How to create custom machine configuration policy definitions](https://learn.microsoft.com/en-us/azure/governance/machine-configuration/machine-configuration-create-definition) +- [Create SAS tokens for storage containers](https://learn.microsoft.com/en-us/azure/applied-ai-services/form-recognizer/create-sas-tokens) ### Solution - Spoilerwarning @@ -297,10 +302,10 @@ If you want to give feedback please dont hesitate to open an Issue on the reposi Thank you for investing the time and see you next time! - ## Contributors -* Adrian Schöne [GitHub](https://github.com/adriandiver); [LinkedIn](https://www.linkedin.com/in/adrian-schoene//) -* Christian Thönes [Github](https://github.com/cthoenes); [LinkedIn](https://www.linkedin.com/in/christian-t-510b7522/) -* Nils Bankert [GitHub](https://github.com/nilsbankert); [LinkedIn](https://www.linkedin.com/in/nilsbankert/) -* Alexander Ortha [GitHub](https://github.com/alexor-ms/); [LinkedIn](https://www.linkedin.com/in/alexanderortha/) -* Christoph Süßer (Schmidt) [GitHub](https://github.com/TheFitzZZ); [LinkedIn](https://www.linkedin.com/in/suesser/) \ No newline at end of file + +- Adrian Schöne [GitHub](https://github.com/adriandiver); [LinkedIn](https://www.linkedin.com/in/adrian-schoene//) +- Christian Thönes [Github](https://github.com/cthoenes); [LinkedIn](https://www.linkedin.com/in/christian-t-510b7522/) +- Nils Bankert [GitHub](https://github.com/nilsbankert); [LinkedIn](https://www.linkedin.com/in/nilsbankert/) +- Alexander Ortha [GitHub](https://github.com/alexor-ms/); [LinkedIn](https://www.linkedin.com/in/alexanderortha/) +- Christoph Süßer (Schmidt) [GitHub](https://github.com/TheFitzZZ); [LinkedIn](https://www.linkedin.com/in/suesser/) diff --git a/03-Azure/01-03-Infrastructure/02_Hybrid_Azure_Arc_Servers/walkthrough/challenge-6/solution.md b/03-Azure/01-03-Infrastructure/02_Hybrid_Azure_Arc_Servers/walkthrough/challenge-6/solution.md index 770d23d6..02d5cbbc 100644 --- a/03-Azure/01-03-Infrastructure/02_Hybrid_Azure_Arc_Servers/walkthrough/challenge-6/solution.md +++ b/03-Azure/01-03-Infrastructure/02_Hybrid_Azure_Arc_Servers/walkthrough/challenge-6/solution.md @@ -3,45 +3,47 @@ Duration: 15 minutes [Previous Challenge Solution](../challenge-5/solution.md) - **[Home](../../Readme.md)** +request with the Azure Arc agent to Azure.` +> **:warning: IMPORTANT :warning:** +> In this challenge you will puchase an ESU license which will incur the cost displayed during the process. Please be aware that the overall cost also includes back-billing as per the rules of ESU licensing. While the montly billing will stop once the license is deactivated, the back-billing will be final. ## Task 1: Create a Windows Server ESU license 1. Navigate to the Azure Arc center and click "Licenses" and "Windows Server ESU licenses" (or click [here](https://portal.azure.com/#view/Microsoft_Azure_ArcCenterUX/ArcCenterMenuBlade/~/license)) 2. Click "Create" on the top bar. A new blade will open. 3. Fill in the required field: - - Subscription and Resource group (where you created your previous objects) - - A license name - should only contain letters (both uppercase and lowercase), digits, hyphens, underscores, and periods. Consecutive dots are not allowed. - - Select "Activate now" (you could create one with "Activate later" but cannot attach it to a server then) - - Keep "West Europe" as the selected region - - Select virtual cores with 8 total - - De-select the "Have an invoice?" checkbox at the bottom - - Make sure the Software Assurance box is checked, and then click "Create" - ![alt text](img/image1.png) - ![alt text](img/image2.png) - - Wait a couple of moments and click "Refresh" in the license overview. Your new item will apprear: - ![alt text](img/image3.png) -### - + - Subscription and Resource group (where you created your previous objects) + - A license name - should only contain letters (both uppercase and lowercase), digits, hyphens, underscores, and periods. Consecutive dots are not allowed. + - Select "Activate now" (you could create one with "Activate later" but cannot attach it to a server then) + - Keep "West Europe" as the selected region + - Select virtual cores with 8 total + - De-select the "Have an invoice?" checkbox at the bottom + - Make sure the Software Assurance box is checked, and then click "Create" + ![alt text](img/image1.png) + ![alt text](img/image2.png) + - Wait a couple of moments and click "Refresh" in the license overview. Your new item will apprear: + ![alt text](img/image3.png) +### -## Task 2: Attach the ESU license to the server: +## Task 2: Attach the ESU license to the server: 1. Navigate to the Azure Arc center and click "Licenses" and "Windows Server ESU licenses" (or click [here](https://portal.azure.com/#view/Microsoft_Azure_ArcCenterUX/ArcCenterMenuBlade/~/license)) 2. Click "Eligible resources" on the top to get a list of Arc enabled server that are eligible to use an ESU license 3. Select your Windows 2012 server and click "Enable ESUs" -![alt text](img/image4.png) + ![alt text](img/image4.png) 4. Select "Virtual Cores" which will then allow you to select your previously created license -![alt text](img/image5.png) + ![alt text](img/image5.png) 5. Click "Enable" to attach the license to the server 6. The overview, once refreshed, will now report the server es ESU enabled - ![alt text](img/image6.png) - - + ![alt text](img/image6.png) ### + **Congratulations!** You successfully completed the challenge! 🚀🚀🚀 -### Optional Steps: -1. Check for Windows Updates and observe that new security rollups are being downloaded and installed \ No newline at end of file +### Optional Steps: + +1. Check for Windows Updates and observe that new security rollups are being downloaded and installed diff --git a/03-Azure/01-03-Infrastructure/06_Migration_Secure_AI_Ready/Readme.md b/03-Azure/01-03-Infrastructure/06_Migration_Secure_AI_Ready/Readme.md index b6ad5287..72c224c6 100644 --- a/03-Azure/01-03-Infrastructure/06_Migration_Secure_AI_Ready/Readme.md +++ b/03-Azure/01-03-Infrastructure/06_Migration_Secure_AI_Ready/Readme.md @@ -14,23 +14,25 @@ This MicroHack scenario walks through the process how to optimize and modernize This lab is not a full explanation of building up a migration factory or a program to modernize your processes and dependencies. Please consider the following articles required pre-reading to build foundational knowledge. -* [Understand the security baseline from Azure Migrate](https://learn.microsoft.com/en-us/security/benchmark/azure/baselines/azure-migrate-security-baseline?context=%2Fazure%2Fmigrate%2Fcontext%2Fmigrate-context) -* [Build a migration plan](https://learn.microsoft.com/en-us/azure/migrate/concepts-migration-planning) -* [Assessment overview VM´s](https://learn.microsoft.com/en-us/azure/migrate/concepts-assessment-calculation) -* [Assessment overview App Service](https://learn.microsoft.com/en-us/azure/migrate/concepts-azure-webapps-assessment-calculation) -* [Assessment overview SQL](https://learn.microsoft.com/en-us/azure/migrate/concepts-azure-sql-assessment-calculation) -* [Azure Arc Enabled Extended Security Updates](https://learn.microsoft.com/en-us/windows-server/get-started/extended-security-updates-deploy) +- [Understand the security baseline from Azure Migrate](https://learn.microsoft.com/en-us/security/benchmark/azure/baselines/azure-migrate-security-baseline?context=%2Fazure%2Fmigrate%2Fcontext%2Fmigrate-context) +- [Build a migration plan](https://learn.microsoft.com/en-us/azure/migrate/concepts-migration-planning) +- [Assessment overview VM´s](https://learn.microsoft.com/en-us/azure/migrate/concepts-assessment-calculation) +- [Assessment overview App Service](https://learn.microsoft.com/en-us/azure/migrate/concepts-azure-webapps-assessment-calculation) +- [Assessment overview SQL](https://learn.microsoft.com/en-us/azure/migrate/concepts-azure-sql-assessment-calculation) +- [Azure Arc Enabled Extended Security Updates](https://learn.microsoft.com/en-us/windows-server/get-started/extended-security-updates-deploy) Optional (read this after completing this lab to take your learning even deeper!) -* [Web apps migration support](https://learn.microsoft.com/en-us/azure/migrate/concepts-migration-webapps) -* [Support matrix for vSphere migration](https://learn.microsoft.com/en-us/azure/migrate/migrate-support-matrix-vmware-migration) -* [VMWare agentless migration architecture](https://learn.microsoft.com/en-us/azure/migrate/concepts-vmware-agentless-migration) -* [Support matrix for Hyper-V migration](https://learn.microsoft.com/en-us/azure/migrate/migrate-support-matrix-hyper-v-migration) -* [Hyper-V migration architecture](https://learn.microsoft.com/en-us/azure/migrate/hyper-v-migration-architecture) -* [Troubleshooting guide](https://learn.microsoft.com/en-us/azure/migrate/troubleshoot-general) + +- [Web apps migration support](https://learn.microsoft.com/en-us/azure/migrate/concepts-migration-webapps) +- [Support matrix for vSphere migration](https://learn.microsoft.com/en-us/azure/migrate/migrate-support-matrix-vmware-migration) +- [VMWare agentless migration architecture](https://learn.microsoft.com/en-us/azure/migrate/concepts-vmware-agentless-migration) +- [Support matrix for Hyper-V migration](https://learn.microsoft.com/en-us/azure/migrate/migrate-support-matrix-hyper-v-migration) +- [Hyper-V migration architecture](https://learn.microsoft.com/en-us/azure/migrate/hyper-v-migration-architecture) +- [Troubleshooting guide](https://learn.microsoft.com/en-us/azure/migrate/troubleshoot-general) # MicroHack context -This MicroHack scenario walks through the use of Azure Migrate to support the process and the different phases of datacenter modernization: + +This MicroHack scenario walks through the use of Azure Migrate to support the process and the different phases of datacenter modernization: - Discover - Decide @@ -41,14 +43,15 @@ This MicroHack scenario walks through the use of Azure Migrate to support the pr As part of the MicroHack, we will simulate the discovery and migration of physical servers to Azure. We will create the source systems as Azure Virtual Machines within a dedicated source Resource Group in Azure to simulate the on-prem datacenter. We will use Azure Migrate to discover, assess and migrate the systems into a destination Resource Group that simulates the target Azure environment. The concept behind physical server discovery and migration is described in detail under the following links: -* [Physical Server discovery](https://learn.microsoft.com/en-us/azure/migrate/migrate-support-matrix-physical) -* [Physical Server migration](https://learn.microsoft.com/en-us/azure/migrate/migrate-support-matrix-physical-migration) + +- [Physical Server discovery](https://learn.microsoft.com/en-us/azure/migrate/migrate-support-matrix-physical) +- [Physical Server migration](https://learn.microsoft.com/en-us/azure/migrate/migrate-support-matrix-physical-migration) # Objectives After completing this MicroHack you will: -- Know how to build an assessment & business case for you datacenter transformation +- Know how to build an assessment & business case for you datacenter transformation - Understand the default and best practices how to quickly migrate workloads and safe with right sizing - Understand how to use the tools and best practices to optimize and safe time - Know how to not only use the tools to Lift & Shift, you will also understand how to modernize to cloud native services @@ -61,9 +64,9 @@ This MicroHack has a few but important prerequisites In order to use the MicroHack time most effectively, the following prerequisites should be completed prior to starting the session. -* Entra ID Tenant -* At least one Azure Subscription -* Entra ID user with Contributor or Owner permissions on the Azure Subscription +- Entra ID Tenant +- At least one Azure Subscription +- Entra ID user with Contributor or Owner permissions on the Azure Subscription With these pre-requisites in place, we can focus on building the differentiated knowledge in Azure Migrate that is required when working with the product. @@ -71,8 +74,8 @@ With these pre-requisites in place, we can focus on building the differentiated ### Goal -- Deploy a *source* resource group with two VMs and their dependencies that act as our physical on-premise servers that will be migrated to Azure. -- Deploy a *destination* resource group to which the servers will be migrated. +- Deploy a _source_ resource group with two VMs and their dependencies that act as our physical on-premise servers that will be migrated to Azure. +- Deploy a _destination_ resource group to which the servers will be migrated. ### Actions @@ -82,7 +85,7 @@ With these pre-requisites in place, we can focus on building the differentiated - You have understood the concept and architecture for the MicroHack. - The Bicep deployment command exits successfully. -- The *source* and *destination* resource group is visible in the Azure Portal. +- The _source_ and _destination_ resource group is visible in the Azure Portal. ### Learning resources @@ -94,36 +97,37 @@ With these pre-requisites in place, we can focus on building the differentiated ## Challenge 2 - Discover physical servers for the migration -### Goal +### Goal The goal of this exercise is to... -* Setup Azure Migrate Project in Azure -* Installing / Deploying the necessary setup for discovery -* Create a discovery +- Setup Azure Migrate Project in Azure +- Installing / Deploying the necessary setup for discovery +- Create a discovery ### Actions -* Create a Azure Migrate Project -> [!IMPORTANT] -> To be able to create a Business Case, make sure to select Europe as the Geography for the Azure Migrate Project -* Deploy a Azure Migrate Appliance -* Create a continuous discovery of your source environment +- Create a Azure Migrate Project + > [!IMPORTANT] + > To be able to create a Business Case, make sure to select Europe as the Geography for the Azure Migrate Project +- Deploy a Azure Migrate Appliance +- Create a continuous discovery of your source environment ### Success criteria -* You have created a Azure Migrate Project -* You have successfully deployed the Azure Migrate Appliance -* You successfully registered the Azure Migrate Appliance with the Azure Migrate Project -* You have successfully setup a continuous discovery for the physical servers. -* You have successfully verified the discovered servers in the portal +- You have created a Azure Migrate Project +- You have successfully deployed the Azure Migrate Appliance +- You successfully registered the Azure Migrate Appliance with the Azure Migrate Project +- You have successfully setup a continuous discovery for the physical servers. +- You have successfully verified the discovered servers in the portal ### Learning resources -* [Create and managed Azure Migrate projects](https://learn.microsoft.com/en-us/azure/migrate/create-manage-projects) -* [Setup and appliance on VMWare](https://learn.microsoft.com/en-us/azure/migrate/how-to-set-up-appliance-vmware) -* [Setup and appliance on Hyper-V](https://learn.microsoft.com/en-us/azure/migrate/how-to-set-up-appliance-hyper-v) -* [Steup an appliance for physical servers](https://learn.microsoft.com/en-us/azure/migrate/how-to-set-up-appliance-physical) -* [Before you start / general prerequisites](https://learn.microsoft.com/en-us/azure/migrate/how-to-discover-applications#before-you-start) + +- [Create and managed Azure Migrate projects](https://learn.microsoft.com/en-us/azure/migrate/create-manage-projects) +- [Setup and appliance on VMWare](https://learn.microsoft.com/en-us/azure/migrate/how-to-set-up-appliance-vmware) +- [Setup and appliance on Hyper-V](https://learn.microsoft.com/en-us/azure/migrate/how-to-set-up-appliance-hyper-v) +- [Steup an appliance for physical servers](https://learn.microsoft.com/en-us/azure/migrate/how-to-set-up-appliance-physical) +- [Before you start / general prerequisites](https://learn.microsoft.com/en-us/azure/migrate/how-to-discover-applications#before-you-start) ### Solution - Spoilerwarning @@ -131,7 +135,7 @@ The goal of this exercise is to... ## Challenge 3 - Create a Business Case -The Business case capability helps you build a business proposal to understand how Azure can bring the most value to your business. +The Business case capability helps you build a business proposal to understand how Azure can bring the most value to your business. It highlights: @@ -147,7 +151,7 @@ Other key features: - It can be generated in just a few clicks after you have performed discovery using the Azure Migrate appliance. - The feature is automatically enabled for existing Azure Migrate projects. -### Goal +### Goal The goal of this exercise is to create a business case. The Business case capability helps you build a business proposal to understand how Azure can bring the most value to your business. It highlights: @@ -162,58 +166,59 @@ The goal of this exercise is to create a business case. The Business case capabi ### Actions -* Build a business case -* Review a business case -* Adjust business case assumptions +- Build a business case +- Review a business case +- Adjust business case assumptions ### Success criteria -* You successfully build a business case -* You have successfully reviewed the business case -* You understand how to adjust the business case assumptions +- You successfully build a business case +- You have successfully reviewed the business case +- You understand how to adjust the business case assumptions ### Learning resources -* [Business case overview](https://learn.microsoft.com/en-us/azure/migrate/concepts-business-case-calculation) -* [Build a business case](https://learn.microsoft.com/en-us/azure/migrate/how-to-build-a-business-case) -* [Review a business case](https://learn.microsoft.com/en-us/azure/migrate/how-to-view-a-business-case) + +- [Business case overview](https://learn.microsoft.com/en-us/azure/migrate/concepts-business-case-calculation) +- [Build a business case](https://learn.microsoft.com/en-us/azure/migrate/how-to-build-a-business-case) +- [Review a business case](https://learn.microsoft.com/en-us/azure/migrate/how-to-view-a-business-case) ### Solution - Spoilerwarning [Solution Steps](./walkthrough/challenge-3/solution.md) - ## Challenge 4 - Assess VM´s for the migration In most cases, you don't want to migrate all machines at once, but want to prioritize workload by workload and even understand what the dependencies between workloads are. You then look at each phase or wave of migration and break down the risks and workloads. -### Goal +### Goal The goal of this exercise is to ... -* measure the readiness and estimates the effect of migrating on-premises servers to Azure -* review the assessment output to understand the readiness and sizing recommendations -* review the dependencies between the discovered servers +- measure the readiness and estimates the effect of migrating on-premises servers to Azure +- review the assessment output to understand the readiness and sizing recommendations +- review the dependencies between the discovered servers ### Actions -* Group machines for the assessment -* Create an Azure VM assessment -* Review assessment output and recommendations -* Enable and review dependency analysis +- Group machines for the assessment +- Create an Azure VM assessment +- Review assessment output and recommendations +- Enable and review dependency analysis ### Success criteria -* You created a machine group -* You successfully created an Azure VM assessment -* You reviewed the assessment output and recommendations -* You enabled and reviewed the dependencies of the discovered server +- You created a machine group +- You successfully created an Azure VM assessment +- You reviewed the assessment output and recommendations +- You enabled and reviewed the dependencies of the discovered server ### Learning resources -* [Assessment overview - To Azure VMs](https://learn.microsoft.com/en-us/azure/migrate/concepts-assessment-calculation) -* [Select assessment tools](https://learn.microsoft.com/en-us/azure/migrate/how-to-assess) -* [Create a group for assessment](https://learn.microsoft.com/en-us/azure/migrate/how-to-create-a-group) -* [Create an Azure VM assessment](https://learn.microsoft.com/en-us/azure/migrate/how-to-create-assessment) -* [Customize an assessment](https://learn.microsoft.com/en-us/azure/migrate/how-to-modify-assessment) + +- [Assessment overview - To Azure VMs](https://learn.microsoft.com/en-us/azure/migrate/concepts-assessment-calculation) +- [Select assessment tools](https://learn.microsoft.com/en-us/azure/migrate/how-to-assess) +- [Create a group for assessment](https://learn.microsoft.com/en-us/azure/migrate/how-to-create-a-group) +- [Create an Azure VM assessment](https://learn.microsoft.com/en-us/azure/migrate/how-to-create-assessment) +- [Customize an assessment](https://learn.microsoft.com/en-us/azure/migrate/how-to-modify-assessment) ### Solution - Spoilerwarning @@ -221,36 +226,37 @@ The goal of this exercise is to ... ## Challenge 5 - Migrate machines to Azure -### Goal +### Goal The goal of this exercise is to ... -* understand the different migration options and prerequisites provided by Azure Migrate -* perform a test migration of the desired workload -* keep downtime as short as possible -* perform the final migration towards Azure +- understand the different migration options and prerequisites provided by Azure Migrate +- perform a test migration of the desired workload +- keep downtime as short as possible +- perform the final migration towards Azure ### Actions -* Setup the Azure Replication Appliance -* Deploy the Mobility Service Agent -* Replicate the machines to Azure -* Perform a Test Migration -* Prepare the final Migration -* Migrate the workload to Azure +- Setup the Azure Replication Appliance +- Deploy the Mobility Service Agent +- Replicate the machines to Azure +- Perform a Test Migration +- Prepare the final Migration +- Migrate the workload to Azure ### Success criteria -* All the source machines are successfully migrated to and running in Azure -* The Web Servers are seamlessly accessible using a Traffic Manager profile via dedicated Public Load Balancer. +- All the source machines are successfully migrated to and running in Azure +- The Web Servers are seamlessly accessible using a Traffic Manager profile via dedicated Public Load Balancer. ### Learning resources -* [Support matrix for migration of physical servers, AWS VMs, and GCP VMs](https://learn.microsoft.com/en-us/azure/migrate/migrate-support-matrix-physical-migration) -* [Migrate Hyper-V VM´s to Azure](https://learn.microsoft.com/en-us/azure/migrate/tutorial-migrate-hyper-v) -* [Migrate options for VMWare to Azure](https://learn.microsoft.com/en-us/azure/migrate/server-migrate-overview) -* [Migrate Physical Servers](https://learn.microsoft.com/en-us/azure/migrate/tutorial-migrate-physical-virtual-machines) -* [Migrate AWS Instances to Azure](https://learn.microsoft.com/en-us/azure/migrate/tutorial-migrate-aws-virtual-machines) -* [Migrate GCP Instances to Azure](https://learn.microsoft.com/en-us/azure/migrate/tutorial-migrate-gcp-virtual-machines) + +- [Support matrix for migration of physical servers, AWS VMs, and GCP VMs](https://learn.microsoft.com/en-us/azure/migrate/migrate-support-matrix-physical-migration) +- [Migrate Hyper-V VM´s to Azure](https://learn.microsoft.com/en-us/azure/migrate/tutorial-migrate-hyper-v) +- [Migrate options for VMWare to Azure](https://learn.microsoft.com/en-us/azure/migrate/server-migrate-overview) +- [Migrate Physical Servers](https://learn.microsoft.com/en-us/azure/migrate/tutorial-migrate-physical-virtual-machines) +- [Migrate AWS Instances to Azure](https://learn.microsoft.com/en-us/azure/migrate/tutorial-migrate-aws-virtual-machines) +- [Migrate GCP Instances to Azure](https://learn.microsoft.com/en-us/azure/migrate/tutorial-migrate-gcp-virtual-machines) ### Solution - Spoilerwarning @@ -258,22 +264,23 @@ The goal of this exercise is to ... ## Optional Bonus Challenge 6 - Secure on Azure -### Goal +### Goal The goal of this exercise is to ... -* secure the migrated Virtual Machines by enabling Defender for Cloud for Server +- secure the migrated Virtual Machines by enabling Defender for Cloud for Server ### Actions -* Enable Defender for Cloud +- Enable Defender for Cloud ### Success criteria -* The migrated Servers are protected by Defender for Cloud for Servers +- The migrated Servers are protected by Defender for Cloud for Servers ### Learning resources -* [Deploy Defender for Servers](https://learn.microsoft.com/en-us/azure/defender-for-cloud/tutorial-enable-servers-plan) + +- [Deploy Defender for Servers](https://learn.microsoft.com/en-us/azure/defender-for-cloud/tutorial-enable-servers-plan) ### Solution - Spoilerwarning @@ -281,32 +288,34 @@ The goal of this exercise is to ... ## Optional Bonus Challenge 7 - Modernize with Azure -### Goal +### Goal The goal of this exercise is to ... -* modernize the Web App running on the frontend Servers to be hosted on PaaS instead of IaaS (Lift & Shift) -* understand the options that are available for App Services assessment & migration +- modernize the Web App running on the frontend Servers to be hosted on PaaS instead of IaaS (Lift & Shift) +- understand the options that are available for App Services assessment & migration ### Actions -* Create a web app assessment using Azure Migrate -* Preform a web app migration using Azure Migrate towards Azure App Services +- Create a web app assessment using Azure Migrate +- Preform a web app migration, either using Git-based migration or using Azure Migrate towards Azure App Services ### Success criteria -* An assessment has been performed using the already deployed infrastructure. -* An migration has been performed towards PaaS instead of IaaS. -* The App Services are accessible using the source Load Balancer. +- An assessment has been performed using the already deployed infrastructure. +- An migration has been performed towards PaaS instead of IaaS. +- The App Services are accessible using the source Traffic Manager. > [!IMPORTANT] +> > Currently [July 2024], At-Scale Discovery, Assessment and Migration is supported for ASP.NET web apps deployed to on-premises IIS servers hosted on VMware Environment. ### Learning resources -* [App Service assessment overview](https://learn.microsoft.com/en-us/azure/migrate/concepts-azure-webapps-assessment-calculation) -* [Web App migration support](https://learn.microsoft.com/en-us/azure/migrate/concepts-migration-webapps) -* [App Service Migration Assistant](https://github.com/Azure/App-Service-Migration-Assistant/wiki) -* [App Service migration tools and resources](https://learn.microsoft.com/en-us/azure/app-service/app-service-asp-net-migration#app-service-migration-tools-and-resources) + +- [App Service assessment overview](https://learn.microsoft.com/en-us/azure/migrate/concepts-azure-webapps-assessment-calculation) +- [Web App migration support](https://learn.microsoft.com/en-us/azure/migrate/concepts-migration-webapps) +- [App Service Migration Assistant](https://github.com/Azure/App-Service-Migration-Assistant/wiki) +- [App Service migration tools and resources](https://learn.microsoft.com/en-us/azure/app-service/app-service-asp-net-migration#app-service-migration-tools-and-resources) ### Solution - Spoilerwarning @@ -320,7 +329,8 @@ If you want to give feedback please don’t hesitate to open an Issue on the rep Thank you for investing the time and see you next time! ## Contributors -* Nils Bankert [GitHub](https://github.com/nilsbankert); [LinkedIn](https://www.linkedin.com/in/nilsbankert/) -* Andreas Schwarz [LinkedIn](https://www.linkedin.com/in/andreas-schwarz-7518a818b/) -* Christian Thönes [Github](https://github.com/cthoenes); [LinkedIn](https://www.linkedin.com/in/christian-t-510b7522/) -* Stefan Geisler [Github](https://github.com/StefanGeislerMS); [LinkedIn](https://www.linkedin.com/in/stefan-geisler-7b7363139/) + +- Nils Bankert [GitHub](https://github.com/nilsbankert); [LinkedIn](https://www.linkedin.com/in/nilsbankert/) +- Andreas Schwarz [LinkedIn](https://www.linkedin.com/in/andreas-schwarz-7518a818b/) +- Christian Thönes [Github](https://github.com/cthoenes); [LinkedIn](https://www.linkedin.com/in/christian-t-510b7522/) +- Stefan Geisler [Github](https://github.com/StefanGeislerMS); [LinkedIn](https://www.linkedin.com/in/stefan-geisler-7b7363139/) diff --git a/03-Azure/01-03-Infrastructure/06_Migration_Secure_AI_Ready/walkthrough/challenge-1/solution.md b/03-Azure/01-03-Infrastructure/06_Migration_Secure_AI_Ready/walkthrough/challenge-1/solution.md index 86c9c84b..f4d33ba5 100644 --- a/03-Azure/01-03-Infrastructure/06_Migration_Secure_AI_Ready/walkthrough/challenge-1/solution.md +++ b/03-Azure/01-03-Infrastructure/06_Migration_Secure_AI_Ready/walkthrough/challenge-1/solution.md @@ -6,7 +6,7 @@ Duration: 30 minutes - Please ensure that you successfully verified the [General prerequisits](../../Readme.md#general-prerequisites) before continuing with this challenge. - The Azure CLI is required to deploy the Bicep configuration of the Micro Hack. -- Download the *.bicep files from the [Resources](../../resources) to your local PC. +- Download the \*.bicep files from the [Resources](../../resources) to your local PC. ### **Task 1: Deploy the Landing Zone for the Micro Hack** @@ -17,13 +17,13 @@ Duration: 30 minutes > [!NOTE] > You can also use your local PC but make sure to install [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli). -- If this is the first time that Cloud Shell is beeing started, create the required Storage Account by selecting *Bash* and clicking on *Create storage* and wait until the Storage Accounts has been created. +- If this is the first time that Cloud Shell is beeing started, create the required Storage Account by selecting _Bash_ and clicking on _Create storage_ and wait until the Storage Accounts has been created. ![image](./img/CS1-1.png) ![image](./img/CS2.png) -- Make sure to select *Bash*. +- Make sure to select _Bash_. ![image](./img/CS3.png) @@ -39,7 +39,7 @@ Duration: 30 minutes ![image](./img/CS6.png) -- Wait for the deployment to finish. You can view the deployment from the Azure portal by selecting the Azure Subscription and click on *Deployments* from the navigation pane on the left. +- Wait for the deployment to finish. You can view the deployment from the Azure portal by selecting the Azure Subscription and click on _Deployments_ from the navigation pane on the left. ![image](./img/CS7.png) @@ -47,32 +47,32 @@ Duration: 30 minutes > Please note that the deployment may take up to 10 minutes. ### **Task 2: Verify the deployed resources** + The bicep deployment should have created the following resources - source-rg Resource Group containing the follwing resources - + Virtual Network *source-vnet* - + Virtual Machine *Win-fe1* with installed web server on a Windows Server System - + Virtual Machine *Lx-fe2* with installed web server on a REHL System - + Public Load Balancer *plb-frontend* with configured backend pool containing *frontend1* and *frontend2* VM - + Azure Bastion *source-bastion* - + Azure Key Vault *source-kv-* containing username and password for VM login - + - Virtual Network _source-vnet_ + - Virtual Machine _Win-fe1_ with installed web server on a Windows Server System + - Virtual Machine _Lx-fe2_ with installed web server on a REHL System + - Public Load Balancer _plb-frontend_ with configured backend pool containing _frontend1_ and _frontend2_ VM + - Azure Bastion _source-bastion_ + - Azure Key Vault _source-kv-_ containing username and password for VM login - destination-rg Resource Group containing the follwing resources - + Virtual Network *destination-vnet* - + Azure Bastion *destination-bastion* - + - Virtual Network _destination-vnet_ + - Azure Bastion _destination-bastion_ + The deployed architecture looks like following diagram: ![image](./img/Challenge-1.jpg) ### **Task 3: Verify Web Server availability** -- Open *source-rg* Resource Group -- Select *plb-frontend* Load Balancer -- Navigate to *Frontend IP configuration* under *Settings* section on the left -- Note and copy public IP address of *LoadBalancerFrontEnd* +- Open _source-rg_ Resource Group +- Select _plb-frontend_ Load Balancer +- Navigate to _Frontend IP configuration_ under _Settings_ section on the left +- Note and copy public IP address of _LoadBalancerFrontEnd_ - Open web browser and navigate to http://LoadBalancerFrontEnd-IP-Address - A simple website containing the server name of the frontend1 or frontend2 VM should be displayed You successfully completed challenge 1! 🚀🚀🚀 - **[Home](../../Readme.md)** - [Next Challenge Solution](../challenge-2/solution.md) +**[Home](../../Readme.md)** - [Next Challenge Solution](../challenge-2/solution.md) diff --git a/03-Azure/01-03-Infrastructure/06_Migration_Secure_AI_Ready/walkthrough/challenge-3/solution.md b/03-Azure/01-03-Infrastructure/06_Migration_Secure_AI_Ready/walkthrough/challenge-3/solution.md index bd694777..5fd5a94c 100644 --- a/03-Azure/01-03-Infrastructure/06_Migration_Secure_AI_Ready/walkthrough/challenge-3/solution.md +++ b/03-Azure/01-03-Infrastructure/06_Migration_Secure_AI_Ready/walkthrough/challenge-3/solution.md @@ -9,33 +9,32 @@ Please also make sure to review the [prerequisites](https://learn.microsoft.com/ ### **Task 1: Build a business case** -Open the [Azure Portal](https://portal.azure.com) and navigate to the previousley created Azure Migrate project. Select *Servers, databases and web apps*, make sure that the right Azure Migrate Project is selected and click *Build business case*. +Open the [Azure Portal](https://portal.azure.com) and navigate to the previousley created Azure Migrate project. Select _Servers, databases and web apps_, make sure that the right Azure Migrate Project is selected and click _Build business case_. ![image](./img/bc1.png) -Provide a name for the business case and select a target location. For the migration strategy select *Azure recommended approach to minimize cost*. You can select your desired saving options and discounts that may apply to your Azure Subscription. +Provide a name for the business case and select a target location. For the migration strategy select _Azure recommended approach to minimize cost_, if available. You can select your desired saving options and discounts that may apply to your Azure Subscription. ![image](./img/bc2.png) > [!IMPORTANT] > Please set location as "Sweden Central" instead of "West Europe" -Wait for the business case creation to complete and click on the business case name to open it. +> Wait for the business case creation to complete and click on the business case name to open it. > [!NOTE] > Please note that business case creation can take up to 30 minutes. ![image](./img/bc3.png) - ### **Task 2: Review a business case** There are four major reports that you need to review: - Overview: This report is an executive summary of the business case and covers: - + Potential savings (TCO). - + Estimated year on year cashflow savings based on the estimated migration completed that year. - + Savings from unique Azure benefits like Azure Hybrid Benefit. - + Discovery insights covering the scope of the business case. + - Potential savings (TCO). + - Estimated year on year cashflow savings based on the estimated migration completed that year. + - Savings from unique Azure benefits like Azure Hybrid Benefit. + - Discovery insights covering the scope of the business case. ![image](./img/bc4.png) @@ -67,4 +66,4 @@ You can adjust those parameters what would recalculate the business case. You successfully completed challenge 3! 🚀🚀🚀 - **[Home](../../Readme.md)** - [Next Challenge Solution](../challenge-4/solution.md) +**[Home](../../Readme.md)** - [Next Challenge Solution](../challenge-4/solution.md) diff --git a/03-Azure/01-03-Infrastructure/06_Migration_Secure_AI_Ready/walkthrough/challenge-5/solution.md b/03-Azure/01-03-Infrastructure/06_Migration_Secure_AI_Ready/walkthrough/challenge-5/solution.md index 4b30455a..3b634c7f 100644 --- a/03-Azure/01-03-Infrastructure/06_Migration_Secure_AI_Ready/walkthrough/challenge-5/solution.md +++ b/03-Azure/01-03-Infrastructure/06_Migration_Secure_AI_Ready/walkthrough/challenge-5/solution.md @@ -11,54 +11,54 @@ Please make sure thet you successfully completed [Challenge 4](../challenge-4/so To start physical server migration you must install the Azure Replication Appliance on your on-premises. The Azure Replication Appliance can be downloaded as a OVA template or you can download the appliance installer to install it on a already existing server. For the purpose of this MicroHack we will install the Azure Replication Appliance via the installer on a new Windows Server 2019 system. > [!IMPORTANT] -> Please make sure to check the [prerequisites](https://learn.microsoft.com/en-us/azure/migrate/migrate-replication-appliance) of the Azure -Replication Appliance. +> Please make sure to check the [prerequisites](https://learn.microsoft.com/en-us/azure/migrate/migrate-replication-appliance) of the Azure +> Replication Appliance. > [!IMPORTANT] > Please note that it is currently [not supported](https://learn.microsoft.com/en-us/azure/migrate/common-questions-appliance#can-the-azure-migrate-appliancereplication-appliance-connect-to-the-same-vcenter) to install the Azure Migrate Replication Appliance on the same system as the Azure Migrate Appliance. -In the Azure Portal select *Virtual machines* from the navigation pane on the left. Select *Create -> Azure virtual machine* +In the Azure Portal select _Virtual machines_ from the navigation pane on the left. Select _Create -> Azure virtual machine_ ![image](./img/azreplapl1.png) -Under Basics select the *source-rg* Resource Group and provide a name for the server. Select *Windows Server 2019 Datacenter - x64 Gen2* for the Image. +Under Basics select the _source-rg_ Resource Group and provide a name for the server. Select _Windows Server 2019 Datacenter - x64 Gen2_ for the Image. ![image](./img/azreplapl2.png) > [!NOTE] > For the Username and Password you can either select a combination of your choice or check the secrets within the KeyVault. -Add an additional 1024GiB Standard HDD LRS data disk to the Virtual Machine and click *Next* +Add an additional 1024GiB Standard HDD LRS data disk to the Virtual Machine and click _Next_ ![image](./img/azreplapl2-1.png) ![image](./img/azreplapl2-2.png) -In the *Networking* tab, select the *source-vnet* Virtual Network and the *source-subnet* Subnet and make sure to select *None* for the Public IP and NIC network security group. +In the _Networking_ tab, select the _source-vnet_ Virtual Network and the _source-subnet_ Subnet and make sure to select _None_ for the Public IP and NIC network security group. ![image](./img/azreplapl3.png) -Accept the default settings for the remaining tabs, select *Review + create* and click *Create*. +Accept the default settings for the remaining tabs, select _Review + create_ and click _Create_. ![image](./img/azreplapl4.png) -Wait until the deployment has been successfully completed and select *Go to resource* +Wait until the deployment has been successfully completed and select _Go to resource_ ![image](./img/azreplapl5.png) -Select *Bastion* from the navigation pane on the left, provide the credentials to login to the Azure Migrate Replication VM and select *Connect*. A new browser tab should open with a remote session to the Windows Server 2019 system. +Select _Bastion_ from the navigation pane on the left, provide the credentials to login to the Azure Migrate Replication VM and select _Connect_. A new browser tab should open with a remote session to the Windows Server 2019 system. ![image](./img/azreplapl6.png) > [!NOTE] -> You can also select *Password from Azure KeyVault* under *Authentication Type* if you set the password during VM creation to match the secret stored in the KeyVault. +> You can also select _Password from Azure KeyVault_ under _Authentication Type_ if you set the password during VM creation to match the secret stored in the KeyVault. ### **Task 2: Setup the Azure Replication Appliance** To prepare for physical server migration, you need to verify the physical server settings, and prepare to deploy a replication appliance. -First we need to initialize and format the data disk that was attached during the VM creation. -Open Windows Disk Management using the *diskmgmt.msc* command. +First we need to initialize and format the data disk that was attached during the VM creation. +Open Windows Disk Management using the _diskmgmt.msc_ command. ![image](./img/disk1.png) @@ -70,7 +70,7 @@ Select the initialized disk and create a new simple vplume on it. ![image](./img/disk3.png) -Acceppt the default values, name the Volume *ASR* and click *Finish* to format the disk. +Acceppt the default values, name the Volume _ASR_ and click _Finish_ to format the disk. ![image](./img/disk4.png) @@ -78,40 +78,40 @@ Wait until the operation is completed successfully. ![image](./img/disk5.png) -Open the [Azure Portal](https://portal.azure.com) on the Azure Replication Appliance using the Microsoft Edge browser and navigate to the previousley created Azure Migrate project. Select *Servers, databases and web apps*, make sure that the right Azure Migrate Project is selected and click *Discover* in the *Migration tools* box. +Open the [Azure Portal](https://portal.azure.com) on the Azure Replication Appliance using the Microsoft Edge browser and navigate to the previousley created Azure Migrate project. Select _Servers, databases and web apps_, make sure that the right Azure Migrate Project is selected and click _Discover_ in the _Migration tools_ box. ![image](./img/mig1.png) > [!IMPORTANT] > Please double check your preferred target region as this cannot be changed afterwards. In doubt check the region of your destination Resource Group and vNet. -Select *Physical or other...* in the *Are your machines virtualized* drop down and select *Your Target Region* as the *Target Region*. -Make sure to check the confirmation checkbox and click *Create resources*. +Select _Physical or other..._ in the _Are your machines virtualized_ drop down and select _Your Target Region_ as the _Target Region_. +Make sure to check the confirmation checkbox and click _Create resources_. ![image](./img/mig2.png) -Wait until the deployment has been successfully completed. Next under *1. Download and install the repliaction appliance software* click *Download* to download the Azure Migrate Repplication Appliance installer. -You also need to download the registration key that is required to register the replication appliance under *2. Configure the replication appliance and register it to the project*. +Wait until the deployment has been successfully completed. Next under _1. Download and install the repliaction appliance software_ click _Download_ to download the Azure Migrate Repplication Appliance installer. +You also need to download the registration key that is required to register the replication appliance under _2. Configure the replication appliance and register it to the project_. ![image](./img/mig3.png) -Next start the installation of the Azure Migrate Replication Appliance by double cklicking the *MicrosoftAzureSiteRecoveryUnifiedSetup.exe* +Next start the installation of the Azure Migrate Replication Appliance by double cklicking the _MicrosoftAzureSiteRecoveryUnifiedSetup.exe_ ![image](./img/mig4.png) -Select *Install the configuration server and process server* and click *Next* +Select _Install the configuration server and process server_ and click _Next_ ![image](./img/mig5.png) -Check the *I acceppt...* checkbox and click *Next* +Check the _I acceppt..._ checkbox and click _Next_ ![image](./img/mig6.png) -Browse and select the previousley downloaded registration key and click *Next* +Browse and select the previousley downloaded registration key and click _Next_ ![image](./img/mig7.png) -Accept the default *Internet connection* configuration +Accept the default _Internet connection_ configuration ![image](./img/mig8.png) @@ -119,18 +119,18 @@ Review the prerequisites check of the installer. Note that you can safely ignore ![image](./img/mig9.png) -Specify the required passwords and note the password requirements. +Specify the required passwords and note the password requirements. > [!NOTE] > For the Username and Password you can either select a combination of your choice or check the secrets within the KeyVault. ![image](./img/mig10.png) -Select *No* for *Do you want to protect VMware virtual machines* and click *Next* +Select _No_ for _Do you want to protect VMware virtual machines_ and click _Next_ ![image](./img/mig11.png) -Verify the *Install location*. The installer should automatically pre-select the largest disk, in our case the 1024 GiB data disk that was created during VM creation. +Verify the _Install location_. The installer should automatically pre-select the largest disk, in our case the 1024 GiB data disk that was created during VM creation. > [!IMPORTANT] > The additional data disk needs to be initialized first using the [Windows Disk Management tool](https://learn.microsoft.com/en-us/windows-server/storage/disk-management/initialize-new-disks#initialize-a-new-disk). You can open the tool side by side with the installer if you have not initialized the disk beforehand. @@ -141,7 +141,7 @@ Select the appropriate NICs (We only have 1 in our case). ![image](./img/mig13.png) -Verify the installation summary and click *Install* to start the installation. +Verify the installation summary and click _Install_ to start the installation. ![image](./img/mig14.png) @@ -151,6 +151,15 @@ Wait until the installation progress is finished. After the successfull installation a configuration server connection passphrase will be displayed. Copy the passphrase and save it as a new secret in the source-rg Resource Group KeyVault. +> [!NOTE] +> If you forgot to copy the passphrase you can obtain it by executing the following Powershell command on the VM hosting the replication appliance +> +> ```powershell +> Windows PowerShell +> Copyright (C) Microsoft Corporation. All rights > reserved. +> C:\ProgramData\ASR\home\svsystems\bin\genpassphrase.exe -v +> ``` + ![image](./img/mig17.png) After the installation completes, the Appliance configuration wizard will be launched automatically. @@ -158,95 +167,114 @@ You can add the local administrator account credentials of the source servers (s ![image](./img/mig17-1.png) -The last step is to finalize the registration. Refresh the Azure Portal page where you've downloaded the installer and registration keys and select the *azreplappliance* from the drop down list and click on *Finalize registration*. +The last step is to finalize the registration. Refresh the Azure Portal page where you've downloaded the installer and registration keys and select the _azreplappliance_ from the drop down list and click on _Finalize registration_. ![image](./img/mig18.png) -### **Task 3: Copy the Mobility Service Agent to the source server** +### **Task 3: Setup the Mobility Service Agent to your Windows Server** + +On machines you want to migrate, you need to install the Mobility service agent. The agent installers are available on the replication appliance in the _%ProgramData%\ASR\home\svsystems\pushinstallsvc\repository_ directory. -On machines you want to migrate, you need to install the Mobility service agent. The agent installers are available on the replication appliance in the *%ProgramData%\ASR\home\svsystems\pushinstallsvc\repository* directory. +#### **Task 3.1: Transfer Agent to Server** -**Windows** To copy the Mobility service agent to the Windows machine follow the following steps 1. Sign in to the Windows Server source VM. 2. Open Powershell and run the following command -~~~powershell +```powershell Windows PowerShell Copyright (C) Microsoft Corporation. All rights reserved. Copy-Item \\10.1.1.7\C$\ProgramData\ASR\home\svsystems\pushinstallsvc\repository\Microsoft-ASR_UA*Windows*_Release.exe $env:USERPROFILE\Downloads\ -Force -~~~ - -**Linux** -To copy the Mobility service agent to the Linux machine follow the following steps - -1. Sign in to the Linux Server source VM. -2. Run the following command. Replace the Username and the correct filename. - -~~~bash -#List the correct file -smbclient -U //10.1.1.7/c$ -c "dir ProgramData\ASR\home\svsystems\pushinstallsvc\repository\*ASR*RHEL8*" -#Copy the filename to next command and copy it to tmp directory -smbclient '//10.1.1.7/c$' -c 'lcd /tmp; cd ProgramData\ASR\home\svsystems\pushinstallsvc\repository; get Microsoft-ASR_UA_9.63.0.0_RHEL8-64_GA_21Oct2024_Release.tar.gz' -U -cd /tmp -ls -~~~ +``` -#### **Task 3.1: Install the Mobility service on the Windows VM** +#### **Task 3.2: Install the Mobility service on the Windows VM** > [!NOTE] > During the installation you need to provide the passphrase that was created during the Replication Appliance installation. -> If you forgot to copy the passphrase you can obtain it from inside the Replication Appliance via the following Powershell command. -> ~~~powershell +> If you forgot to copy the passphrase you can obtain it from inside the Replication Appliance via the following Powershell command. +> +> ```powershell > Windows PowerShell > Copyright (C) Microsoft Corporation. All rights > reserved. > C:\ProgramData\ASR\home\svsystems\bin\genpassphrase.exe -v -> ~~~ +> ``` > [!WARNING] > Don't regenerate the passphrase. This will break connectivity and you will have to reregister the replication appliance. 1. Extract the contents of installer file to a local folder (for example C:\Temp) on the machine, as follows: -~~~powershell +```powershell Windows PowerShell Copyright (C) Microsoft Corporation. All rights reserved. cd $env:USERPROFILE\Downloads\ Rename-Item .\Microsoft-ASR_UA_9.63.0.0_Windows_GA_21Oct2024_Release.exe MobilityServiceInstaller.exe .\MobilityServiceInstaller.exe /q /x:C:\Temp\Extracted cd C:\Temp\Extracted -~~~ +``` 2. Run the Mobility Service Installer: -~~~powershell + +```powershell Windows PowerShell Copyright (C) Microsoft Corporation. All rights reserved. .\UnifiedAgent.exe /Role "MS" /Platform "VmWare" /Silent /CSType CSLegacy -~~~ +``` > [!IMPORTANT] -> You need to specify *VmWare* for the *Platform* parameter also for physical servers. +> You need to specify _VmWare_ for the _Platform_ parameter also for physical servers. 3. Register the agent with the replication appliance: -~~~powershell + +```powershell Windows PowerShell Copyright (C) Microsoft Corporation. All rights reserved. cd "C:\Program Files (x86)\Microsoft Azure Site Recovery\agent" set-Content .\password.txt -Force # This is the password you received during the installation of the Azure Replication Appliance, replace it with your password. .\UnifiedAgentConfigurator.exe /CSEndPoint 10.1.1.7 /PassphraseFilePath "C:\Program Files (x86)\Microsoft Azure Site Recovery\agent\password.txt" -~~~ - -#### **Task 3.2: Install the Mobility service on the Linux VM** +``` + +### **Task 4: Setup the Mobility Service Agent to your Linux Server** + +On machines you want to migrate, you need to install the Mobility service agent. The agent installers are available on the replication appliance in the _%ProgramData%\ASR\home\svsystems\pushinstallsvc\repository_ directory. + +#### **Task 4.1: Transfer Agent to Server** + +To copy the Mobility service agent to the Linux machine follow the following steps + +1. Sign in to the Linux Server source VM. +2. Run the following command. Replace the Username and the correct filename. + +```bash +#List the correct file +smbclient -U //10.1.1.7/c$ -c "dir ProgramData\ASR\home\svsystems\pushinstallsvc\repository\*ASR*RHEL8*" +#Copy the filename to next command and copy it to tmp directory +smbclient '//10.1.1.7/c$' -c 'lcd /tmp; cd ProgramData\ASR\home\svsystems\pushinstallsvc\repository; get Microsoft-ASR_UA_9.63.0.0_RHEL8-64_GA_21Oct2024_Release.tar.gz' -U +cd /tmp +ls +``` + +> [!NOTE] +> You might need to install smbclient on your linux environment to complete the above step. +> For example : + +```bash +Ubuntu : sudo apt-get install smbclient +RedHat : sudo yum install samba-client samba-common cifs-utils +``` + +#### **Task 4.2: Install the Mobility service on the Linux VM** > [!NOTE] > During the installation you need to provide the passphrase that was created during the Replication Appliance installation. -> If you forgot to copy the passphrase you can obtain it from inside the Replication Appliance via the following Powershell command. -> ~~~powershell +> If you forgot to copy the passphrase you can obtain it from inside the Replication Appliance via the following Powershell command. +> +> ```powershell > Windows PowerShell > Copyright (C) Microsoft Corporation. All rights > reserved. > C:\ProgramData\ASR\home\svsystems\bin\genpassphrase.exe -v -> ~~~ +> ``` > [!WARNING] > Don't regenerate the passphrase. This will break connectivity and you will have to reregister the replication appliance. @@ -257,50 +285,50 @@ Log into the Linux VM with Azure Bastion and install the mobility service agent. ![image](./img/mal1.png) -~~~bash +```bash mkdir MobSvcInstaller tar -C ./MobSvcInstaller -xvf /tmp/Microsoft-ASR_UA_9.63.0.0_RHEL8-64_GA_21Oct2024_Release.tar.gz cd MobSvcInstaller sudo ./install -r MS -v VmWare -q -c CSLegacy # You need to specify VmWare as the platform also for physical servers. -~~~ +``` -~~~bash +```bash echo > password.txt # This is the password you received during the installation of the Azure Replication Appliance, replace it with your password. sudo /usr/local/ASR/Vx/bin/UnifiedAgentConfigurator.sh -i 10.1.1.7 -P password.txt -c CSLegacy # IP 10.1.1.7 is the IP of the Azure Replication Appliance Windows VM you created. logout -~~~ +``` -### **Task 4: Enable Replication** +### **Task 5: Enable Replication** -Open the [Azure Portal](https://portal.azure.com) and navigate to the previousley created Azure Migrate project. Select *Servers, databases and web apps*, make sure that the right Azure Migrate Project is selected and click *Replicate* under *Migration Tools*. +Open the [Azure Portal](https://portal.azure.com) and navigate to the previousley created Azure Migrate project. Select _Servers, databases and web apps_, make sure that the right Azure Migrate Project is selected and click _Replicate_ under _Migration Tools_. -![image](./img/repl1.png) +![image](./img/repl1.png) -Select *Servers or virtual machines (VM)* and *Azure VM* and click *Continue*. +Select _Servers or virtual machines (VM)_ and _Azure VM_ and click _Continue_. -![image](./img/repl2.png) +![image](./img/repl2.png) -In the *Basics* page select the previousley created Azure Migrate Replication appliance and specify the Guest Credentials and click next: +In the _Basics_ page select the previousley created Azure Migrate Replication appliance and specify the Guest Credentials and click next: ![image](./img/repl3.png) -Under *Virtual Machines* select *No I'll specify the migration settings manually* and select the *frontend1* and *frontend2* server from the list. +Under _Virtual Machines_ select _No I'll specify the migration settings manually_ and select the _frontend1_ and _frontend2_ server from the list. ![image](./img/repl4.png) -Under *Traget Settings* select the *destination-rg* Resource Group and the *destination-vnet* vNet and select next. +Under _Traget Settings_ select the _destination-rg_ Resource Group and the _destination-vnet_ vNet and select next. ![image](./img/repl5.png) -Under *Compute* acceppt the defaults and click next. +Under _Compute_ acceppt the defaults and click next. ![image](./img/repl6.png) -Under *Disks* change the Disk Type to *Standard SSD* and click next. +Under _Disks_ change the Disk Type to _Standard SSD_ and click next. ![image](./img/repl7.png) -Acceppt the defaults for *Tags* and proceed to *Review + Start Replication*. Click *Replicate* to start the replication. +Acceppt the defaults for _Tags_ and proceed to _Review + Start Replication_. Click _Replicate_ to start the replication. ![image](./img/repl8.png) @@ -308,11 +336,11 @@ Wait until the replication has been successfully initiated. ![image](./img/repl9.png) -Under *Migration Tools* you should know see that 2 Server are beeing replicated. Click on *Overview* to see more details. +Under _Migration Tools_ you should know see that 2 Server are beeing replicated. Click on _Overview_ to see more details. ![image](./img/repl10.png) -Select *Replicating Machines* from the navigation pane on the left. You should now see the 2 servers and their status. +Select _Replicating Machines_ from the navigation pane on the left. You should now see the 2 servers and their status. > [!IMPORTANT] > Please note that the initial replication might take some time. Within the MicroHack environment it should not take longer than 30 minutes. @@ -323,23 +351,23 @@ Select *Replicating Machines* from the navigation pane on the left. You should n When delta replication begins, you can run a test migration for the VMs, before running a full migration to Azure. We highly recommend that you do this at least once for each machine, before you migrate it. -* Running a test migration checks that migration will work as expected, without impacting the on-premises machines, which remain operational, and continue replicating. -* Test migration simulates the migration by creating an Azure VM using replicated data (usually migrating to a non-production VNet in your Azure subscription). -* You can use the replicated test Azure VM to validate the migration, perform app testing, and address any issues before full migration. +- Running a test migration checks that migration will work as expected, without impacting the on-premises machines, which remain operational, and continue replicating. +- Test migration simulates the migration by creating an Azure VM using replicated data (usually migrating to a non-production VNet in your Azure subscription). +- You can use the replicated test Azure VM to validate the migration, perform app testing, and address any issues before full migration. -Open the [Azure Portal](https://portal.azure.com) and navigate to the previousley created Azure Migrate project. Select *Servers, databases and web apps*, make sure that the right Azure Migrate Project is selected and click *Overview* in the *Migration tools* box. +Open the [Azure Portal](https://portal.azure.com) and navigate to the previousley created Azure Migrate project. Select _Servers, databases and web apps_, make sure that the right Azure Migrate Project is selected and click _Overview_ in the _Migration tools_ box. ![image](./img/test1.png) -Select *Perform more test migrations* under *Step 2: Test migration*. +Select _Perform more test migrations_ under _Step 2: Test migration_. ![image](./img/test2.png) -Click on the 3 dots on the right corner of each server and select *Test migration* from the drop down. +Click on the 3 dots on the right corner of each server and select _Test migration_ from the drop down. ![image](./img/test3.png) -Select the *destination-vnet* and click on *Test migration*. +Select the _destination-vnet_ and click on _Test migration_. ![image](./img/test4.png) @@ -347,27 +375,29 @@ Repeat the above steps for the remaining server and wait until the test migratio ![image](./img/test5.png) -Switch back to the *Overview* section of the *Azure Migrate: Migration and modernization* page. The Cleanup should be pending for the 2 servers. +Switch back to the _Overview_ section of the _Azure Migrate: Migration and modernization_ page. The Cleanup should be pending for the 2 servers. ![image](./img/test6.png) -Select *Virtual machines* from the navigation pane on the left. There will be 2 additional servers *frontend1-test* and *frontend2-test*. Those servers were created during test migration. +Select _Virtual machines_ from the navigation pane on the left. There will be 2 additional servers _frontend1-test_ and _frontend2-test_. Those servers were created during test migration. ![image](./img/test7.png) -Click on the *frontend1-test* server, select *Bastion* and provide the login credentials for the server. Select *Connect* to initiate the connection. +Click on the _frontend1-test_ server, select _Bastion_ and provide the login credentials for the server. Select _Connect_ to initiate the connection. ![image](./img/test8.png) -Open the Microsoft Edge browser on the server, enter *localhost* in the address bar and make sure that the web server is running. +Open the Microsoft Edge browser on the server, enter _localhost_ in the address bar and make sure that the web server is running. ![image](./img/test9.png) -Repeat the above steps for the *Lxfe2-test* system. Once you've confirmed that the applications on the systems are running as expected you can perfom a cleanup for the test migration. Change back to the *Azure Migrate: Migration and modernization* overview page, click on the 3 dots on the end of each row of the replicating servers and select *Clean up test migration*. +Repeat the above steps for the _Lxfe2-test_ system. Once you've confirmed that the applications on the systems are running as expected you can perfom a cleanup for the test migration. Change back to the _Azure Migrate: Migration and modernization_ overview page, click on the 3 dots on the end of each row of the replicating servers and select _Clean up test migration_. + +> [!NOTE] You can use the IP address of the Linux machine in this browser or connect to the Linux machine and use `curl localhost` to see i fthe server responds correctly. ![image](./img/test10.png) -Select *Testing complete. Delete test virtual machine* and select *Cleanup Test*. Reapeat the step for the remainig server and wait until the cleanup has been successfully processed. +Select _Testing complete. Delete test virtual machine_ and select _Cleanup Test_. Reapeat the step for the remainig server and wait until the cleanup has been successfully processed. ![image](./img/test11.png) @@ -377,66 +407,66 @@ Currently the two frontend servers are published via an Azure Public Load Balanc #### **Task 6.1: Create a new Azure Public Load Balancer in the destination environment** -From the Azure Portal open the Load Balancing blade, select Load Balancer on the Navigation pane on the left and click *Create*. +From the Azure Portal open the Load Balancing blade, select Load Balancer on the Navigation pane on the left and click _Create_. ![image](./img/prep1.png) -Under *Basics* select the *destination-rg* Resource Group and provide a name for the new Load Balancer. +Under _Basics_ select the _destination-rg_ Resource Group and provide a name for the new Load Balancer. ![image](./img/prep2.png) -Under *Frontend IP configuration*, click *Add a frontend IP configuration* and create a new Public IP address. +Under _Frontend IP configuration_, click _Add a frontend IP configuration_ and create a new Public IP address. ![image](./img/prep3.png) -Under *Backend Pools*, select *Add a backend Pool*. Provide a name and select the *destination-vnet* as the Virtual Network. -Add *10.2.1.4* and *10.2.1.5* as the IP addresses. +Under _Backend Pools_, select _Add a backend Pool_. Provide a name and select the _destination-vnet_ as the Virtual Network. +Add _10.2.1.4_ and _10.2.1.5_ as the IP addresses. > [!NOTE] > Please note: Azure reserves the first four addresses (0-3) in each subnet address range, and doesn't assign the addresses. Azure assigns the next available address to a resource from the subnet address range. So it is predictable which IP addresses will be assigned to the destination VMs after the migration. ![image](./img/prep4.png) -Under *Inbound rules* click on *Add a load balancing rule* and create the load balancing rule as illustrated on the following diagram. +Under _Inbound rules_ click on _Add a load balancing rule_ and create the load balancing rule as illustrated on the following diagram. ![image](./img/prep5.png) -Under *Outbound rules* click *Add an outbound rule* and create the outbound rule as illustrated on the following diagram. +Under _Outbound rules_ click _Add an outbound rule_ and create the outbound rule as illustrated on the following diagram. ![image](./img/prep6.png) -Proceed to the *Review + create* section, review your configuration and click *Create* +Proceed to the _Review + create_ section, review your configuration and click _Create_ ![image](./img/prep7.png) -Wait until the load balancer has been created, cahnge back to the *Load balancing* section, select the *plb-frontend* Load Balancer and click *Frontend IP configuration* from the navigation pane on the left. Note down the Public IP of the *LoadBalancerFrontEnd* configuration. Repeat the step for the *plb-frontend-dest* Load Balancer. +Wait until the load balancer has been created, cahnge back to the _Load balancing_ section, select the _plb-frontend_ Load Balancer and click _Frontend IP configuration_ from the navigation pane on the left. Note down the Public IP of the _LoadBalancerFrontEnd_ configuration. Repeat the step for the _plb-frontend-dest_ Load Balancer. ![image](./img/prep8.png) +> [!NOTE] +> In the next task we will configure an Azure Traffic Manager Profile for load balancing. To be able to add the public IP addresses they need to be configured with an [DNS name lable](https://learn.microsoft.com/en-us/azure/dns/dns-custom-domain?toc=%2Fazure%2Fvirtual-network%2Ftoc.json#public-ip-address). + +![image](./img/prep11-1.png) + #### **Task 6.2: Create a new Azure Traffic Manager Profile** Azure Traffic Manager is a DNS-based traffic load balancer. It allows us to distribute traffic to public facing endpoints like our two Public Load Balancer. Traffic Manager can be created in advance to distribute traffic among the old and new load balancer. The DNS conbfiguration of the application can be changed in advance to point to the Traffic Manager Profile instead to the Public IP of the Load Balancer. Using this approach makes sure that Traffic Manager automatically removes the old Load Balancer after the frontend servers were migrated. -From the Azure Portal open the Load Balancing blade, select Traffic Manager on the Navigation pane on the left and click *Create*. +From the Azure Portal open the Load Balancing blade, select Traffic Manager on the Navigation pane on the left and click _Create_. ![image](./img/prep9.png) -Select a name for the Traffic Manager profile and select the *destination-rg* as the Resourec Group. +Select a name for the Traffic Manager profile and select the _destination-rg_ as the Resourec Group. ![image](./img/prep10.png) -From the Load Balancing overview page select *Traffic Manager* and select the previously created Traffic Manager profile. -Select *Endpoints* and click *Add*. Add each public IP of the source and destination Load Balancer as separate endpoints. +From the Load Balancing overview page select _Traffic Manager_ and select the previously created Traffic Manager profile. +Select _Endpoints_ and click _Add_. Add each public IP of the source and destination Load Balancer as separate endpoints. ![image](./img/prep11.png) -> [!NOTE] -> Please note: To be able to add the public IP addresses they need to be configured with an [DNS name lable](https://learn.microsoft.com/en-us/azure/dns/dns-custom-domain?toc=%2Fazure%2Fvirtual-network%2Ftoc.json#public-ip-address). - -![image](./img/prep11-1.png) - -Check the Overview section under the navigation pane and note that the source load balancer is shown as *online* whereas the -destination load balancer is shown as *degraded*. If you copy the DNS name of the Traffic Manager profile and paste it into your browser, you should be able to browse the source web servers through the Traffic Manager Profile. +Check the Overview section under the navigation pane and note that the source load balancer is shown as _online_ whereas the +destination load balancer is shown as _degraded_. If you copy the DNS name of the Traffic Manager profile and paste it into your browser, you should be able to browse the source web servers through the Traffic Manager Profile. ![image](./img/prep12.png) @@ -444,19 +474,19 @@ destination load balancer is shown as *degraded*. If you copy the DNS name of th ### **Task 7: Perform Final Migration** -Open the [Azure Portal](https://portal.azure.com) and navigate to the previousley created Azure Migrate project. Select *Servers, databases and web apps*, make sure that the right Azure Migrate Project is selected and click *Overview* in the *Migration tools* box. From the Overview section click in *Migrate* under *Step 3: Migrate*. +Open the [Azure Portal](https://portal.azure.com) and navigate to the previousley created Azure Migrate project. Select _Servers, databases and web apps_, make sure that the right Azure Migrate Project is selected and click _Overview_ in the _Migration tools_ box. From the Overview section click in _Migrate_ under _Step 3: Migrate_. ![image](./img/finalmig1.png) -Select *AzureVM* and click *Continue*. +Select _AzureVM_ and click _Continue_. ![image](./img/finalmig1-2.png) -Select *No* because shutdown of source machines is only supported for HyperVisor based migrations, select the two servers and click *Migrate*. +Select _No_ because shutdown of source machines is only supported for HyperVisor based migrations, select the two servers and click _Migrate_. ![image](./img/finalmig2.png) -You can check the progress of the migration under the *Jobs* section within the navigation pane. +You can check the progress of the migration under the _Jobs_ section within the navigation pane. ![image](./img/finalmig3.png) @@ -464,12 +494,12 @@ After a few minutes the migration should be successfully completed. ![image](./img/finalmig4.png) -When you change to the *Virtual machine* section within the Azure Portal you should now see 2 additional serves in the *destination-rg* Resource Group. -Please select the original source Virtual Machines and click on *Stop* to shutdown the source VMs. +When you change to the _Virtual machine_ section within the Azure Portal you should now see 2 additional serves in the _destination-rg_ Resource Group. +Please select the original source Virtual Machines and click on _Stop_ to shutdown the source VMs. ![image](./img/finalmig5.png) -Change to the Azure Traffic Manager profile you've created previousley and look at the endpoints. Please note that the *fe-source* endpoint is now shown as degraded and that the *fe-dest* endpoint is shown as online. +Change to the Azure Traffic Manager profile you've created previousley and look at the endpoints. Please note that the _fe-source_ endpoint is now shown as degraded and that the _fe-dest_ endpoint is shown as online. ![image](./img/finalmig6.png) @@ -477,15 +507,15 @@ From a user perspective nothing changed. You're still able to browse the Traffic ![image](./img/finalmig7.png) -🚀🚀🚀🚀🚀🚀 Congratulations, you've successfully migrated the frontend application to Azure.🚀🚀🚀🚀🚀🚀 +## 🚀 Congratulations, you've successfully migrated the frontend application to Azure.🚀 -### **Task 8: Cleanup** +### **Task 8: Stopping Replcation** -After the successfull migration you can now stop replicating the source virtual machines. Open the [Azure Portal](https://portal.azure.com) and navigate to the previousley created Azure Migrate project. Select *Servers, databases and web apps*, make sure that the right Azure Migrate Project is selected and click *Overview* in the *Migration tools* box. In the *Azure Migrate: Migration and modernization* pane, select *Replicating machines* from the navigation pane on the left, click on the 3 dots on the end of each row of the replicating servers and select *Stop replicating*. +After the successfull migration you can now stop replicating the source virtual machines. Open the [Azure Portal](https://portal.azure.com) and navigate to the previousley created Azure Migrate project. Select _Servers, databases and web apps_, make sure that the right Azure Migrate Project is selected and click _Overview_ in the _Migration tools_ box. In the _Azure Migrate: Migration and modernization_ pane, select _Replicating machines_ from the navigation pane on the left, click on the 3 dots on the end of each row of the replicating servers and select _Stop replicating_. ![image](./img/finalmig8.png) -Select *Stop replication and remove replication settings* from the drop down list and click *OK*. Repeat this step for the remaining Server. +Select _Stop replication and remove replication settings_ from the drop down list and click _OK_. Repeat this step for the remaining Server. ![image](./img/finalmig9.png) @@ -493,14 +523,23 @@ From the Traffic Manager Profile you can now also safley remove the endpoint for ![image](./img/finalmig10.png) -🚀🚀🚀 You successfully completed challenge 5! 🚀🚀🚀 +# 🚀 **Congratulations!** + +You successfully completed the MicroHack. The deployed architecture now looks like the following diagram. ![image](./img/Challenge-5.jpg) -🚀🚀🚀 **!!!Congratulations!!! - You successfully completed the MicroHack. You can now safley remove the *source-rg* and *destination-rg* Resource Groups.** 🚀🚀🚀 +### **Task 9 : Cleanup** + +> [!NOTE] +> +> If you still want to continue, there are 2 additional bonus challenges to secure OR modernize the migrated environment. +> +> Continue with either [Bonus Challenge 6 solution](../challenge-6/solution.md) +> OR [Bonus Challenge 7 solution](../challenge-7/solution.md) -🚀🚀🚀 **If you still want to continue we have 2 additional bonus challenges to modernize OR secure the migrated environment.**🚀🚀🚀 +Otherwise please help us clean up the workhop environment. You can now safley remove the _source-rg_ and _destination-rg_ Resource Groups. - **[Home](../../Readme.md)** - Continue with either [Bonus Challenge 6 solution](../challenge-6/solution.md) OR [Bonus Challenge 7 solution](../challenge-7/solution.md) +[Home](../../Readme.md) diff --git a/03-Azure/01-03-Infrastructure/06_Migration_Secure_AI_Ready/walkthrough/challenge-6/solution.md b/03-Azure/01-03-Infrastructure/06_Migration_Secure_AI_Ready/walkthrough/challenge-6/solution.md index db7cc70f..bd9d66a7 100644 --- a/03-Azure/01-03-Infrastructure/06_Migration_Secure_AI_Ready/walkthrough/challenge-6/solution.md +++ b/03-Azure/01-03-Infrastructure/06_Migration_Secure_AI_Ready/walkthrough/challenge-6/solution.md @@ -10,19 +10,19 @@ Please make sure that you successfully completed [Challenge 5](../challenge-5/so In [Challenge 5](../challenge-5/solution.md) we migrated two servers to Azure. The servers are already protected by the basic services of Defender for Cloud. In this challenge, we'll improve significantly the protection level by activating advanced services such as "Cloud Security Posture Management (CSPM)" and "Cloud Workload Protection (CWP)" (Defender for Server). -To enable the advanced Defender for Cloud components, open the portal and select *Defender for Cloud*. Under *Management*, select the *Environment Settings* to define the Defender for Cloud setting for the subscription. +To enable the advanced Defender for Cloud components, open the portal and select _Defender for Cloud_. Under _Management_, select the _Environment Settings_ to define the Defender for Cloud setting for the subscription. ![image](./img/Def-environment-settings.jpg) -In the settings, enable *Defender CSPM* and *Defender for Server* plans to better protect the migrated servers from threats. After enabling the plans, use the "Settings" link for both plans and verify that all features are enabled. Finally *Save* the new configuration. +In the settings, enable _Defender CSPM_ and _Defender for Server_ plans to better protect the migrated servers from threats. After enabling the plans, use the "Settings" link for both plans and verify that all features are enabled. Finally _Save_ the new configuration. ![image](./img/Def-environment-settings.jpg) -Verify the *Defender CSPM* Settings & monitoring details +Verify the _Defender CSPM_ Settings & monitoring details ![image](./img/Def-CSPM-monitoring.png) -Verify the *Defender for Server* Settings & monitoring details +Verify the _Defender for Server_ Settings & monitoring details ![image](./img/Def-DefenderServerSettings.png) @@ -31,34 +31,35 @@ Verify the *Defender for Server* Settings & monitoring details ## **Task 2: Check if Defender for Endpoint is active on the virtual machines** -To check if *Defender for Server* was successfully activated on the virtual machines, open the portal and select *Virtual Machines* and select a Windows Server. Under *Operations'* select to run a command and chose to run a PowerShell script/command. +To check if _Defender for Server_ was successfully activated on the virtual machines, open the portal and select _Virtual Machines_ and select a Windows Server. Under _Operations'_ select to run a command and chose to run a PowerShell script/command. ![image](./img/VM-runps.png) -Run the *Get-MpComputerStatus* cmdlet to get the status of antimalware software installed on the virtual machine. +Run the _Get-MpComputerStatus_ cmdlet to get the status of antimalware software installed on the virtual machine. + +> [!NOTE] Keep in mind that you might need to scroll up in the response window. ![image](./img/vmatpstatus.png) -On a Linux machine you run a shell script instead of PowerShell - the commandline *mdatp health* will return the health of the *Defender for Endpoint* on a Linux box. +On a Linux machine you run a shell script instead of PowerShell - the commandline _mdatp health_ will return the health of the _Defender for Endpoint_ on a Linux box. ![image](./img/vmlinuxatpstatus.png) - ## **Task 3: Check if a virus attack is reported in Azure** In the next step, we check whether the infection with malware is reported to Azure, so that appropriate reactions can be triggered based on an alert - e.g. inform administrators, open an incident or follow up on the problem and initiate appropriate measures or react to such incidents with automatic rules. -Open the portal and select *Virtual Machines* and select a Windows Server. Select *Connect* and establish a connection with the virtual machines using *Bastion*. +Open the portal and select _Virtual Machines_ and select a Windows Server. Select _Connect_ and establish a connection with the virtual machines using _Bastion_. ![image](./img/vmconnect.png) -The European Institute for Computer Antivirus Research (EICAR) and Computer Antivirus Research Organization (CARO), provide a harmless test file to test the response of computer antivirus programs. Instead of using real malware, which could cause real damage, this test file allows people to test anti-virus software without having to use a real computer virus. Open the following UIRL in a browser in the virtual machine: https://www.eicar.org/download-anti-malware-testfile/ +The European Institute for Computer Antivirus Research (EICAR) and Computer Antivirus Research Organization (CARO), provide a harmless test file to test the response of computer antivirus programs. Instead of using real malware, which could cause real damage, this test file allows people to test anti-virus software without having to use a real computer virus. Open the following UIRL in a browser in the virtual machine: https://www.eicar.org/download-anti-malware-testfile/ -Scroll down a bit until you can see the 68 character long EICAR string. +Scroll down a bit until you can see the 68 character long EICAR string. ![image](./img/vm-eicarstring.png) -We will not try to download a test-file from the website, because this will be blocked by the browser already. Instead, we will create a new file on the virtual machine and paste the EICAR string into and try to safe the file. +We will not try to download a test-file from the website, because this will be blocked by the browser already. Instead, we will create a new file on the virtual machine and paste the EICAR string into and try to safe the file. Select the EICAR String and copy it into the clipboard. Create a new file on the desktop and paste the EICAR string into the file. @@ -70,15 +71,15 @@ Try to safe the file. Defender for Endpoint will trigger - it'll quarantine the ![image](./img/vmthreat.png) -Next, we will double-check if this alert was forwarded to Azure. Open the portal and select *Defender for Cloud* and select *Security Alerts*. EICAR malware detections are reported with severity "Informational" - to include these alerts in the view you need to change the filter: Add severity "informational" in the filter settings - and the security alerts will be displayed. +Next, we will double-check if this alert was forwarded to Azure. Open the portal and select _Defender for Cloud_ and select _Security Alerts_. EICAR malware detections are reported with severity "Informational" - to include these alerts in the view you need to change the filter: Add severity "informational" in the filter settings - and the security alerts will be displayed. ![image](./img/DefSecAlert.png) -## **Task 4: Explore *Defender for Cloud* proactive security advice** +## **Task 4: Explore _Defender for Cloud_ proactive security advice** -The challenges in this Microhack were designed to be simple and implemented straight forward as virtual machines in a single subscription. The implementation of a secure and scalable landing zone according to the best practices from the *Cloud Adaption Framework* ([What is an Azure landing zone? - Cloud Adoption Framework | Microsoft Learn](https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/ready/landing-zone/)) was waived for the sake of simplicity. +The challenges in this Microhack were designed to be simple and implemented straight forward as virtual machines in a single subscription. The implementation of a secure and scalable landing zone according to the best practices from the _Cloud Adaption Framework_ ([What is an Azure landing zone? - Cloud Adoption Framework | Microsoft Learn](https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/ready/landing-zone/)) was waived for the sake of simplicity. -On the other hand, this now causes *Defender for Cloud* making a number of recommendations on how to proactively improve the security of the environment. +On the other hand, this now causes _Defender for Cloud_ making a number of recommendations on how to proactively improve the security of the environment. To view general security recommendations for the managed virtual machines, please open the portal and select Defender for Cloud. Under Security Posture, you can view the recommendations in detail. ![image](./img/secpost01.png) @@ -87,26 +88,24 @@ Click on Security Posture to view a list of recommendations for the various reso ![image](./img/secpost02.png) -The list of recommendations for your environment will look slightly different than in this screenshot, because the resource that you've installed might experience different vulnerabilities. Review the recommendations and click them to view the details. In the details for each recommendation, you'll find a description, you can assign the recommendation to a user for implementation or you can create an exempt. +The list of recommendations for your environment will look slightly different than in this screenshot, because the resource that you've installed might experience different vulnerabilities. Review the recommendations and click them to view the details. In the details for each recommendation, you'll find a description, you can assign the recommendation to a user for implementation or you can create an exempt. -Go back to *Defender for Cloud* and click on *Attack path analysis* - this will provide you an overview about specific vulnerabilities in your environment and how they can be utilized by attackers to compromise your environment. +Go back to _Defender for Cloud_ and click on _Attack path analysis_ - this will provide you an overview about specific vulnerabilities in your environment and how they can be utilized by attackers to compromise your environment. ![image](./img/secpost03.png) -In this Microhack, we deployed virtual machines that use public IP addresses and are directly exposed to the internet - this is straight forward, but for sure not a best practice. Click on one of the *Attack paths* to learn more about the details of this attack vector. +In this Microhack, we deployed virtual machines that use public IP addresses and are directly exposed to the internet - this is straight forward, but for sure not a best practice. Click on one of the _Attack paths_ to learn more about the details of this attack vector. ![image](./img/secpost04.png) - ## **Task 4: Enable and configure Copilot for Security** Sign in to Copilot for Security (https://securitycopilot.microsoft.com). - - - You successfully completed challenge 6! 🚀🚀🚀 -🚀🚀🚀 **!!!Congratulations!!! - You successfully completed the MicroHack. You can now safley remove the *source-rg* and *destination-rg* Resource Groups.** 🚀🚀🚀 +🚀🚀🚀 **!!!Congratulations!!! - You successfully completed the MicroHack.** 🚀🚀🚀 + +Feel free to contrinue to [Bonus Challenge 7 solution](../challenge-7/solution.md) or help us clean up the workhop environment. You can now safley remove the _source-rg_ and _destination-rg_ Resource Groups. - **[Home](../../Readme.md)** \ No newline at end of file +**[Home](../../Readme.md)** diff --git a/03-Azure/01-03-Infrastructure/06_Migration_Secure_AI_Ready/walkthrough/challenge-7/gitDeploy.md b/03-Azure/01-03-Infrastructure/06_Migration_Secure_AI_Ready/walkthrough/challenge-7/gitDeploy.md new file mode 100644 index 00000000..7b7cbbae --- /dev/null +++ b/03-Azure/01-03-Infrastructure/06_Migration_Secure_AI_Ready/walkthrough/challenge-7/gitDeploy.md @@ -0,0 +1,153 @@ +# Modernizing with Azure - Git-based deployment + +In this solution apporach you will use the "Local Git" deployment model to transfer the content of the current Web app. While this solution is usig direct Git push to the App service, a more common way would be to push the code into a central Git repo (if not already used for deployment) and deploy it from there to App Service. + +## Materials + +- https://learn.microsoft.com/en-us/azure/app-service/deploy-local-git?tabs=cli + +## Task 1 - Install Git + +1. Connect to the migrated Windows server using Bastion +2. [Download the Git client](https://www.git-scm.com/downloads) and install, using the default settings for the installer. +3. Open a command prompt or PowerShell to test git to see if install available +4. Configure Credential Manager + + `git config --global credential.helper wincred` + +## Task 2 - Create Azure App Service + +The following commands are easiest sumbitted using _Cloud Shell_ in Azure Portal. + +1. Create App Service Plan + + ``` + az appservice plan create \ + --name mh1-asp-test \ + --resource-group mh-rg1 \ + --sku P0v3 + ``` + + > [!NOTE] + > + > Because the environment uses Azure Traffic Manager as entrypoint, the neessary App Service Plan needs to be Standard or Premium. In this simplified scenario with two backend servers, Azure App Service alone could be used to serve the workload, unless global load balancing would be required. + +2. Create Web app, with "Local Git" deployment model + + ``` + az webapp create \ + --resource-group mh-rg1 \ + --name mh1-app \ + --plan mh1-asp \ + --deployment-local-git + ``` + +3. Enable Basic Auth and set Deployment Password + + ``` + az webapp deployment user set \ + --user-name mh1-deploy \ + --password "mh1-Deploy" + ``` + +4. Fetch Git URL + ``` + az webapp deployment source config-local-git \ + --resource-group mh-rg1 \ + --name mh1-app \ + --query url \ + --output tsv + ``` + +## Task 3 - Initialize Git repo for the current app + +Back on the Windows server you need to convert the code base to a Git repo and connect it to the App Service. + +1. Change to the home folder of the Web app + + ``` + cd C:\inetpub\wwwrootebroot + ``` + +2. Initialize Repo + + ``` + git init + ``` + +3. Legitimize webroot directory + + ``` + git config --global --add safe.directory C:/inetpub/wwwroot + ``` + +4. Connect to Azure App Service + + ``` + git remote add azure https://mh1-app.scm.azurewebsites.net:443/mh1-app.git + ``` + +5. personalize git repo + + ``` + git config --global user.email "you@example.com" + git config --global user.name "Your Name" + ``` + +6. Commit initial files + + ``` + git commit -m "initial commit" + ``` + +7. Push content + + ``` + git push azure master + ``` + +> [!Note] You will be challenged for the deployment credentials. + +## **Task 3 : Disable Basic Auth for SCM** + +Since _BasicAuth_ does have security implications it is a good idea to disable it, once no longer needed for deployments. + + az resource update \ + --resource-group mh-rg1 \ + --name scm \ + --namespace Microsoft.Web \ + --resource-type basicPublishingCredentialsPolicies \ + --parent sites/mh1-app \ + --set properties.allow=false + +> [!TIP] To re-enable, simply change the parameter accordingly. Once you have re-enabled it, you will need to create a new set of credentials using the command from Task 1, Step 3. +> +> ``` +> -set properties.allow=true +> ``` + +### **Task 2: Update Traffic Manager profile** + +The Traffic Manager profile is still pointing to the previousley migrated Virtual Machines. You can now update the endpoints within the profile to point to the App Services instead of the VMs. + +From the Azure Portal open the Load Balancing blade, select Traffic Manager on the navigation pane and select the previously created _tfp-frontend_ Traffic Manager profile. Select _Endpoints_ and click _Add_. + +![image](./img/tfupdate1.png) + +Select _Azure endpoint_, provide a name, select _App Service_ and select the previousley created App Service. + +![image](./img/tfupdate2.png) + +Next delete the endpoints for the Virtual Machines. + +![image](./img/tfupdate3.png) + +You can now browse to the Traffic Manager profile. Again, from a user perspective nothing changed but you are now browsing the web site content that is hosted on Azure App Service instead of Virtual Machines. + +You successfully completed challenge 7! 🚀🚀🚀 + +🚀 **Congratulations!** + +You successfully completed the MicroHack. You can now safeley remove the _source-rg_ and _destination-rg_ Resource Groups.\*\* 🚀🚀🚀 + +**[Home](../../Readme.md)** diff --git a/03-Azure/01-03-Infrastructure/06_Migration_Secure_AI_Ready/walkthrough/challenge-7/migrationAssistantDeploy.md b/03-Azure/01-03-Infrastructure/06_Migration_Secure_AI_Ready/walkthrough/challenge-7/migrationAssistantDeploy.md new file mode 100644 index 00000000..c0eeff46 --- /dev/null +++ b/03-Azure/01-03-Infrastructure/06_Migration_Secure_AI_Ready/walkthrough/challenge-7/migrationAssistantDeploy.md @@ -0,0 +1,97 @@ +# Modernizing with Azure - Azure App Service Migration Assistant + +Azure App Service Migration Assistant is a tool to help you to quickly and easily do a one-time migration of your web application to an Azure App Service. The following steps will guide you through the process. + +> [!NOTE] +> +> The server names below are for illustration purposes only. The steps should be performed on the windows server you migrated in Challenge 5. + +### **Task 1 : Set up Azure App Service Migration Assistant** + +Login to the Virtual Machine _frontend1_ in the _destination-rg_ Resource Group via Azure Bastion, open the [Azure Portal](https://portal.azure.com) from the _frontend1_ VM and navigate to the previousley created Azure Migrate project. Select _Servers, databases and web apps_, **make sure that the right Azure Migrate Project is selected** and click on _Replicate_ within the _Migration tools_ box. + +![image](./img/modernize1.png) + +On the next page select _ASP.NET web apps_, _Azure App Service code_, _Pyhsical or others (AWS, GCP, Xen, etc)_ and click on the link below to be redirected to the [App Service migration assistant tool](https://learn.microsoft.com/en-us/azure/app-service/app-service-asp-net-migration). + +![image](./img/modernize2.png) + +Navigate to _App Service migration tools and resources_ and click on the link to download the [App Service Migration Assistant](https://appmigration.microsoft.com/api/download/windows/AppServiceMigrationAssistant.msi) (1) and after the file was downloaded click on the link to be redirectioed to the [documentation](https://github.com/Azure/App-Service-Migration-Assistant/wiki/PowerShell-Scripts) (2) for the App Service Migration Assistant. + +![image](./img/modernize3.png) + +Change to your download location e.g. \\\Downloads and double-click the AppServiceMigrationAssistant.msi file. + +![image](./img/modernize4.png) + +The installation should finish without any input requirements. After the installation you will find a shortcut on the Desktop to start the App Service Migration Assistant. Double-click on the shortcut to start the App Service Migration Assistant. + +![image](./img/modernize5.png) + +Under _Choose a Site_ select _Default Web Site_ and click next. + +![image](./img/modernize6.png) + +Wait until the assessment report is finished and click next under _Assessment Report_ + +![image](./img/modernize7.png) + +Under _Login to Azure_, click on _Copy Code & Open Browser_ and login to Azure using your credentials. + +![image](./img/modernize8.png) + +Select _Continue_ when prompted to allow to sign in to the _Azure App Service Migration Assistant_ application. You can then close the browser. + +![image](./img/modernize9.png) + +Select the correct Azure Migrate project and click next. + +![image](./img/modernize10.png) + +Under _Azure Options_, select the correct Azure Subscription and Resource Group. Next specify a unique name for your web app. Select to create a new App Service Plan and choose the region of your choise. Click _Migrate_ to start the migration. + +![image](./img/modernize11.png) + +The migration should complete successfully. You can now click on _Go to your website_ to open the migrated web app now running on Azure App Services. + +![image](./img/modernize12.png) + +Change back to the Azure Portal and open the Resource Group _destination-rg_. You should now see a App Service and a App Service Plan resource. Click on the App Service and select _Browse_ to open your web app again. + +![image](./img/modernize13.png) + +![image](./img/modernize13-1.png) + +You should now see the web site content that was previously running on Windows Server IIS. + +![image](./img/modernize14.png) + +### **Task 2: Update Traffic Manager profile** + +The Traffic Manager profile is still pointing to the previousley migrated Virtual Machines. You can now update the endpoints within the profile to point to the App Services instead of the VMs. + +From the Azure Portal open the Load Balancing blade, select Traffic Manager on the navigation pane and select the previously created _tfp-frontend_ Traffic Manager profile. Select _Endpoints_ and click _Add_. + +![image](./img/tfupdate1.png) + +Select _Azure endpoint_, provide a name, select _App Service_ and select the previousley created App Service. + +![image](./img/tfupdate2.png) + +Next delete the endpoints for the Virtual Machines. + +![image](./img/tfupdate3.png) + +You can now browse to the Traffic Manager profile. Again, from a user perspective nothing changed but you are now browsing the web site content that is hosted on Azure App Service instead of Virtual Machines. + +![image](./img/tfupdate4.png) + +You successfully completed challenge 7! 🚀🚀🚀 + +The deployed architecture now looks like the following diagram. + +![image](./img/Challenge-complete.jpg) + +🚀🚀🚀 **!!!Congratulations!!! - You successfully completed the MicroHack. You can now safeley remove the _source-rg_ and _destination-rg_ Resource Groups.** 🚀🚀🚀 + +**[Home](../../Readme.md)** - diff --git a/03-Azure/01-03-Infrastructure/06_Migration_Secure_AI_Ready/walkthrough/challenge-7/solution.md b/03-Azure/01-03-Infrastructure/06_Migration_Secure_AI_Ready/walkthrough/challenge-7/solution.md index 62d0b9cd..8addb0f9 100644 --- a/03-Azure/01-03-Infrastructure/06_Migration_Secure_AI_Ready/walkthrough/challenge-7/solution.md +++ b/03-Azure/01-03-Infrastructure/06_Migration_Secure_AI_Ready/walkthrough/challenge-7/solution.md @@ -12,34 +12,36 @@ The Azure Migrate tool offers additional capabilities that make it easier for yo Azure App Service bulk migration capabilities are now available as an Azure Migrate feature: -* Discover and assess ASP.NET web apps in addition to categorizing which apps are ready for migration. -* Suggest a destination for migration and provide a guided content and configuration experience for ASP.NET web apps to Azure App Service. -* Discover and migrate with Java Tomcat applications to App Service Linux and to Azure Kubernetes Service. -* Containerize your ASP.NET web apps and move them to either Windows Containers on App Service or to Azure Kubernetes Service. +- Discover and assess ASP.NET web apps in addition to categorizing which apps are ready for migration. +- Suggest a destination for migration and provide a guided content and configuration experience for ASP.NET web apps to Azure App Service. +- Discover and migrate with Java Tomcat applications to App Service Linux and to Azure Kubernetes Service. +- Containerize your ASP.NET web apps and move them to either Windows Containers on App Service or to Azure Kubernetes Service. -> [!WARNING] +> [!CAUTION] +> > **Currently this feature has a few [limitations](https://learn.microsoft.com/en-us/azure/migrate/concepts-migration-webapps#limitations) and therefore it can't be used to migrate web apps directly from physical servers. However, we can use it at least to perform the assessment of our web apps and use the [App Service migration assistant tool](https://learn.microsoft.com/en-us/azure/app-service/app-service-asp-net-migration) for the migration. Please note that this will only work for the migrated Windows VM** -> [!WARNING] +> [!IMPORTANT] +> > **Please note that this challenge will only work for the migrated Windows VM. Currently we do not support direct migrations from Linux VMs** -Open the [Azure Portal](https://portal.azure.com) and navigate to the previousley created Azure Migrate project. Select *Servers, databases and web apps*, **make sure that the right Azure Migrate Project is selected** and click on *Assess* and select *Web Apps on Azure* from the drop down list. +Open the [Azure Portal](https://portal.azure.com) and navigate to the previousley created Azure Migrate project. Select _Servers, databases and web apps_, **make sure that the right Azure Migrate Project is selected** and click on _Assess_ and select _Web Apps on Azure_ from the drop down list. ![image](./img/appservice1.png) -Under *Basics* select *Web Apps on Azure* and *Web apps to App Service* and provide your desired assessment settings. +Under _Basics_ select _Web Apps on Azure_ and _Web apps to App Service_ and provide your desired assessment settings. ![image](./img/appservice2.png) -Under *Select servers to assess*, provide a Assessment name and select the previously created Group. +Under _Select servers to assess_, provide a Assessment name and select the previously created Group. ![image](./img/appservice3.png) -Proceed to the last section *Review + create assessment* and click *Create assessment* +Proceed to the last section _Review + create assessment_ and click _Create assessment_ ![image](./img/appservice4.png) -From the *Azure Migrate:Discovery and assessment* page select the *Web apps on Azure* assessment. +From the _Azure Migrate:Discovery and assessment_ page select the _Web apps on Azure_ assessment. ![image](./img/appservice5.png) @@ -53,96 +55,11 @@ Review the output of the assessment to see if the web app currently running on W ### **Task 2: Modernize web app to Azure App Service Code** -> [!WARNING] +> [!CAUTION] +> > **As mentioned above, the current [limitations](https://learn.microsoft.com/en-us/azure/migrate/concepts-migration-webapps#limitations) will not allow the direct migration of web apps running on physical machines. Therefore, we will use the [App Service migration assistant tool](https://learn.microsoft.com/en-us/azure/app-service/app-service-asp-net-migration) for the migration.** +There are multiple different ways to migrate legacy Web apps to Azure: -Login to the Virtual Machine *frontend1* in the *destination-rg* Resource Group via Azure Bastion, open the [Azure Portal](https://portal.azure.com) from the *frontend1* VM and navigate to the previousley created Azure Migrate project. Select *Servers, databases and web apps*, **make sure that the right Azure Migrate Project is selected** and click on *Replicate* within the *Migration tools* box. - -![image](./img/modernize1.png) - -On the next page select *ASP.NET web apps*, *Azure App Service code*, *Pyhsical or others (AWS, GCP, Xen, etc)* and click on the link below to be redirected to the [App Service migration assistant tool](https://learn.microsoft.com/en-us/azure/app-service/app-service-asp-net-migration). - -![image](./img/modernize2.png) - -Navigate to *App Service migration tools and resources* and click on the link to download the [App Service Migration Assistant](https://appmigration.microsoft.com/api/download/windows/AppServiceMigrationAssistant.msi) (1) and after the file was downloaded click on the link to be redirectioed to the [documentation](https://github.com/Azure/App-Service-Migration-Assistant/wiki/PowerShell-Scripts) (2) for the App Service Migration Assistant. - -![image](./img/modernize3.png) - -Change to your download location e.g. \\\Downloads and double-click the AppServiceMigrationAssistant.msi file. - -![image](./img/modernize4.png) - -The installation should finish without any input requirements. After the installation you will find a shortcut on the Desktop to start the App Service Migration Assistant. Double-click on the shortcut to start the App Service Migration Assistant. - -![image](./img/modernize5.png) - -Under *Choose a Site* select *Default Web Site* and click next. - -![image](./img/modernize6.png) - -Wait until the assessment report is finished and click next under *Assessment Report* - -![image](./img/modernize7.png) - -Under *Login to Azure*, click on *Copy Code & Open Browser* and login to Azure using your credentials. - -![image](./img/modernize8.png) - -Select *Continue* when prompted to allow to sign in to the *Azure App Service Migration Assistant* application. You can then close the browser. - -![image](./img/modernize9.png) - -Select the correct Azure Migrate project and click next. - -![image](./img/modernize10.png) - -Under *Azure Options*, select the correct Azure Subscription and Resource Group. Next specify a unique name for your web app. Select to create a new App Service Plan and choose the region of your choise. Click *Migrate* to start the migration. - -![image](./img/modernize11.png) - -The migration should complete successfully. You can now click on *Go to your website* to open the migrated web app now running on Azure App Services. - -![image](./img/modernize12.png) - -Change back to the Azure Portal and open the Resource Group *destination-rg*. You should now see a App Service and a App Service Plan resource. Click on the App Service and select *Browse* to open your web app again. - -![image](./img/modernize13.png) - -![image](./img/modernize13-1.png) - -You should now see the web site content that was previously running on Windows Server IIS. - -![image](./img/modernize14.png) - -**Repeat the above steps for the frontend2 VM** - -### **Task 3: Update Traffic Manager profile** - -The Traffic Manager profile is still pointing to the previousley migrated Virtual Machines. You can now update the endpoints within the profile to point to the App Services instead of the VMs. - -From the Azure Portal open the Load Balancing blade, select Traffic Manager on the navigation pane and select the previously created *tfp-frontend* Traffic Manager profile. Select *Endpoints* and click *Add*. - -![image](./img/tfupdate1.png) - -Select *Azure endpoint*, provide a name, select *App Service* and select the previousley created App Service. - -![image](./img/tfupdate2.png) - -Next delete the endpoints for the Virtual Machines. - -![image](./img/tfupdate3.png) - -You can now browse to the Traffic Manager profile. Again, from a user perspective nothing changed but you are now browsing the web site content that is hosted on Azure App Service instead of Virtual Machines. - -![image](./img/tfupdate4.png) - -You successfully completed challenge 6! 🚀🚀🚀 - -The deployed architecture now looks like the following diagram. - -![image](./img/Challenge-complete.jpg) - -🚀🚀🚀 **!!!Congratulations!!! - You successfully completed the MicroHack. You can now safley remove the *source-rg* and *destination-rg* Resource Groups.** 🚀🚀🚀 - - **[Home](../../Readme.md)** - \ No newline at end of file +- **Code-Migration** : via [Git-based](gitDeploy.md) to Azure App Service or by using the [Azure App Service Migration Assistant](./migrationAssistantDeploy.md) +- **Containerization** : Azure Container Apps, Azure Kubernetes Service, Azure App Service for Containers, Azure Container Instance diff --git a/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/Readme.md b/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/Readme.md new file mode 100644 index 00000000..67239c5f --- /dev/null +++ b/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/Readme.md @@ -0,0 +1,265 @@ +![image](img/1920x300_EventBanner_MicroHack_General_wText.jpg) + +# **MicroHack - Azure Landing Zones with Microsoft Cloud Adoption Framework** + +- [**MicroHack introduction**](#MicroHack-introduction) +- [**MicroHack context**](#microhack-context) +- [**Objectives**](#objectives) +- [**MicroHack Challenges**](#microhack-challenges) +- [**Contributors**](#contributors) + +# MicroHack introduction + +This MicroHack scenario walks through the use of Microsoft Cloud Adoption Framework and its Landing Zone Accelerators with a focus on the best practices and the design principles. + +![image](Path to the high level architecture ) + +This lab is not a full explanation of setting up a Landing Zone and all involved technologies, please consider the following articles required pre-reading to build foundational knowledge. + +- [Microsoft Cloud Adoption Framework for Azure](https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/) + - [What is a Landing Zone?](https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/ready/landing-zone/) +- [What is Bicep?](https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/overview?tabs=bicep) + +Optional (read this after completing this lab to take your learning even deeper!) + +# MicroHack context + +The foundation of a successful cloud journey is a structured approach to workload deplyoment and governance. For Microsoft Azure, these guiding principals are collected under the Microsoft Cloud Adoption Framework umbrella. + +As the architect of such cloud journey it is imperative to understand the core requirements and the best practises of implementing those in order to create a clean foundation for scalable cloud deployments and flexibility, while maintaining guardrails and governance across the board. + +We will follow the Microsoft Cloud Adoption Framework for Azure's methodology by using the Bicep Accelerator and its module strucutre. + +![image](https://learn.microsoft.com/en-us/azure/architecture/landing-zones/bicep/images/high-level-deployment-flow.png#lightbox) + +While green field scenariso would start with Module 1 (Management Groups Module), we have set up corresponding assets for each participant followng Module 1 through 3 and the hands-on activiteis will commence with Module 4 (Logging & Security Module). + +# Objectives + +After completing this MicroHack you will: + +- Know how to conceptuallize a landing zone in Microsoft Azure +- Understand the best practise accelerators and how to use them +- Know how to customize the accelerators to build upon them to tailor the landing zone to your organizations specific needs + +# MicroHack challenges + +## General prerequisites + +When using a predefined workshop environment, all prerequisites have been set up for you already and you should have been issued user credentials and an assigned resource group for running the challenges. + +The accelerator can (and has to be) customized via parameters (and possible code changes). For this purpose make sure you clone the [ALZ-Bicep repository](https://github.com/Azure/ALZ-Bicep) + +```bash +git clone https://github.com/Azure/ALZ-Bicep.git +``` + +If you want to run though the whole experience in your own environment, please refer to the [Prerequistes Section](https://github.com/Azure/ALZ-Bicep/wiki/DeploymentFlow#prerequisites) of the Azure Landing Zone Deployment Flow instructions. + +### Learing Resources + +- [Deployment Flow Wiki](https://github.com/Azure/ALZ-Bicep/wiki/DeploymentFlow) +- [Design Considerations of Azure Landing Zone concept](https://learn.microsoft.com/en-us/azure/architecture/landing-zones/bicep/landing-zone-bicep) + +## Accelerator for Bicep - Deployment Flow + +![image](https://learn.microsoft.com/en-us/azure/architecture/landing-zones/bicep/images/high-level-deployment-flow.png) + +## Challenge 1 - Core Setup + +### Goal + +You should create a Management Group hierarchy in accordance with the Microsoft Cloud Adoption Framework for Azure. Please make sure you read the COMPLETE list of expected actions in order to plan accordingly from the get-go. Based on this hierarchy, the respective Custom Policy Definitions and Custom Role Definitiosn will be deployed to your landing zone. + +### Actions + +- Deploy a management group hierarchy in your tenant under the managment group assigned to you (to be assumed the Root Managment Group). +- Deploy the custom Azure Policy Definitions & Initiatives supplied by the Azure Landing Zones conceptual architecture and reference implementation defined [here](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/enterprise-scale/architecture) to the specified Management Group. (Make sure you prefix all so the names become unique in this shared environment) +- Define custom roles based on the recommendations from the Azure Landing Zone Conceptual Architecture. The role definitions are defined in [Identity and access management](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/enterprise-scale/identity-and-access-management) recommendations. + +### Success criteria + +- You feel confident in how to create a Management Group hierarchies in accordance with the Microsoft Cloud Adoption Framework for Azure +- You successfully deployed a corresponding Managemnt Group hierarchy within the Management Group branch assigned to you + +### Learning resources + +- https://learn.microsoft.com/en-us/azure/architecture/landing-zones/bicep/landing-zone-bicep +- https://github.com/Azure/ALZ-Bicep/wiki/DeploymentFlow#deployment-identity + +### Solution + +> [!warning] +> SPOILER - You can find pointers to a faster solution in the [solution document](./walkthrough/solution.md) + +## Challenge 2 - Logging & Security + +### Goal + +Configures a centrally managed Log Analytics Workspace, Automation Account and Sentinel. + +As optional content you can also look at Management Groups Diagnostic Settings to enable Diagnostic Settings for Management Groups to the Log Analytics Workspace created in the Logging subscription. + +> [!NOTE] +> In the pre-defined workshop environment you need to apply Module 4.1 to the Management Group associated with your specific user. + +### Actions + +- Deploy Azure Log Analytics Workspace, Automation Account (linked together) & multiple Solutions to an existing Resource Group +- [optional] Enable Diagnostic Settings on the Management Group hierarchy that was defined during the deployment of the Management Group + +### Success criteria + +- You provisioned several data collection rules (VM Insights, Change Tracking, and Defender for SQL) as well as a user-assigned managed identity (UAMI). +- [optional] You have successfully enabled (and validated) Diagnostic Settings on the Management Group scope + +### Learning resources + +- [infra-as-code/bicep/modules/logging](https://github.com/Azure/ALZ-Bicep/tree/main/infra-as-code/bicep/modules/logging) +- [infra-as-code/bicep/orchestration/mgDiagSettingsAll](https://github.com/Azure/ALZ-Bicep/tree/main/infra-as-code/bicep/orchestration/mgDiagSettingsAll)] + +### Solution + +> [!warning] +> SPOILER - You can find pointers to a faster solution in the [solution document](./walkthrough/solution.md) + +## Challenge 3 - Core Connectivity + +### Goal + +Create the core connectivity infrastructure (Hub vnet or vWAN Hub) correspoding to the best practises of Microsoft Cloud Adoption Framework for Azure. + +### Actions + +- Define hub networking based on the recommendations from the Azure Landing Zone Conceptual Architecture. +- Make sure you DO NOT deploy DDoS Protection during this step! +- [Alternative] Deploy the Virtual WAN network topology and its components according to the Azure Landing Zone conceptual architecture which can be found [here](https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/ready/azure-best-practices/virtual-wan-network-topology). + +### Success criteria + +- Your environment now contains a complete connectivity infrastructure, either based on Hub vNet or vWAN Hub. + +### Learning resources + +- [Netowrk Topoligy Considerations](https://github.com/Azure/ALZ-Bicep/wiki/DeploymentFlow#network-topology-deployment) + +### Solution + +> [!warning] +> SPOILER - You can find pointers to a faster solution in the [solution document](./walkthrough/solution.md) + +## Challenge 4 - Role Assignments + +### Goal + +Role assignments are part of [Identity and Access Management (IAM)](https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/ready/enterprise-scale/identity-and-access-management), which is one of the critical design areas in Enterprise-Scale Architecture. + +In this challenge you need to prepare a resource group for later workload deployment by creating it and assigning the appropriate roles. + +> [!NOTE] +> For this challenge, and the deployment happening later in this workshop, you have been issued a separate set of user credentials, so the assignment exercise should be performed on this _deployment_ user. + +### Actions + +- Create resource group that will later hold a specific workload +- Ensure your user has the appropriate role on the created resource group for workload deployment assigned (In a later challenge we will use that user to deploy the demo workload) + +### Success criteria + +- Necessary RBAC-roles were assgined +- You can successfully log in as that user and access the resource group + +### Learning resources + +- [infra-as-code/bicep/modules/roleAssignments](https://github.com/Azure/ALZ-Bicep/tree/main/infra-as-code/bicep/modules/roleAssignments) + +### Solution + +> [!warning] +> SPOILER - You can find pointers to a faster solution in the [solution document](./walkthrough/solution.md) + +## Challenge 5 - Subscription Placement + +In proper production environments you would place subscriptions into their respective management groups in order to inherit the corresponding configurations, like RBAC roles, policy assignments, etc. + +> [!NOTE] +> In this workshop environment we are using a shared subscription for all participants and therefore moving subscripitions is not part of the workshop. + +### Learning resources + +- [infra-as-code/bicep/orchestration/subPlacementAll](https://github.com/Azure/ALZ-Bicep/tree/main/infra-as-code/bicep/orchestration/subPlacementAll) + +### Solution + +> [!warning] +> SPOILER - You can find pointers to a faster solution in the [solution document](./walkthrough/solution.md) + +## Challenge 6 - Built-In and Custom Policy Assignments + +### Goal + +To ensure consistent governance across the whole landing zone, Azure Policies are deployed across the management groups. As a result of this Challenge you should have a set of Policies and Initiatives assigned to your management group hierarchy. + +### Actions + +- Deploys the default Azure Landing Zone Azure Policy Assignments to the Management Group Hierarchy and also assigns the relevant RBAC for the system-assigned Managed Identities created for policies that require them (e.g DeployIfNotExist & Modify effect policies) + +- Make sure the policy assignment for "Storage Account must not have public access" applied to your management group is not applied to the subscription. + +- Add a custom policy which limits the resource deployment to Azure region "swedencentral" +- Assign this custom policy to the scope of your workload resource group +- Ensure that a policy prevents stroage accounts from using public endpoints, but scoped only to the Resource Group + +### Success criteria + +- You have a set of default policies assigned to your managmeent group hierarchy +- You have a custom policy and a default policy assinment for your workload resource group + +### Learning resources + +- [infra-as-code/bicep/modules/policy/assignments/alzDefaults](https://github.com/Azure/ALZ-Bicep/tree/main/infra-as-code/bicep/modules/policy/assignments/alzDefaults) +- [infra-as-code/bicep/modules/policy/assignments/workloadSpecific](https://github.com/Azure/ALZ-Bicep/tree/main/infra-as-code/bicep/modules/policy/assignments/workloadSpecific) + +### Solution + +> [!warning] +> SPOILER - You can find pointers to a faster solution in the [solution document](./walkthrough/solution.md) + +## Challenge 7 - Workload Deployment to Landing Zone + +### Goal + +Now that the foundation is layed, you are ready to deploy your first workload. At the end of this challenge you should have a peered spoke vnet with an simple web application deployed in the valid deployment region + +### Actions + +- Create and configures a spoke network to deliver the Azure Landing Zone Hub & Spoke architecture based on the network toplogy you chose in Challegen 3 +- Deploy the "Final" Web application (deployment scripts see below). In order to test the policy assignments, try to deploy the application to a region other than the one enforced by your policy +- Create a storage account and link the storage account to the Web application (details should be displayed for any app that is not configured yet) + +### Success criteria + +- Deployment is limited to the valid region +- Storage account creation with public endpoints is prevented +- Application shows the "Congratulations" screen + +### Learning resources + +- [Netowrk Topoligy Considerations](https://github.com/Azure/ALZ-Bicep/wiki/DeploymentFlow#network-topology-deployment) + +### Solution + +> [!warning] +> SPOILER - You can find pointers to a faster solution in the [solution document](./walkthrough/solution.md) + +# Finish + +Congratulations! You finished the MicroHack _Name_. We hope you had the chance to learn about the how to implement a successful... +If you want to give feedback please dont hesitate to open an Issue on the repository or get in touch with one of us directly. + +Thank you for investing the time and see you next time! + +## Contributors + +- Stephan Niklas [GitHub](); [LinkedIn]() +- Philipp Weckerle [GitHub](https://github.com/phwecker); [LinkedIn](https://www.linkedin.com/in/philippweckerle/) diff --git a/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/img/1920x300_EventBanner_MicroHack_General_wText.jpg b/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/img/1920x300_EventBanner_MicroHack_General_wText.jpg new file mode 100644 index 00000000..fd071855 Binary files /dev/null and b/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/img/1920x300_EventBanner_MicroHack_General_wText.jpg differ diff --git a/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/challenge6/custom-policy/allowed-regions/README.md b/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/challenge6/custom-policy/allowed-regions/README.md new file mode 100644 index 00000000..b146d0b4 --- /dev/null +++ b/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/challenge6/custom-policy/allowed-regions/README.md @@ -0,0 +1,86 @@ +# Custom Policy: Allowed Regions + +This folder contains a custom Azure Policy that restricts resource deployments to a specified list of Azure regions. The policy definition and assignment are split so they can be deployed separately or together via the provided script. + +## Files + +| File | Purpose | +| --------------------------- | ------------------------------------------------------------------------------------------------ | +| `policyDefinition.bicep` | Creates (or updates) the custom policy definition at subscription scope (parameter schema only). | +| `policyAssignment.bicep` | Assigns the existing policy definition to a specified resource group. | +| `deploy-allowed-regions.sh` | Convenience script to deploy the definition and then the assignment using the Azure CLI. | + +## Parameters + +### Definition (`policyDefinition.bicep`) + +| Name | Type | Description | +| ---------------------- | ------ | ------------------------------------------------------------- | +| `policyDefinitionName` | string | Name of policy definition (default `custom-allowed-regions`). | +| `displayName` | string | Display name. | +| `policyDescription` | string | Description. | + +### Assignment (`policyAssignment.bicep`) + +| Name | Type | Description | +| ------------------------- | ------ | ------------------------------------------------------------------- | +| `assignmentName` | string | Name of the policy assignment. | +| `displayName` | string | Display name. | +| `description` | string | Description. | +| `policyDefinitionName` | string | Existing policy definition name. | +| `targetResourceGroupName` | string | Resource group to scope the assignment to. | +| `allowedLocations` | array | Same array of locations passed through to the definition parameter. | +| `enforcementMode` | string | `Default` or `DoNotEnforce` (default `Default`). | + +## Manual Deploy (Bicep via Azure CLI) + +Deploy definition (no region values needed at definition time): + +```bash + +az deployment sub create \ + --name allowedRegionsDef \ + --location $LOCATION$ \ + --template-file policyDefinition.bicep \ + --parameters policyDefinitionName=custom-allowed-regions +``` + +Deploy assignment: + +```bash +az deployment sub create \ + --name allowedRegionsAssign \ + --location "LOCATION" \ + --template-file policyAssignment.bicep \ + --parameters assignmentName=custom-allowed-regions-assignment \ + policyDefinitionName=custom-allowed-regions \ + targetResourceGroupName=MyWorkloadRG \ + allowedLocations='["eastus","westeurope"]' +``` + +## Validate + +List the assignment: + +```bash +az policy assignment list --query "[?name=='custom-allowed-regions-assignment']" +``` + +Summarize policy state for the resource group: + +```bash +az policy state summarize --resource-group MyWorkloadRG +``` + +## Clean Up + +```bash +az policy assignment delete --name custom-allowed-regions-assignment --resource-group MyWorkloadRG +az policy definition delete --name custom-allowed-regions +``` + +## Notes + +- The definition is idempotent; redeploying updates it. +- Assignment can be updated by redeploying with modified parameters. +- Use `DoNotEnforce` during rollout/testing to audit before enforcement. diff --git a/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/challenge6/custom-policy/allowed-regions/deploy-allowed-regions.sh b/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/challenge6/custom-policy/allowed-regions/deploy-allowed-regions.sh new file mode 100644 index 00000000..1fc521b2 --- /dev/null +++ b/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/challenge6/custom-policy/allowed-regions/deploy-allowed-regions.sh @@ -0,0 +1,101 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Deploy and assign the custom Allowed Regions policy using Bicep templates. +# This script deploys the policy definition at subscription scope and then +# assigns it to a specified resource group. +# +# Requirements: +# - Azure CLI logged in (az login) +# - Appropriate RBAC: Policy Contributor (definition) + Resource Policy Contributor / Owner on target RG +# - Bicep CLI (bundled in az CLI >= 2.20) +# +# Usage examples: +# ./deploy-allowed-regions.sh -g MyWorkloadRG -r "eastus westeurope" \ +# -d custom-allowed-regions -a custom-allowed-regions-assignment -l eastus +# +# Flags: +# -g Target resource group name (required) +# -r Space-separated list of allowed regions (required) +# -d Policy definition name (default: custom-allowed-regions) +# -a Policy assignment name (default: custom-allowed-regions-assignment) +# -l Deployment location for the sub-level deployments (default: eastus) +# -e Enforcement mode (Default|DoNotEnforce) (default: Default) +# -h Help + +DEF_NAME="custom-allowed-regions" +ASSIGN_NAME="custom-allowed-regions-assignment" +DEPLOY_LOCATION="eastus" +ENFORCEMENT_MODE="Default" +TARGET_RG="" +ALLOWED_REGIONS=() + +while getopts ":g:r:d:a:l:e:h" opt; do + case ${opt} in + g) TARGET_RG="$OPTARG" ;; + r) IFS=' ' read -r -a ALLOWED_REGIONS <<< "$OPTARG" ;; + d) DEF_NAME="$OPTARG" ;; + a) ASSIGN_NAME="$OPTARG" ;; + l) DEPLOY_LOCATION="$OPTARG" ;; + e) ENFORCEMENT_MODE="$OPTARG" ;; + h) + grep '^# ' "$0" | sed 's/^# \{0,1\}//' + exit 0 + ;; + *) echo "Invalid option: -$OPTARG" >&2; exit 1 ;; + esac +done + +if [[ -z "$TARGET_RG" || ${#ALLOWED_REGIONS[@]} -eq 0 ]]; then + echo "ERROR: Resource group (-g) and allowed regions (-r) are required." >&2 + exit 1 +fi + +if [[ "$ENFORCEMENT_MODE" != "Default" && "$ENFORCEMENT_MODE" != "DoNotEnforce" ]]; then + echo "ERROR: enforcement mode must be 'Default' or 'DoNotEnforce'" >&2 + exit 1 +fi + +echo "==> Verifying Azure CLI login..." +az account show >/dev/null 2>&1 || { echo "Please run 'az login' first." >&2; exit 1; } + +echo "==> Checking that resource group '$TARGET_RG' exists..." +if ! az group show -n "$TARGET_RG" >/dev/null 2>&1; then + echo "ERROR: Resource group '$TARGET_RG' not found." >&2 + exit 1 +fi + +SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd) +DEF_FILE="$SCRIPT_DIR/policyDefinition.bicep" +ASSIGN_FILE="$SCRIPT_DIR/policyAssignment.bicep" + +if [[ ! -f "$DEF_FILE" || ! -f "$ASSIGN_FILE" ]]; then + echo "ERROR: Bicep files not found next to script." >&2 + exit 1 +fi + +# Build JSON array string for allowedLocations parameter. +ALLOWED_JSON=$(printf '"%s",' "${ALLOWED_REGIONS[@]}") +ALLOWED_JSON="[${ALLOWED_JSON%,}]" + +STAMP=$(date +%Y%m%d%H%M%S) + +echo "==> Deploying policy definition '$DEF_NAME' (definition does not need allowed locations values)" +az deployment sub create \ + --name "${DEF_NAME}-def-${STAMP}" \ + --location "$DEPLOY_LOCATION" \ + --template-file "$DEF_FILE" \ + --parameters policyDefinitionName="$DEF_NAME" + +echo "==> Deploying policy assignment '$ASSIGN_NAME' to resource group '$TARGET_RG'" +az deployment sub create \ + --name "${ASSIGN_NAME}-assign-${STAMP}" \ + --location "$DEPLOY_LOCATION" \ + --template-file "$ASSIGN_FILE" \ + --parameters assignmentName="$ASSIGN_NAME" policyDefinitionName="$DEF_NAME" \ + targetResourceGroupName="$TARGET_RG" allowedLocations="$ALLOWED_JSON" \ + enforcementMode="$ENFORCEMENT_MODE" + +echo "==> Completed. Verification suggestions:" +echo " az policy assignment list --query \"[?name=='$ASSIGN_NAME']\"" +echo " az policy state summarize --resource-group '$TARGET_RG'" \ No newline at end of file diff --git a/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/challenge6/custom-policy/allowed-regions/policyAssignment.bicep b/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/challenge6/custom-policy/allowed-regions/policyAssignment.bicep new file mode 100644 index 00000000..d202b5f8 --- /dev/null +++ b/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/challenge6/custom-policy/allowed-regions/policyAssignment.bicep @@ -0,0 +1,44 @@ +// Custom Policy Assignment: Allowed Regions +// Deploy at subscription scope. Assigns an existing custom allowed regions policy +// to a specified resource group. +// Parameters: +// - assignmentName (string) +// - displayName (string) +// - description (string) +// - policyDefinitionName (string) (must already exist or be deployed separately) +// - targetResourceGroupName (string) +// - allowedLocations (array) (passed to policy definition parameters) +// - enforcementMode (string) (Default | DoNotEnforce) + +// This file remains subscription scoped and uses a module deployed to the RG scope. +// If you prefer a purely RG-scoped template, create a separate file with targetScope='resourceGroup'. +targetScope = 'subscription' + +param assignmentName string = 'custom-allowed-regions-assignment' +param displayName string = 'Enforce allowed regions' +param assignmentDescription string = 'Ensures only approved regions are used in the target resource group.' +param policyDefinitionName string +param targetResourceGroupName string +param allowedLocations array +@allowed(['Default','DoNotEnforce']) +param enforcementMode string = 'Default' + +resource policyDef 'Microsoft.Authorization/policyDefinitions@2025-03-01' existing = { + name: policyDefinitionName +} + +// Module that performs the assignment at the resource group scope +module rgAssignment './rgPolicyAssignmentModule.bicep' = { + name: '${assignmentName}-module' + scope: resourceGroup(targetResourceGroupName) + params: { + assignmentName: assignmentName + displayName: displayName + assignmentDescription: assignmentDescription + policyDefinitionId: policyDef.id + allowedLocations: allowedLocations + enforcementMode: enforcementMode + } +} + +output policyAssignmentId string = rgAssignment.outputs.policyAssignmentId \ No newline at end of file diff --git a/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/challenge6/custom-policy/allowed-regions/policyDefinition.bicep b/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/challenge6/custom-policy/allowed-regions/policyDefinition.bicep new file mode 100644 index 00000000..2cd1b6dd --- /dev/null +++ b/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/challenge6/custom-policy/allowed-regions/policyDefinition.bicep @@ -0,0 +1,68 @@ +// Custom Policy Definition: Allowed Regions +// Deploy at subscription scope. Defines a custom policy that denies resource deployments +// whose location is not in the provided allowedLocations list. +// Parameters: +// - policyDefinitionName (string) +// - displayName (string) +// - description (string) +// - allowedLocations (array) + +targetScope = 'subscription' + +// Parameters kept simple for broad Bicep version compatibility (decorators removed) +param policyDefinitionName string = 'custom-allowed-regions' +param displayName string = 'Allowed regions (custom)' +param policyDescription string = 'Restricts resource deployment to the specified list of regions.' + +// NOTE: Policy definitions only define parameter schema; values are supplied at assignment time. +resource policyDef 'Microsoft.Authorization/policyDefinitions@2025-03-01' = { + name: policyDefinitionName + properties: { + policyType: 'Custom' + mode: 'All' + displayName: displayName + description: policyDescription + metadata: { + category: 'General' + version: '1.0.0' + } + parameters: { + allowedLocations: { + type: 'Array' + metadata: { + displayName: 'Allowed locations' + description: 'The list of allowed locations for resources.' + } + } + } + // Policy rule embedded as raw JSON to allow Azure Policy expression syntax. + policyRule: policyRule + } +} + +// Raw JSON policy rule (uses Azure Policy expression for parameters). Kept after resource for readability. +var policyRule = json(''' +{ + "if": { + "allOf": [ + { + "field": "type", + "notEquals": "Microsoft.Resources/subscriptions" + }, + { + "field": "location", + "notIn": "[parameters('allowedLocations')]" + }, + { + "field": "location", + "notEquals": "global" + } + ] + }, + "then": { + "effect": "Deny" + } +} +''') + +output policyDefinitionId string = policyDef.id \ No newline at end of file diff --git a/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/challenge6/custom-policy/allowed-regions/rgPolicyAssignmentModule.bicep b/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/challenge6/custom-policy/allowed-regions/rgPolicyAssignmentModule.bicep new file mode 100644 index 00000000..a7570cf1 --- /dev/null +++ b/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/challenge6/custom-policy/allowed-regions/rgPolicyAssignmentModule.bicep @@ -0,0 +1,27 @@ +// Module deployed at resource group scope to create the policy assignment. +targetScope = 'resourceGroup' + +param assignmentName string +param displayName string +param assignmentDescription string +param policyDefinitionId string +param allowedLocations array +@allowed(['Default','DoNotEnforce']) +param enforcementMode string = 'Default' + +resource assignment 'Microsoft.Authorization/policyAssignments@2025-03-01' = { + name: assignmentName + properties: { + displayName: displayName + description: assignmentDescription + policyDefinitionId: policyDefinitionId + enforcementMode: enforcementMode + parameters: { + allowedLocations: { + value: allowedLocations + } + } + } +} + +output policyAssignmentId string = assignment.id \ No newline at end of file diff --git a/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/challenge6/excemption/README.md b/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/challenge6/excemption/README.md new file mode 100644 index 00000000..4ed40909 --- /dev/null +++ b/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/challenge6/excemption/README.md @@ -0,0 +1,116 @@ +# Policy Exemption Automation (Microhack Challenge 6) + +This folder (name kept as `excemption` per challenge materials) contains: + +1. `create-exemption.sh` – Bash automation to discover policy assignments under a given scope (subscription or management group) that match a specified **policy** (by GUID, full ID, or display name) and create a policy exemption for each at a target scope (subscription or resource group). +2. `policyExemption.bicep` – Re‑usable Bicep module to declare a single static policy exemption when the assignment ID is already known. +3. `req.txt` – Original requirement list. + +## Requirements Mapping + +| Requirement (updated) | Implemented In | Notes | +| ---------------------------------------------------- | --------------------------------------------------- | --------------------------------------------------------------------- | +| use bicep or bash | Both (script + module) | Dynamic discovery in Bash; static declaration via Bicep | +| pass in assignment scope (incl. MG) | `--assignment-scope` (script) | Supports subscription or management group scopes | +| pass in policy name (GUID), full ID, or display name | `--policy` (script) | Accepts GUID, full ID, or display name (case-insensitive exact match) | +| legacy full policy id support | `--policy-definition-id` (script) | Backwards compatible alias | +| pass in exemption scope | `--exemption-scope-type` / `--exemption-scope-name` | Builds full resource ID | +| pass in name of scope | `--exemption-scope-name` | Used in exemption naming | +| determine assignment id | Script queries Azure | Filters assignments after retrieval | +| determine exemption scope resource id | Built from type + name | Displays computed ID | +| create exemption for each assignment | Loop in script | Skips if exemption already exists (idempotent) | + +## Bash Script Usage + +```bash +chmod +x create-exemption.sh +./create-exemption.sh \ + --assignment-scope /subscriptions/ \ + --policy \ + --exemption-scope-type resourceGroup \ + --exemption-scope-name \ + --reason "Approved exception - CAB#1234" +``` + +Dry run (no changes): + +```bash +./create-exemption.sh --assignment-scope /providers/Microsoft.Management/managementGroups/ \ + --policy "Storage accounts should disable public network access" \ + --exemption-scope-type subscription \ + --exemption-scope-name \ + --dry-run --verbose +``` + +### Parameters (Script) + +| Flag | Description | Required | +| ------------------------ | --------------------------------------------------- | -------- | +| `--assignment-scope` | Scope to search for policy assignments | Yes | +| `--policy` | Policy GUID, full ID, or display name | Yes | +| `--policy-definition-id` | (Legacy) full policy definition ID | No | +| `--exemption-scope-type` | `subscription` or `resourceGroup` | Yes | +| `--exemption-scope-name` | Subscription GUID (if type=subscription) or RG name | Yes | +| `--exemption-category` | Waiver (default) or Mitigated | No | +| `--reason` | Description / justification | No | +| `--dry-run` | Show actions only | No | +| `--verbose` | Debug logging | No | + +### Behavior Notes + +- Generates deterministic exemption names (`ex--`). +- Skips creation if an exemption with that name already exists at the target scope. +- Supports macOS (`md5`) and Linux (`md5` or falls back to `shasum`). +- Extend `build_exemption_scope_id()` to support management groups or granular resource scopes if required. + +## Bicep Module Usage + +Deploy a single exemption (example targeting a resource group): + +```bicep +// In a parent Bicep file +targetScope = 'subscription' + +resource rg 'Microsoft.Resources/resourceGroups@2022-09-01' existing = { + name: 'my-workload-rg' +} + +module exemption './policyExemption.bicep' = { + name: 'exemptionModule' + scope: rg + params: { + exemptionName: 'ex-my-workload-rg-001' + displayName: 'Exemption for Policy XYZ' + policyAssignmentId: '/subscriptions//providers/Microsoft.Authorization/policyAssignments/' + exemptionCategory: 'Waiver' + description: 'Approved deviation CAB#1234' + } +} +``` + +Deploy with Azure CLI: + +```bash +az deployment sub create \ + --name ExemptionDeploy \ + --location \ + --template-file main.bicep +``` + +## Extending + +- Already supports management group assignment scopes (e.g., `/providers/Microsoft.Management/managementGroups/`). +- Add selective exemption for policy set references via `policyDefinitionReferenceIds` parameter in the module. +- Introduce expiry handling by adding a `--expires-on` flag to the script (already supported in Bicep via parameter) and mapping through to the CLI with `--expires-on`. + +## Troubleshooting + +| Issue | Cause | Fix | +| ------------------------ | ------------------------ | ----------------------------------------------------------- | +| No assignments found | Wrong scope or policy ID | Verify `az policy assignment list --scope ` manually | +| Auth error | Not logged in | Run `az login` | +| Exemption already exists | Name collision | Remove existing or adjust naming logic | + +--- + +Generated as part of Microhack Challenge 6 automation deliverable. diff --git a/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/challenge6/excemption/create-excemption.sh b/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/challenge6/excemption/create-excemption.sh new file mode 100755 index 00000000..1ef417ec --- /dev/null +++ b/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/challenge6/excemption/create-excemption.sh @@ -0,0 +1,262 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Purpose: Create policy exemptions for all policy assignments at a given scope +# that reference a specified policy definition (by GUID, full ID, or display name). +# Exemptions are created at a provided exemption scope. +# +# Updated Requirements (req.txt): +# - pass in assignment scope (now supports management group scopes) +# - pass in policy name (GUID) OR the policy display name +# - pass in exemption scope (e.g., resource group) & its name +# - determine assignment id(s) +# - determine exemption scope resource id +# - create exemption for each matching assignment +# +# Backwards compatibility: --policy-definition-id retained but superseded by --policy if both supplied. +# +# Notes: +# 1. Supports assignment scopes at subscription or management group (e.g. /providers/Microsoft.Management/managementGroups/). +# 2. Exemption target scopes currently: subscription, resourceGroup (extendable). +# 3. Policy display name matching is case-insensitive exact match. +# 4. Basic caching avoids redundant policy definition lookups without requiring associative arrays (macOS default bash 3.x). +# 5. "excemption" spelling kept to align with provided folder name. + +usage() { + cat < \\ + --policy \\ + [--policy-definition-id ] \\ + --exemption-scope-type \\ + --exemption-scope-name \\ + [--exemption-category ] \\ + [--reason ] \\ + [--dry-run] \\ + [--verbose] + +Examples: + # Exempt a resource group from a specific policy definition (by GUID) enforced at subscription scope + $0 \ + --assignment-scope /subscriptions/00000000-0000-0000-0000-000000000000 \ + --policy a1b2c3d4-1111-2222-3333-444455556666 \ + --exemption-scope-type resourceGroup \ + --exemption-scope-name my-workload-rg + + # Exempt using display name (quotes required if spaces) + $0 \ + --assignment-scope /providers/Microsoft.Management/managementGroups/myRootMG \ + --policy "Storage accounts should disable public network access" \ + --exemption-scope-type subscription \ + --exemption-scope-name 00000000-0000-0000-0000-000000000000 + + # Dry run to see which assignments would get exemptions (full ID example) + $0 --assignment-scope /subscriptions/000... \ + --policy /providers/Microsoft.Authorization/policyDefinitions/a1b2c3d4 \ + --exemption-scope-type subscription \ + --exemption-scope-name 00000000-0000-0000-0000-000000000000 \ + --dry-run --verbose + +EOF + exit 1 +} + +ASSIGNMENT_SCOPE="" +POLICY_INPUT="" +LEGACY_POLICY_DEFINITION_ID="" +EXEMPTION_SCOPE_TYPE="" +EXEMPTION_SCOPE_NAME="" +EXEMPTION_CATEGORY="Waiver" +REASON="Policy exemption generated via automation script." +DRY_RUN=false +VERBOSE=false + +while [[ $# -gt 0 ]]; do + case "$1" in + --assignment-scope) ASSIGNMENT_SCOPE="$2"; shift 2;; + --policy) POLICY_INPUT="$2"; shift 2;; + --policy-definition-id) LEGACY_POLICY_DEFINITION_ID="$2"; shift 2;; + --exemption-scope-type) EXEMPTION_SCOPE_TYPE="$2"; shift 2;; + --exemption-scope-name) EXEMPTION_SCOPE_NAME="$2"; shift 2;; + --exemption-category) EXEMPTION_CATEGORY="$2"; shift 2;; + --reason) REASON="$2"; shift 2;; + --dry-run) DRY_RUN=true; shift 1;; + --verbose) VERBOSE=true; shift 1;; + -h|--help) usage;; + *) echo "Unknown argument: $1"; usage;; + esac +done + +if [[ -z "$POLICY_INPUT" && -n "$LEGACY_POLICY_DEFINITION_ID" ]]; then + POLICY_INPUT="$LEGACY_POLICY_DEFINITION_ID" +fi + +[[ -z "$ASSIGNMENT_SCOPE" || -z "$POLICY_INPUT" || -z "$EXEMPTION_SCOPE_TYPE" || -z "$EXEMPTION_SCOPE_NAME" ]] && usage + +log() { echo "[INFO] $*"; } +vlog() { if $VERBOSE; then echo "[DEBUG] $*"; fi; } +warn() { echo "[WARN] $*" >&2; } +err() { echo "[ERROR] $*" >&2; exit 1; } + +require_tool() { command -v "$1" >/dev/null 2>&1 || err "Required tool '$1' not found in PATH"; } +require_tool az + +if ! az account show >/dev/null 2>&1; then + err "Not logged in to Azure CLI. Run 'az login' first." +fi + +# Build the exemption scope resource ID +build_exemption_scope_id() { + case "$EXEMPTION_SCOPE_TYPE" in + subscription) + # Name must be subscription GUID + echo "/subscriptions/${EXEMPTION_SCOPE_NAME}" ;; + resourceGroup) + # Derive current subscription from assignment scope if possible + # If assignment scope is at subscription or RG under the same subscription + local subId + if [[ "$ASSIGNMENT_SCOPE" =~ ^/subscriptions/([^/]+) ]]; then + subId="${BASH_REMATCH[1]}" + else + # fallback: use current subscription + subId=$(az account show --query id -o tsv) + fi + echo "/subscriptions/${subId}/resourceGroups/${EXEMPTION_SCOPE_NAME}" ;; + *) + err "Unsupported --exemption-scope-type '$EXEMPTION_SCOPE_TYPE' (supported: subscription, resourceGroup)" ;; + esac +} + +EXEMPTION_SCOPE_ID=$(build_exemption_scope_id) +log "Exemption scope resource ID: ${EXEMPTION_SCOPE_ID}" + +log "Querying policy assignments at scope: $ASSIGNMENT_SCOPE" +ASSIGNMENTS_RAW=$(az policy assignment list --scope "$ASSIGNMENT_SCOPE" -o json) + +if [[ -z "$ASSIGNMENTS_RAW" || "$ASSIGNMENTS_RAW" == "[]" ]]; then + warn "No policy assignments found at scope: $ASSIGNMENT_SCOPE" + exit 0 +fi + +# Determine match type for POLICY_INPUT +POLICY_INPUT_LOWER=$(echo "$POLICY_INPUT" | tr '[:upper:]' '[:lower:]') +MATCHED_ASSIGNMENTS="" + +# Simple pattern detection +is_guid=false +if [[ "$POLICY_INPUT" =~ ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$ ]]; then + is_guid=true +fi + +is_full_id=false +if [[ "$POLICY_INPUT_LOWER" == *"/providers/microsoft.authorization/policydefinitions/"* || "$POLICY_INPUT_LOWER" == *"/providers/microsoft.authorization/policysetdefinitions/"* ]]; then + is_full_id=true +fi + +# Cache file for policy definition display names (id|lower(displayName)) +PD_CACHE=$(mktemp) +trap 'rm -f "$PD_CACHE"' EXIT + +get_cached_display_name_lower() { + local defId="$1" + local line + line=$(grep "^${defId}|" "$PD_CACHE" || true) + if [[ -n "$line" ]]; then + echo "${line#${defId}|}" + return 0 + fi + # Determine if definition or set definition + local lowerId=$(echo "$defId" | tr '[:upper:]' '[:lower:]') + local showCmd + if [[ "$lowerId" == *"/policysetdefinitions/"* ]]; then + showCmd=(az policy set-definition show --id "$defId" --query displayName -o tsv) + else + showCmd=(az policy definition show --id "$defId" --query displayName -o tsv) + fi + local dn + if dn=$("${showCmd[@]}" 2>/dev/null); then + local dnLower=$(echo "$dn" | tr '[:upper:]' '[:lower:]') + echo "${defId}|${dnLower}" >> "$PD_CACHE" + echo "$dnLower" + else + echo "" >> "$PD_CACHE" + echo "" + fi +} + +count_total=$(echo "$ASSIGNMENTS_RAW" | az dataplane transform --only-show-errors --output tsv --query 'length(@)' 2>/dev/null || echo 0) +vlog "Total assignments retrieved: $count_total" + +# Extract id, name, policyDefinitionId using az's JMESPath (avoid jq dependency) +ASSIGNMENTS_TSV=$(echo "$ASSIGNMENTS_RAW" | az dataplane transform --only-show-errors -o tsv --query "[].[id,name,policyDefinitionId]") || true + +while IFS=$'\t' read -r aId aName aPolicyDefId; do + [[ -z "$aId" ]] && continue + aPolicyDefIdLower=$(echo "$aPolicyDefId" | tr '[:upper:]' '[:lower:]') + match=false + if $is_full_id; then + if [[ "$aPolicyDefIdLower" == "$POLICY_INPUT_LOWER" ]]; then match=true; fi + elif $is_guid; then + # Compare trailing GUID segment + trailingGuid=$(echo "$aPolicyDefIdLower" | sed 's:.*/::') + if [[ "$trailingGuid" == "$POLICY_INPUT_LOWER" ]]; then match=true; fi + else + # Display name match (case-insensitive) + dnLower=$(get_cached_display_name_lower "$aPolicyDefId") + if [[ "$dnLower" == "$POLICY_INPUT_LOWER" ]]; then match=true; fi + fi + if $match; then + MATCHED_ASSIGNMENTS+="$aId\t$aName\n" + fi +done <<< "$ASSIGNMENTS_TSV" + +if [[ -z "$MATCHED_ASSIGNMENTS" ]]; then + warn "No policy assignments matched policy filter: $POLICY_INPUT" + exit 0 +fi + +ASSIGNMENTS="$MATCHED_ASSIGNMENTS" +log "Found $(echo "$ASSIGNMENTS" | grep -c '.') matching assignment(s)." + +create_exemption() { + local assignmentId="$1" assignmentName="$2" + # Stable short name based on assignmentId hash + local hashPart + if command -v md5 >/dev/null 2>&1; then + hashPart=$(echo -n "$assignmentId" | md5 | cut -c1-8) + else + hashPart=$(echo -n "$assignmentId" | shasum | cut -c1-8) + fi + local exemptionName="ex-${EXEMPTION_SCOPE_NAME}-${hashPart}" + local displayName="Exemption for ${assignmentName} on ${EXEMPTION_SCOPE_NAME}" + + # Check if an exemption with same name already exists + if az policy exemption show --name "$exemptionName" --scope "$EXEMPTION_SCOPE_ID" >/dev/null 2>&1; then + log "Exemption already exists: $exemptionName (scope: $EXEMPTION_SCOPE_ID) - skipping" + return 0 + fi + + if $DRY_RUN; then + log "[DRY-RUN] Would create exemption '$exemptionName' for assignment '$assignmentName'" + return 0 + fi + + log "Creating exemption '$exemptionName' for assignment '$assignmentName'" + az policy exemption create \ + --name "$exemptionName" \ + --scope "$EXEMPTION_SCOPE_ID" \ + --policy-assignment "$assignmentId" \ + --exemption-category "$EXEMPTION_CATEGORY" \ + --display-name "$displayName" \ + --description "$REASON" \ + --only-show-errors 1>/dev/null + + log "Created exemption: $exemptionName" +} + +while IFS=$'\t' read -r assignmentId assignmentName; do + vlog "Processing assignment: $assignmentName ($assignmentId)" + create_exemption "$assignmentId" "$assignmentName" +done <<< "$ASSIGNMENTS" + +log "Completed processing exemptions." diff --git a/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/challenge6/excemption/policyExcemption.bicep b/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/challenge6/excemption/policyExcemption.bicep new file mode 100644 index 00000000..27c8315e --- /dev/null +++ b/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/challenge6/excemption/policyExcemption.bicep @@ -0,0 +1,46 @@ +// Bicep module to create a single policy exemption at the module deployment scope. +// Suitable when the policy assignment ID is already known and a static declaration is desired. +// For dynamic discovery of assignments, prefer the accompanying bash script. + +@description('Name of the policy exemption resource (must be unique within the scope).') +param exemptionName string + +@description('Display name for the exemption.') +param displayName string + +@description('Policy Assignment (full resource ID) this exemption applies to.') +param policyAssignmentId string + +@description('Exemption category: Waiver or Mitigated.') +@allowed(['Waiver', 'Mitigated']) +param exemptionCategory string = 'Waiver' + +@description('Optional ISO8601 UTC date/time when the exemption expires. Leave empty for no expiry.') +param expiresOn string = '' + +@description('Optional description / justification.') +param exemptionDescription string = 'Policy exemption created via policyExemption.bicep module.' + +@description('Optional metadata object (e.g., owner, ticketId).') +param metadata object = {} + +// Optional: list of policy definition reference IDs if applying exemption only to part of a policy set +@description('Optional list of policy definition reference IDs (for policy set assignments). Leave empty to exempt entire assignment.') +param policyDefinitionReferenceIds array = [] + +resource exemption 'Microsoft.Authorization/policyExemptions@2022-07-01-preview' = { + name: exemptionName + properties: { + displayName: displayName + description: exemptionDescription + exemptionCategory: exemptionCategory + policyAssignmentId: policyAssignmentId + metadata: metadata + // Only include expiresOn if provided (non-empty string) + ...(length(expiresOn) == 0 ? {} : { expiresOn: expiresOn }) + ...(length(policyDefinitionReferenceIds) == 0 ? {} : { policyDefinitionReferenceIds: policyDefinitionReferenceIds }) + } +} + +@description('Exemption name output for reference.') +output name string = exemption.name diff --git a/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/challenge6/storage-policy/README.md b/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/challenge6/storage-policy/README.md new file mode 100644 index 00000000..34744e46 --- /dev/null +++ b/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/challenge6/storage-policy/README.md @@ -0,0 +1,66 @@ +# Storage Policy Assignment: Disallow Public Blob Access + +Creates a policy assignment at a target resource group enforcing that storage accounts do not allow public blob access. + +## Files + +| File | Purpose | +| --------------------------------------- | ----------------------------------------------------------------------------- | +| `storageNoPublicAccessAssignment.bicep` | Subscription-scope template assigning built-in policy to RG (module pattern). | +| `storagePolicyRgModule.bicep` | RG-scope module that actually creates the assignment. | +| `deploy-storage-no-public.sh` | Helper script resolving built-in policy and deploying assignment. | + +## Parameters (subscription template) + +| Name | Description | +| ------------------------- | -------------------------------------------------------------------- | +| `assignmentName` | Policy assignment name. | +| `displayName` | Friendly display name. | +| `assignmentDescription` | Description. | +| `targetResourceGroupName` | Target RG scope. | +| `policyDefinitionName` | Built-in policy definition name (GUID). Optional if script resolves. | +| `policyDefinitionId` | Full resource ID (alternative to name). | +| `enforcementMode` | `Default` or `DoNotEnforce`. | + +## Deployment (Script) + +```bash +./deploy-storage-no-public.sh -g MyRG +``` + +Optional flags: + +- `-a` assignment name +- `-m` enforcement mode (`Default|DoNotEnforce`) +- `-n` supply built-in definition name GUID directly +- `-i` supply full policy definition resource ID +- `-l` location for subscription deployment (default eastus) + +## Manual Deployment + +Resolve built-in definition name GUID (example): + +```bash +POLICY_NAME=$(az policy definition list --query "[?displayName=='Storage accounts should disallow public blob access'].name | [0]" -o tsv) +az deployment sub create \ + --name storageNoPublicAssign \ + --location eastus \ + --template-file storageNoPublicAccessAssignment.bicep \ + --parameters targetResourceGroupName=MyRG policyDefinitionName=$POLICY_NAME +``` + +## Verification + +```bash +az policy assignment list --resource-group MyRG --query "[?contains(displayName,'Deny storage public blob access')]" +``` + +## Cleanup + +```bash +az policy assignment delete --name enforce-storage-no-public-blob --resource-group MyRG +``` + +## Notes + +If Microsoft updates the built-in policy display name, use `-n` or `-i` to override. diff --git a/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/challenge6/storage-policy/deploy-storage-no-public.sh b/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/challenge6/storage-policy/deploy-storage-no-public.sh new file mode 100644 index 00000000..f65d5b5a --- /dev/null +++ b/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/challenge6/storage-policy/deploy-storage-no-public.sh @@ -0,0 +1,90 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Deploy a policy assignment that enforces no public blob access for storage accounts in a resource group. +# The script discovers the built-in policy definition name (GUID) using its display name unless one is provided. +# +# Built-in policy display name commonly used: "Storage accounts should disallow public blob access" +# If Microsoft renames the policy, override with -i or -n . +# +# Usage: +# ./deploy-storage-no-public.sh -g MyRG +# ./deploy-storage-no-public.sh -g MyRG -a customAssignName -m DoNotEnforce +# ./deploy-storage-no-public.sh -g MyRG -n +# ./deploy-storage-no-public.sh -g MyRG -i /providers/Microsoft.Authorization/policyDefinitions/ +# +# Requirements: az CLI logged in & correct subscription selected. + +ASSIGN_NAME="enforce-storage-no-public-blob" +DISPLAY_NAME="Deny storage public blob access" +DESCRIPTION="Ensures storage accounts in this resource group do not permit public blob access." +RG_NAME="" +LOCATION="eastus" # deployment location (subscription deployment requirement) +ENFORCEMENT_MODE="Default" +POLICY_DEF_NAME="" # GUID (name) of the policy definition +POLICY_DEF_ID="" # Full resource ID +POLICY_DISPLAY_NAME="Storage accounts should disallow public blob access" + +while getopts ":g:a:l:m:n:i:d:h" opt; do + case $opt in + g) RG_NAME="$OPTARG" ;; + a) ASSIGN_NAME="$OPTARG" ;; + l) LOCATION="$OPTARG" ;; + m) ENFORCEMENT_MODE="$OPTARG" ;; + n) POLICY_DEF_NAME="$OPTARG" ;; + i) POLICY_DEF_ID="$OPTARG" ;; + d) DISPLAY_NAME="$OPTARG" ;; + h) + grep '^# ' "$0" | sed 's/^# \{0,1\}//' + exit 0 + ;; + *) echo "Invalid option: -$OPTARG" >&2; exit 1 ;; + esac +done + +if [[ -z "$RG_NAME" ]]; then + echo "ERROR: Resource group (-g) is required." >&2 + exit 1 +fi + +if [[ "$ENFORCEMENT_MODE" != "Default" && "$ENFORCEMENT_MODE" != "DoNotEnforce" ]]; then + echo "ERROR: Enforcement mode must be Default or DoNotEnforce" >&2 + exit 1 +fi + +echo "==> Ensuring az login context" +az account show >/dev/null 2>&1 || { echo "Run 'az login' first." >&2; exit 1; } + +echo "==> Checking resource group '$RG_NAME' exists" +az group show -n "$RG_NAME" >/dev/null 2>&1 || { echo "Resource group '$RG_NAME' not found" >&2; exit 1; } + +if [[ -z "$POLICY_DEF_ID" && -z "$POLICY_DEF_NAME" ]]; then + echo "==> Resolving built-in policy definition name by displayName: $POLICY_DISPLAY_NAME" + POLICY_DEF_NAME=$(az policy definition list --query "[?displayName=='$POLICY_DISPLAY_NAME'].name | [0]" -o tsv) + if [[ -z "$POLICY_DEF_NAME" ]]; then + echo "ERROR: Could not resolve built-in policy by display name. Use -n or -i ." >&2 + exit 1 + fi +fi + +if [[ -z "$POLICY_DEF_ID" ]]; then + POLICY_DEF_ID="/providers/Microsoft.Authorization/policyDefinitions/$POLICY_DEF_NAME" +fi + +STAMP=$(date +%Y%m%d%H%M%S) +TEMPLATE_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd) +TEMPLATE_FILE="$TEMPLATE_DIR/storageNoPublicAccessAssignment.bicep" + +echo "==> Deploying policy assignment $ASSIGN_NAME to RG $RG_NAME using definition $POLICY_DEF_ID" +az deployment sub create \ + --name "${ASSIGN_NAME}-${STAMP}" \ + --location "$LOCATION" \ + --template-file "$TEMPLATE_FILE" \ + --parameters assignmentName="$ASSIGN_NAME" \ + displayName="$DISPLAY_NAME" \ + assignmentDescription="$DESCRIPTION" \ + targetResourceGroupName="$RG_NAME" \ + policyDefinitionId="$POLICY_DEF_ID" \ + enforcementMode="$ENFORCEMENT_MODE" + +echo "==> Done. Verify with: az policy assignment list --resource-group $RG_NAME --query \"[?name=='$ASSIGN_NAME']\"" diff --git a/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/challenge6/storage-policy/storageNoPublicAccessAssignment.bicep b/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/challenge6/storage-policy/storageNoPublicAccessAssignment.bicep new file mode 100644 index 00000000..1f4519d8 --- /dev/null +++ b/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/challenge6/storage-policy/storageNoPublicAccessAssignment.bicep @@ -0,0 +1,52 @@ +// Subscription-scope template that assigns a built-in policy denying public blob access on storage accounts +// to a specified resource group. Uses a module for RG scope assignment. +// +// The script provided resolves the built-in policy definition name dynamically by displayName to avoid +// hard-coding GUIDs. You can also supply policyDefinitionName directly. + +targetScope = 'subscription' + +@description('Name of the policy assignment.') +param assignmentName string = 'enforce-storage-no-public-blob' + +@description('Display name for the policy assignment.') +param displayName string = 'Deny storage public network access' + +@description('Description for the policy assignment.') +param assignmentDescription string = 'Ensures storage accounts in this resource group do not permit public blob access.' + +@description('Target resource group name for the policy assignment scope.') +param targetResourceGroupName string + +@description('Name (GUID) of the built-in policy definition that disallows public blob access. If empty, provide via script.') +param policyDefinitionName string = '' + +@description('Enforcement mode: Default (enforced) or DoNotEnforce.') +@allowed([ + 'Default' + 'DoNotEnforce' +]) +param enforcementMode string = 'Default' + +// Optionally allow passing the full policyDefinitionId instead of name (takes precedence if provided) +@description('Optional full resource ID of the policy definition. If provided, overrides policyDefinitionName.') +param policyDefinitionId string = '' + +// Determine effective policy definition id +var effectivePolicyDefinitionId = empty(policyDefinitionId) + ? subscriptionResourceId('Microsoft.Authorization/policyDefinitions', policyDefinitionName) + : policyDefinitionId + +module rgAssignment './storagePolicyRgModule.bicep' = { + name: '${assignmentName}-module' + scope: resourceGroup(targetResourceGroupName) + params: { + assignmentName: assignmentName + displayName: displayName + assignmentDescription: assignmentDescription + policyDefinitionId: effectivePolicyDefinitionId + enforcementMode: enforcementMode + } +} + +output policyAssignmentId string = rgAssignment.outputs.policyAssignmentId diff --git a/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/challenge6/storage-policy/storagePolicyRgModule.bicep b/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/challenge6/storage-policy/storagePolicyRgModule.bicep new file mode 100644 index 00000000..04adb399 --- /dev/null +++ b/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/challenge6/storage-policy/storagePolicyRgModule.bicep @@ -0,0 +1,21 @@ +// Resource-group scope module that creates the policy assignment (no parameters required by policy) +targetScope = 'resourceGroup' + +param assignmentName string +param displayName string +param assignmentDescription string +param policyDefinitionId string +@allowed(['Default', 'DoNotEnforce']) +param enforcementMode string = 'Default' + +resource assignment 'Microsoft.Authorization/policyAssignments@2025-03-01' = { + name: assignmentName + properties: { + displayName: displayName + description: assignmentDescription + policyDefinitionId: policyDefinitionId + enforcementMode: enforcementMode + } +} + +output policyAssignmentId string = assignment.id diff --git a/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/challenge7/README.md b/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/challenge7/README.md new file mode 100644 index 00000000..0a7efdf6 --- /dev/null +++ b/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/challenge7/README.md @@ -0,0 +1,67 @@ +# Challenge 7: Storage Account Deployment + +Implements the requirement in `req.txt`: + +> Create Bicep scripts to deploy an Azure Storage Account with parameters for name, region, and allowing/denying public access. + +## Files + +| File | Purpose | +|------|---------| +| `storageAccount.bicep` | Resource group scope template deploying StorageV2 account. | +| `storageAccount.parameters.json` | Example parameter file. | +| `deploy-storage.sh` | Helper script for ad-hoc deployment. | +| `req.txt` | Original requirement. | + +## Parameters + +| Name | Type | Default | Description | +|------|------|---------|-------------| +| `storageAccountName` | string | (none) | Globally unique name (3-24 lowercase alphanumeric). | +| `location` | string | RG location | Region. | +| `allowBlobPublicAccess` | bool | false | Enables/disables anonymous blob access. | +| `skuName` | string | Standard_LRS | Replication SKU. | +| `tags` | object | {} | Optional tags. | + +## Deploy (Direct) + +```bash +az deployment group create \ + --resource-group MyRG \ + --template-file storageAccount.bicep \ + --parameters storageAccountName=mystorageacct001 allowBlobPublicAccess=false +``` + +## Deploy (Parameter File) + +Edit `storageAccount.parameters.json` then: + +```bash +az deployment group create \ + --resource-group MyRG \ + --template-file storageAccount.bicep \ + --parameters @storageAccount.parameters.json +``` + +## Deploy (Script) + +```bash +./deploy-storage.sh -g MyRG -n mystorageacct001 -l westeurope -p false -s Standard_LRS -t env=dev;owner=me +``` + +## Validate + +```bash +az storage account show -n mystorageacct001 -g MyRG --query "allowBlobPublicAccess" +``` + +## Cleanup + +```bash +az storage account delete -n mystorageacct001 -g MyRG --yes +``` + +## Notes + +* `allowBlobPublicAccess=false` is recommended baseline. +* Adjust network rules / private endpoints as needed for production. diff --git a/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/challenge7/deploy-storage.sh b/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/challenge7/deploy-storage.sh new file mode 100644 index 00000000..61a7bf36 --- /dev/null +++ b/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/challenge7/deploy-storage.sh @@ -0,0 +1,79 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Deploy storage account using storageAccount.bicep +# Params: +# -g (resource group) REQUIRED +# -n storage account name (override) (optional) +# -l location (optional) +# -p allow public blob access true|false (default false) +# -s sku (default Standard_LRS) +# -t extra tags (key=value;key2=value2) +# -f parameter file (alternative to individual flags) +# +# Examples: +# ./deploy-storage.sh -g MyRG -n mystorageacct001 -l westeurope -p false -s Standard_LRS -t env=dev;owner=you +# ./deploy-storage.sh -g MyRG -f storageAccount.parameters.json + +RG="" +NAME="" +LOCATION="" +PUBLIC="false" +SKU="Standard_LRS" +TAGS="" +PARAM_FILE="" + +while getopts ":g:n:l:p:s:t:f:h" opt; do + case $opt in + g) RG="$OPTARG" ;; + n) NAME="$OPTARG" ;; + l) LOCATION="$OPTARG" ;; + p) PUBLIC="$OPTARG" ;; + s) SKU="$OPTARG" ;; + t) TAGS="$OPTARG" ;; + f) PARAM_FILE="$OPTARG" ;; + h) + grep '^# ' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;; + *) echo "Invalid option -$OPTARG" >&2; exit 1 ;; + esac +done + +[[ -z "$RG" ]] && { echo "-g resource group required" >&2; exit 1; } + +az account show >/dev/null 2>&1 || { echo "Run az login first" >&2; exit 1; } +az group show -n "$RG" >/dev/null 2>&1 || { echo "Resource group $RG not found" >&2; exit 1; } + +SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd) +TEMPLATE="$SCRIPT_DIR/storageAccount.bicep" +DEPLOY_NAME="storageAcct$(date +%Y%m%d%H%M%S)" + +CLI_ARGS=(--name "$DEPLOY_NAME" --resource-group "$RG" --template-file "$TEMPLATE") + +if [[ -n "$PARAM_FILE" ]]; then + CLI_ARGS+=(--parameters "$PARAM_FILE") +else + [[ -n "$NAME" ]] && CLI_ARGS+=(--parameters storageAccountName="$NAME") + [[ -n "$LOCATION" ]] && CLI_ARGS+=(--parameters location="$LOCATION") + CLI_ARGS+=(--parameters allowBlobPublicAccess=$PUBLIC) + CLI_ARGS+=(--parameters skuName="$SKU") + if [[ -n "$TAGS" ]]; then + # Convert key=value;key2=value2 to JSON object string + IFS=';' read -r -a PAIRS <<< "$TAGS" + TAG_JSON="{" + FIRST=1 + for kv in "${PAIRS[@]}"; do + k="${kv%%=*}"; v="${kv#*=}" + [[ $FIRST -eq 0 ]] && TAG_JSON+=" ," + TAG_JSON+=" \"$k\": \"$v\"" + FIRST=0 + done + TAG_JSON+=" }" + CLI_ARGS+=(--parameters tags="$TAG_JSON") + fi +fi + +echo "==> Deploying storage account (deployment name: $DEPLOY_NAME)" +az deployment group create "${CLI_ARGS[@]}" + +echo "==> Done. Show outputs:" +echo " az deployment group show -g $RG -n $DEPLOY_NAME --query properties.outputs" \ No newline at end of file diff --git a/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/challenge7/req.txt b/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/challenge7/req.txt new file mode 100644 index 00000000..e22f00cf --- /dev/null +++ b/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/challenge7/req.txt @@ -0,0 +1,3 @@ +- create bicep scripts to implement the following resource deplyoments + +- azure storage account with parameter for storage account name, region and to allow/deny public access to the service diff --git a/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/challenge7/storageAccount.bicep b/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/challenge7/storageAccount.bicep new file mode 100644 index 00000000..53fbd882 --- /dev/null +++ b/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/challenge7/storageAccount.bicep @@ -0,0 +1,71 @@ +// Storage Account deployment (resource group scope) +// Implements requirements from req.txt: +// - Parameters: storage account name, region, allow/deny public blob access +// - Deploys a StorageV2 account with secure defaults + +targetScope = 'resourceGroup' + +@description('Globally unique storage account name (3-24 lowercase alphanumeric).') +@minLength(3) +@maxLength(24) +param storageAccountName string + +@description('Azure region for the storage account. Defaults to the resource group location.') +param location string = resourceGroup().location + +@description('Allow public network access to the storage account (controls publicNetworkAccess and anonymous blob access).') +param allowPublicAccess bool = false + +// Re-use for allowBlobPublicAccess property +var allowBlobPublicAccess = allowPublicAccess +// Value to use in the resource: set properties.publicNetworkAccess to this variable +var publicNetworkAccessSetting = allowPublicAccess ? 'Enabled' : 'Disabled' + +@description('Replication SKU for the storage account.') +@allowed([ + 'Standard_LRS' + 'Standard_GRS' + 'Standard_ZRS' + 'Standard_RAGRS' + 'Standard_GZRS' + 'Standard_RAGZRS' + 'Premium_LRS' +]) +param skuName string = 'Standard_LRS' + +@description('Optional tags to apply to the storage account.') +param tags object = {} + +// Basic validation / normalization note (Bicep cannot enforce regex here) +// Ensure provided name already meets naming rules. + +resource storageAcct 'Microsoft.Storage/storageAccounts@2023-01-01' = { + name: storageAccountName + location: location + sku: { + name: skuName + } + kind: 'StorageV2' + tags: tags + properties: { + allowBlobPublicAccess: allowBlobPublicAccess + minimumTlsVersion: 'TLS1_2' + supportsHttpsTrafficOnly: true + encryption: { + services: { + blob: { enabled: true } + file: { enabled: true } + } + keySource: 'Microsoft.Storage' + } + publicNetworkAccess: publicNetworkAccessSetting + networkAcls: { + bypass: 'AzureServices' + defaultAction: 'Allow' + } + } +} + +output storageAccountId string = storageAcct.id +output primaryEndpoints object = storageAcct.properties.primaryEndpoints +output allowBlobPublicAccessEffective bool = storageAcct.properties.allowBlobPublicAccess diff --git a/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/images/challenge01/custom-role-result.jpg b/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/images/challenge01/custom-role-result.jpg new file mode 100644 index 00000000..0bc125f8 Binary files /dev/null and b/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/images/challenge01/custom-role-result.jpg differ diff --git a/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/images/challenge01/mg-group-result.jpg b/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/images/challenge01/mg-group-result.jpg new file mode 100644 index 00000000..37fdd598 Binary files /dev/null and b/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/images/challenge01/mg-group-result.jpg differ diff --git a/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/images/challenge01/policy-result.jpg b/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/images/challenge01/policy-result.jpg new file mode 100644 index 00000000..48990cb4 Binary files /dev/null and b/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/images/challenge01/policy-result.jpg differ diff --git a/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/images/challenge02/logging-result.jpg b/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/images/challenge02/logging-result.jpg new file mode 100644 index 00000000..86be9fc1 Binary files /dev/null and b/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/images/challenge02/logging-result.jpg differ diff --git a/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/images/challenge03/hubNetworking.jpg b/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/images/challenge03/hubNetworking.jpg new file mode 100644 index 00000000..e0df3978 Binary files /dev/null and b/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/images/challenge03/hubNetworking.jpg differ diff --git a/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/images/challenge03/vwanNetworking.jpg b/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/images/challenge03/vwanNetworking.jpg new file mode 100644 index 00000000..793c0fe0 Binary files /dev/null and b/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/images/challenge03/vwanNetworking.jpg differ diff --git a/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/images/challenge04/IAM.jpg b/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/images/challenge04/IAM.jpg new file mode 100644 index 00000000..52deab20 Binary files /dev/null and b/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/images/challenge04/IAM.jpg differ diff --git a/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/solution.md b/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/solution.md new file mode 100644 index 00000000..ccf45700 --- /dev/null +++ b/03-Azure/01-03-Infrastructure/11_CAF_Landing_Zone_WiP/walkthrough/solution.md @@ -0,0 +1,381 @@ +# GENERIC + +```bash +az login +ConnectivitySubscriptionId="ccba9824-4a78-4aae-be58-2a597800d986" +az account set --subscription $ConnectivitySubscriptionId + +TopLevelMGPrefix="mhpgw" +``` + +> [!IMPORTANT] +> During the execution of the various chellenges take special care of setting the parameter files correctly. Most importantly make sure you scan the parameters for location and company prefix settings (also in the parameter values. Wherever you see _alz_ you should use the prefix assigned to you) + +> [!TIP] +> In the following sections, the _PARAMETERS_ env variable will point to the parameter files for the respective modules. We would strongly suggest you create a copy of one of the ones in the accelerator (e.g. the _.all._) and rename it (e.g. to _.solution._) before editing it. To prevent you from accidentally deploying with defaults, we are always referenceing a _*.solution.*_ file in the code samples. + +# Challenge 1 - Management Groups + +## Solution + +```bash +dateYMD=$(date +%Y%m%dT%H%M%S%NZ) +NAME="alz-MGDeployment-${dateYMD}" +LOCATION="swedencentral" +``` + +### 1.1 Management Group Hierarchy + +> [!CAUTION] +> For the workshop, the Management Group hierarchy (steps below) was created for you. Your user does not have the necessary permissions to do so. In case you want to run through this in your own environment, you need to follow the permissions setup as described [here](https://github.com/Azure/Enterprise-Scale/wiki/ALZ-Setup-azure). +> From here on out, whenver a MGID or MGIDprefix is required, please use your **userid**. + +```bash +TEMPLATEFILE="bicep/modules/managementGroups/managementGroups.bicep" +PARAMETERS="@bicep/modules/managementGroups/parameters/managementGroups.parameters.solution.json" + +MGID=$TopLevelMGPrefix +NAME="alz-PolicyDefsDefaults-${dateYMD}" + +az deployment tenant create --name ${NAME:0:63} --location $LOCATION --template-file $TEMPLATEFILE --parameters $PARAMETERS +``` + +![image](images/challenge01/mg-group-result.jpg) + +### 1.2 Custom Policy Definition + +> [!TIP] +> Make sure you update the parameter file to provide the value for _parTargetManagementGroupId_ to correspond to your _MGID_ env variable, or provide the parameter using the commandline. + +```bash +MGID=mhpgw +TEMPLATEFILE="bicep/modules/policy/definitions/customPolicyDefinitions.bicep" +PARAMETERS="@bicep/modules/policy/definitions/parameters/customPolicyDefinitions.parameters.solution.json" + +az deployment mg create --name ${NAME:0:63} --location $LOCATION --management-group-id $MGID --template-file $TEMPLATEFILE --parameters $PARAMETERS +``` + +> [!TIP] +> Make sure you switch the scope to your management group in the list filter at the top + +![image](images/challenge01/policy-result.jpg) + +### 1.3 Custom RBAC Roles + +> [!TIP] +> Make sure you update the parameter file to provide the value for _parAssignableScopeManagementGroupId_ to correspond to your _MGID_ env variable, or provide the parameter using the commandline. + +```bash +dateYMD=$(date +%Y%m%dT%H%M%S%NZ) +NAME="alz-CustomRoleDefsDeployment-${dateYMD}" +TEMPLATEFILE="bicep/modules/customRoleDefinitions/customRoleDefinitions.bicep" +PARAMETERS="@bicep/modules/customRoleDefinitions/parameters/customRoleDefinitions.parameters.solution.json" + +az deployment mg create --name ${NAME:0:63} --location $LOCATION --management-group-id $MGID --template-file $TEMPLATEFILE --parameters $PARAMETERS +``` + +![image](images/challenge01/custom-role-result.jpg) + +# Challenge 2 - Logging & Security + +## Solution + +> [!TIP] +> Make sure you inspect the parameter file carfully. There are certain parameters (e.g. _parLogAnalyticsWorkspaceLocation_) which you need to take care of in the parameter file. + +### 2.1 Logging + +```bash +dateYMD=$(date +%Y%m%dT%H%M%S%NZ) +GROUP="rg-$TopLevelMGPrefix-logging-001" +NAME="alz-loggingDeployment-${dateYMD}" +TEMPLATEFILE="bicep/modules/logging/logging.bicep" +PARAMETERS="@bicep/modules/logging/parameters/logging.parameters.solution.json" + +az group create \ + --name $GROUP \ + --location $LOCATION + +az deployment group create --name ${NAME:0:63} --resource-group $GROUP --template-file $TEMPLATEFILE --parameters $PARAMETERS +``` + +![image](images/challenge02/logging-result.jpg) + +### 2.2. Management Group Diagnostic Settings + +> [!TIP] +> This step requires referencing the Log Analystics worspace you just created by its resource id, which can be found in the output of the previous deployment step or via Azure Portal. +> The resource id needs to be provided as the value of _parLogAnalyticsWorkspaceResourceId_ in the parameter file. + +```bash +dateYMD=$(date +%Y%m%dT%H%M%S%NZ) +NAME="alz-mgDiagSettings-${dateYMD}" +TEMPLATEFILE="bicep/modules/mgDiagSettings/mgDiagSettings.bicep" +PARAMETERS="bicep/modules/mgDiagSettings/parameters/mgDiagSettings.parameters.solution.json" + +az deployment mg create --name $NAME --location $LOCATION --template-file $TEMPLATEFILE --parameters $PARAMETERS --management-group-id $MGID +``` + +> [!TIP] +> The only way to validate the correct creation is to use the REST APIs as documented [here](https://learn.microsoft.com/en-us/rest/api/monitor/management-group-diagnostic-settings/get?view=rest-monitor-2020-01-01-preview&tabs=HTTP#code-try-0). This call requires the Management Group Id the settings were deployed to and the name of the settings, which can be found in the parameters file. + +# Challenge 3 - Core Connectivity + +## Solution + +> [!NOTE] +> Depending on the network topology you are planning to use (Hub-Spoke or Virtual WAN) you can use the respective chapters. + +### 3.1 Hub Connectivity + +```bash +ConnectivitySubscriptionId="ccba9824-4a78-4aae-be58-2a597800d986" +``` + +> [!IMPORTANT] +> For the workshop, we are using the same subscription for all aspects. In a real deployment you might distribute the connectivity components into their own "Connectivity" subscription, for easier access control and cost managment. + +> [!TIP] +> Make sure you set -at least- the value for _parLocation_ and _parCompanyPrefix_ in the parameter file. + +```bash +az account set --subscription $ConnectivitySubscriptionId + +dateYMD=$(date +%Y%m%dT%H%M%S%NZ) +NAME="${TopLevelMGPrefix}-HubNetworkingDeploy-${dateYMD}" +GROUP="rg-${TopLevelMGPrefix}-hub-networking-000" + +TEMPLATEFILE="bicep/modules/hubNetworking/hubNetworking.bicep" +PARAMETERS="bicep/modules/hubNetworking/parameters/hubNetworking.parameters.solution.json" + +az group create --location $LOCATION --name $GROUP +``` + +> [!TIP] +> Since the challenge is asking for DDoS Protection to be initially disabled, you need to set the value of _parDdosEnabled_ accordingly. + +```bash +az deployment group create --name ${NAME:0:63} --resource-group $GROUP --template-file $TEMPLATEFILE --parameters $PARAMETERS +``` + +![image](images/challenge03/hubNetworking.jpg) + +### 3.1a vWAN Connectivity + +```bash +dateYMD=$(date +%Y%m%dT%H%M%S%NZ) +NAME="alz-vwanConnectivityDeploy-${dateYMD}" +GROUP="rg-$TopLevelMGPrefix-vwan-001" +TEMPLATEFILE="bicep/modules/vwanConnectivity/vwanConnectivity.bicep" +PARAMETERS="@bicep/modules/vwanConnectivity/parameters/vwanConnectivity.parameters.solution.json" + +az group create \ + --name $GROUP \ + --location $LOCATION +``` + +> [!TIP] +> Since the challenge is asking for DDoS Protection to be initially disabled, you need to set the value of _parDdosEnabled_ accordingly. + +```bash +az deployment group create --name ${NAME:0:63} --resource-group $GROUP --template-file $TEMPLATEFILE --parameters $PARAMETERS +``` + +![image](images/challenge03/vwanNetworking.jpg) + +# Challenge 4 - Role Assignments + +## Solution + +```bash +GROUP="rg-$TopLevelMGPrefix-workload-001" + +az group create \ + --name $GROUP \ + --location $LOCATION +``` + +> [!TIP] +> If you have not set up a security group which would technically hold your users for this given role, you need to create one as the templates will need an assignee's object ID. +> +> ```bash +> GROUP_NAME="sg-mhpgw-workload-admins" +> GROUP_NICK="sg-mhpgw-workload-admins" +> GROUP_DESC="Workshop workload admins" +> +> az ad group create \ +> --display-name "$GROUP_NAME" \ +> --mail-nickname "$GROUP_NICK" \ +> --description "$GROUP_DESC" +> ``` +> +> You can then query the groups object id using the following command +> +> ```bash +> az ad group show --group --query id +> ``` +> +> e.g. az ad group show --group $GROUP_NAME --query id + +```bash +dateYMD=$(date +%Y%m%dT%H%M%S%NZ) +MGID=$TopLevelMGPrefix +NAME="alz-RoleAssignmentsDeployment-${dateYMD}" +TEMPLATEFILE="bicep/modules/roleAssignments/roleAssignmentResourceGroup.bicep" +PARAMETERS="@bicep/modules/roleAssignments/parameters/roleAssignmentResourceGroup.securityGroup.parameters.solution.json" + +az deployment group create --name ${NAME:0:63} --resource-group $GROUP --template-file $TEMPLATEFILE --parameters $PARAMETERS +``` + +> [!NOTE] +> This module covers multiple options for role assginemnt. For simplicity we are using the _single Resource group_ option, but strongly encourage you to also check out the _many_ assignments, different scope and assignee options. + +Validate the assginmet in _Identity & Access Management_ for the Resource group in Azure Portal. + +![image](images/challenge04/IAM.jpg) + +# Challenge 5 - Subscription Placement + +> [!IMPORTANT] +> As noted in the description of Challenge 5, there is no sulution steps as this challenge cannot be executed in the shared workshop environment. +> +> In real-world environments, a subscription would be moved to its corresponding management group, which would automatically apply and RBAC or policy assignments. +> +> Please continue with Challenge 6. + +# Challenge 6 - Policy Assignments + +> [!NOTE] +> Policy Assignment is handled at the Management Group level. So for this challenge you will need to choose one of the Management Groups of the hierarchy assigned to you as part of Challenge 1. + +## Solution + +### 6.1 - Policy Assignment to Managmeent Group + +Default Policy Assignments + +```bash + +dateYMD=$(date +%Y%m%dT%H%M%S%NZ) +NAME="alz-alzPolicyAssignmentDefaults-${dateYMD}" +TEMPLATEFILE="bicep/modules/policy/assignments/alzDefaults/alzDefaultPolicyAssignments.bicep" +PARAMETERS="@bicep/modules/policy/assignments/alzDefaults/parameters/alzDefaultPolicyAssignments.parameters.solution.json" + +az deployment mg create --name ${NAME:0:63} --location $LOCATION --management-group-id $MGID --template-file $TEMPLATEFILE --parameters $PARAMETERS +``` + +Workload-specific Policy Assignments + +```bash +dateYMD=$(date +%Y%m%dT%H%M%S%NZ) +NAME="alz-alzPolicyAssignmentWorkloadSpecific-${dateYMD}" +TEMPLATEFILE="bicep/modules/policy/assignments/workloadSpecific/workloadSpecificPolicyAssignments.bicep" +PARAMETERS="@bicep/modules/policy/assignments/workloadSpecific/parameters/workloadSpecificPolicyAssignments.parameters.solution.json" + +az deployment mg create --name ${NAME:0:63} --location $LOCATION --management-group-id $MGID --template-file $TEMPLATEFILE --parameters $PARAMETERS +``` + +### 6.2 Policy Excemption for Subscription + +```bash +EXCEMPTION_NAME="" +SCOPE_ID="" +ASSIGNMENT_ID="" +EXCEMPTION_CATEGORY="Waiver" +DISPLAY_NAME="" +REASON="" + +az policy exemption create \ + --name "$EXCEMPTION_NAME" \ + --scope "$SCOPE_ID" \ + --policy-assignment "$ASSIGNMENT_ID" \ + --exemption-category "$EXCEMPTION_CATEGORY" \ + --display-name "$DISPLAY_NAME" \ + --description "$REASON" +``` + +> [!NOTE] +> You can find an example on how to create a comfortable (and automatable) way in challenge6/excemption. +> The example consists of a bash script which populates all of the above environment variables. + +### 6.3 Policy Assignment to Resource Group + +For the purpose of this workshop we assume certain policies excluded at the Management Group level need to be assigned at the Resource Group level for one particular workload. + +> [!NOTE] +> Use the Resource Group you created in Challenge 4 for this assignment. + +```bash + +dateYMD=$(date +%Y%m%dT%H%M%S%NZ) +NAME="alz-customPolicy-${dateYMD}" + +az deployment sub create \ + --name $NAME \ + --location $LOCATION \ + --template-file challenge6/custom-policy/allowed-regions/policyDefinition.bicep \ + --parameters policyDefinitionName=${TopLevelMGPrefix}-custom-allowed-regions +``` + +Deploy assignment: + +```bash +dateYMD=$(date +%Y%m%dT%H%M%S%NZ) +NAME="alz-customPolicy-assginment-${dateYMD}" + +az deployment sub create \ + --name $NAME \ + --location $LOCATION \ + --template-file challenge6/custom-policy/allowed-regions/policyAssignment.bicep \ + --parameters assignmentName=${TopLevelMGPrefix}-custom-allowed-regions-assignment \ + policyDefinitionName=${TopLevelMGPrefix}-custom-allowed-regions \ + targetResourceGroupName=$GROUP \ + allowedLocations='["swedencentral"]' +``` + +```bash +POLICY_NAME=$(az policy definition list --query "[?displayName=='Storage accounts should disable public network access'].name | [0]" -o tsv) +POLICY_ID="/providers/Microsoft.Authorization/policyDefinitions/${POLICY_NAME}" +dateYMD=$(date +%Y%m%dT%H%M%S%NZ) +NAME="alz-storageNoPublicAccess-assginment-${dateYMD}" + +az deployment sub create \ + --name $NAME \ + --location $LOCATION \ + --template-file challenge6/storage-policy/storageNoPublicAccessAssignment.bicep \ + --parameters targetResourceGroupName=$GROUP \ + policyDefinitionId="$POLICY_ID" +``` + +# Challenge 7 - Workload Deployment + +## Solution + +```bash +TEMPLATEFILE=challenge7/storageAccount.bicep +STORAGENAME=alz${TopLevelMGPrefix}st +# should fail --> wrong region +az deployment group create \ + --resource-group $GROUP \ + --template-file $TEMPLATEFILE \ + --parameters storageAccountName=$STORAGENAME \ + allowPublicAccess=false \ + location=westeurope +# should fail --> policy vialoation, no public access +# if it succeeds, check your policies enforcement mode +az deployment group create \ + --resource-group $GROUP \ + --template-file $TEMPLATEFILE \ + --parameters storageAccountName=$STORAGENAME \ + allowPublicAccess=true \ + location=swedencentral +# shopuld succeed +az deployment group create \ + --resource-group $GROUP \ + --template-file $TEMPLATEFILE \ + --parameters storageAccountName=$STORAGENAME \ + allowPublicAccess=false \ + location=swedencentral +``` + +[Top](#generic)