├── .github ├── ISSUE_TEMPLATE │ ├── config.yml │ ├── feedback.yml │ └── bug.yml ├── release.yml ├── PULL_REQUEST_TEMPLATE.md └── CONTRIBUTING.md ├── Instructions └── Labs │ ├── media │ ├── vg-create.png │ ├── acr-password.png │ ├── agent-status.png │ ├── import-repo.png │ ├── create-project.png │ ├── new-agent-pool.png │ ├── new-team-project.png │ ├── add-role-assignment.png │ ├── agent-configuration.png │ ├── agent-pool-security.png │ ├── eshop-variable-group.png │ ├── managed-identities.png │ ├── pipeline-permissions.png │ ├── repository-security.png │ ├── azure-devops-projects.png │ ├── create-security-group.png │ ├── multi-stage-completed.png │ ├── new-service-connection.png │ ├── add-environment-approvals.png │ ├── azure-container-registry.png │ ├── create-managed-identity.png │ ├── pipeline-parameters-run.png │ ├── pipeline-permit-resource.png │ ├── pipeline-validation-fail.png │ ├── security-group-settings.png │ ├── personal-access-token-menu.png │ ├── pipeline-environment-permit.png │ ├── pipeline-permission-permit.png │ ├── select-ci-container-compose.png │ ├── add-environment-branch-control.png │ ├── create-virtual-machine-preset.png │ ├── eshoponweb-variables-template.png │ ├── pipeline-add-yaml-deployment.png │ ├── pipeline-logs-managed-identity.png │ ├── pipeline-successful-executed.png │ ├── eshoponweb-pipeline-multi-stage.png │ ├── pipeline-deploy-permit-resource.png │ ├── agent-pool-security-no-restriction.png │ ├── personal-access-token-configuration.png │ ├── pipeline-deploy-environment-success.png │ ├── pipeline-execution-using-template.png │ ├── pipeline-test-environment-approve.png │ ├── pipeline-test-environment-success.png │ ├── pipeline-variables-resource-section.png │ ├── agent-pool-security-add-user-permissions.png │ └── create-new-agent-pool-self-hosted-agent.png │ ├── APL2001_M07_L07_Configure_Pipelines_to_Securely_Use_Variables_and_Parameters.md │ ├── APL2001_M05_L05_Extend_a_Pipeline_to_Use_Multiple_Templates.md │ ├── APL2001_M00_Validate_Lab_Environment.md │ ├── APL2001_M04_L04_Configure_and_Validate_Permissions.md │ ├── APL2001_M06_L06_Integrate_Azure_Key_Vault_With_Azure_Pipelines.md │ ├── APL2001_M01_L01_Configure_a_Project_and_Repository_Structure_to_Support_Secure_Pipelines.md │ ├── APL2001_M03_L03_Managed_Identity_for_Projects_and_Pipelines.md │ └── APL2001_M02_L02_Configure_Agents_And_Agent_Pools_for_Secure_Pipelines.md ├── .gitignore ├── _config.yml ├── .gitattributes ├── README.md ├── index.md ├── LICENSE └── _build.yml /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | -------------------------------------------------------------------------------- /Instructions/Labs/media/vg-create.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/implement-security-through-pipeline-using-devops/HEAD/Instructions/Labs/media/vg-create.png -------------------------------------------------------------------------------- /Instructions/Labs/media/acr-password.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/implement-security-through-pipeline-using-devops/HEAD/Instructions/Labs/media/acr-password.png -------------------------------------------------------------------------------- /Instructions/Labs/media/agent-status.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/implement-security-through-pipeline-using-devops/HEAD/Instructions/Labs/media/agent-status.png -------------------------------------------------------------------------------- /Instructions/Labs/media/import-repo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/implement-security-through-pipeline-using-devops/HEAD/Instructions/Labs/media/import-repo.png -------------------------------------------------------------------------------- /Instructions/Labs/media/create-project.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/implement-security-through-pipeline-using-devops/HEAD/Instructions/Labs/media/create-project.png -------------------------------------------------------------------------------- /Instructions/Labs/media/new-agent-pool.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/implement-security-through-pipeline-using-devops/HEAD/Instructions/Labs/media/new-agent-pool.png -------------------------------------------------------------------------------- /Instructions/Labs/media/new-team-project.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/implement-security-through-pipeline-using-devops/HEAD/Instructions/Labs/media/new-team-project.png -------------------------------------------------------------------------------- /Instructions/Labs/media/add-role-assignment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/implement-security-through-pipeline-using-devops/HEAD/Instructions/Labs/media/add-role-assignment.png -------------------------------------------------------------------------------- /Instructions/Labs/media/agent-configuration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/implement-security-through-pipeline-using-devops/HEAD/Instructions/Labs/media/agent-configuration.png -------------------------------------------------------------------------------- /Instructions/Labs/media/agent-pool-security.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/implement-security-through-pipeline-using-devops/HEAD/Instructions/Labs/media/agent-pool-security.png -------------------------------------------------------------------------------- /Instructions/Labs/media/eshop-variable-group.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/implement-security-through-pipeline-using-devops/HEAD/Instructions/Labs/media/eshop-variable-group.png -------------------------------------------------------------------------------- /Instructions/Labs/media/managed-identities.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/implement-security-through-pipeline-using-devops/HEAD/Instructions/Labs/media/managed-identities.png -------------------------------------------------------------------------------- /Instructions/Labs/media/pipeline-permissions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/implement-security-through-pipeline-using-devops/HEAD/Instructions/Labs/media/pipeline-permissions.png -------------------------------------------------------------------------------- /Instructions/Labs/media/repository-security.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/implement-security-through-pipeline-using-devops/HEAD/Instructions/Labs/media/repository-security.png -------------------------------------------------------------------------------- /Instructions/Labs/media/azure-devops-projects.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/implement-security-through-pipeline-using-devops/HEAD/Instructions/Labs/media/azure-devops-projects.png -------------------------------------------------------------------------------- /Instructions/Labs/media/create-security-group.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/implement-security-through-pipeline-using-devops/HEAD/Instructions/Labs/media/create-security-group.png -------------------------------------------------------------------------------- /Instructions/Labs/media/multi-stage-completed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/implement-security-through-pipeline-using-devops/HEAD/Instructions/Labs/media/multi-stage-completed.png -------------------------------------------------------------------------------- /Instructions/Labs/media/new-service-connection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/implement-security-through-pipeline-using-devops/HEAD/Instructions/Labs/media/new-service-connection.png -------------------------------------------------------------------------------- /Instructions/Labs/media/add-environment-approvals.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/implement-security-through-pipeline-using-devops/HEAD/Instructions/Labs/media/add-environment-approvals.png -------------------------------------------------------------------------------- /Instructions/Labs/media/azure-container-registry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/implement-security-through-pipeline-using-devops/HEAD/Instructions/Labs/media/azure-container-registry.png -------------------------------------------------------------------------------- /Instructions/Labs/media/create-managed-identity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/implement-security-through-pipeline-using-devops/HEAD/Instructions/Labs/media/create-managed-identity.png -------------------------------------------------------------------------------- /Instructions/Labs/media/pipeline-parameters-run.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/implement-security-through-pipeline-using-devops/HEAD/Instructions/Labs/media/pipeline-parameters-run.png -------------------------------------------------------------------------------- /Instructions/Labs/media/pipeline-permit-resource.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/implement-security-through-pipeline-using-devops/HEAD/Instructions/Labs/media/pipeline-permit-resource.png -------------------------------------------------------------------------------- /Instructions/Labs/media/pipeline-validation-fail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/implement-security-through-pipeline-using-devops/HEAD/Instructions/Labs/media/pipeline-validation-fail.png -------------------------------------------------------------------------------- /Instructions/Labs/media/security-group-settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/implement-security-through-pipeline-using-devops/HEAD/Instructions/Labs/media/security-group-settings.png -------------------------------------------------------------------------------- /Instructions/Labs/media/personal-access-token-menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/implement-security-through-pipeline-using-devops/HEAD/Instructions/Labs/media/personal-access-token-menu.png -------------------------------------------------------------------------------- /Instructions/Labs/media/pipeline-environment-permit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/implement-security-through-pipeline-using-devops/HEAD/Instructions/Labs/media/pipeline-environment-permit.png -------------------------------------------------------------------------------- /Instructions/Labs/media/pipeline-permission-permit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/implement-security-through-pipeline-using-devops/HEAD/Instructions/Labs/media/pipeline-permission-permit.png -------------------------------------------------------------------------------- /Instructions/Labs/media/select-ci-container-compose.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/implement-security-through-pipeline-using-devops/HEAD/Instructions/Labs/media/select-ci-container-compose.png -------------------------------------------------------------------------------- /Instructions/Labs/media/add-environment-branch-control.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/implement-security-through-pipeline-using-devops/HEAD/Instructions/Labs/media/add-environment-branch-control.png -------------------------------------------------------------------------------- /Instructions/Labs/media/create-virtual-machine-preset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/implement-security-through-pipeline-using-devops/HEAD/Instructions/Labs/media/create-virtual-machine-preset.png -------------------------------------------------------------------------------- /Instructions/Labs/media/eshoponweb-variables-template.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/implement-security-through-pipeline-using-devops/HEAD/Instructions/Labs/media/eshoponweb-variables-template.png -------------------------------------------------------------------------------- /Instructions/Labs/media/pipeline-add-yaml-deployment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/implement-security-through-pipeline-using-devops/HEAD/Instructions/Labs/media/pipeline-add-yaml-deployment.png -------------------------------------------------------------------------------- /Instructions/Labs/media/pipeline-logs-managed-identity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/implement-security-through-pipeline-using-devops/HEAD/Instructions/Labs/media/pipeline-logs-managed-identity.png -------------------------------------------------------------------------------- /Instructions/Labs/media/pipeline-successful-executed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/implement-security-through-pipeline-using-devops/HEAD/Instructions/Labs/media/pipeline-successful-executed.png -------------------------------------------------------------------------------- /Instructions/Labs/media/eshoponweb-pipeline-multi-stage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/implement-security-through-pipeline-using-devops/HEAD/Instructions/Labs/media/eshoponweb-pipeline-multi-stage.png -------------------------------------------------------------------------------- /Instructions/Labs/media/pipeline-deploy-permit-resource.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/implement-security-through-pipeline-using-devops/HEAD/Instructions/Labs/media/pipeline-deploy-permit-resource.png -------------------------------------------------------------------------------- /Instructions/Labs/media/agent-pool-security-no-restriction.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/implement-security-through-pipeline-using-devops/HEAD/Instructions/Labs/media/agent-pool-security-no-restriction.png -------------------------------------------------------------------------------- /Instructions/Labs/media/personal-access-token-configuration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/implement-security-through-pipeline-using-devops/HEAD/Instructions/Labs/media/personal-access-token-configuration.png -------------------------------------------------------------------------------- /Instructions/Labs/media/pipeline-deploy-environment-success.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/implement-security-through-pipeline-using-devops/HEAD/Instructions/Labs/media/pipeline-deploy-environment-success.png -------------------------------------------------------------------------------- /Instructions/Labs/media/pipeline-execution-using-template.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/implement-security-through-pipeline-using-devops/HEAD/Instructions/Labs/media/pipeline-execution-using-template.png -------------------------------------------------------------------------------- /Instructions/Labs/media/pipeline-test-environment-approve.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/implement-security-through-pipeline-using-devops/HEAD/Instructions/Labs/media/pipeline-test-environment-approve.png -------------------------------------------------------------------------------- /Instructions/Labs/media/pipeline-test-environment-success.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/implement-security-through-pipeline-using-devops/HEAD/Instructions/Labs/media/pipeline-test-environment-success.png -------------------------------------------------------------------------------- /Instructions/Labs/media/pipeline-variables-resource-section.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/implement-security-through-pipeline-using-devops/HEAD/Instructions/Labs/media/pipeline-variables-resource-section.png -------------------------------------------------------------------------------- /Instructions/Labs/media/agent-pool-security-add-user-permissions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/implement-security-through-pipeline-using-devops/HEAD/Instructions/Labs/media/agent-pool-security-add-user-permissions.png -------------------------------------------------------------------------------- /Instructions/Labs/media/create-new-agent-pool-self-hosted-agent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/implement-security-through-pipeline-using-devops/HEAD/Instructions/Labs/media/create-new-agent-pool-self-hosted-agent.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | log/ 2 | obj/ 3 | raw/ 4 | viewmodel/ 5 | _model/ 6 | _viewmodel/ 7 | _site/ 8 | .optemp/ 9 | _themes*/ 10 | _dependentPackages/ 11 | 12 | **/.vscode/ 13 | .devcontainer/ 14 | .vs/ 15 | .DS_Store 16 | Thumbs.db 17 | *.bak 18 | .fake 19 | 20 | ###################### 21 | # IntelliJ 22 | ###################### 23 | .idea/ 24 | *.iml 25 | *.iws 26 | *.ipr 27 | *.ids -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | remote_theme: MicrosoftLearning/Jekyll-Theme 2 | exclude: 3 | - readme.md 4 | - .github/ 5 | header_pages: 6 | - index.html 7 | author: Microsoft Learning 8 | twitter_username: mslearning 9 | github_username: MicrosoftLearning 10 | plugins: 11 | - jekyll-sitemap 12 | - jekyll-mentions 13 | - jemoji 14 | markdown: kramdown 15 | kramdown: 16 | syntax_highlighter_opts: 17 | disable : true 18 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Set the default behavior, in case people don't have core.autocrlf set. 2 | * text=auto 3 | 4 | # Explicitly declare text files you want to always be normalized and converted 5 | # to native line endings on checkout. 6 | *.c text 7 | *.h text 8 | 9 | # Declare files that will always have CRLF line endings on checkout. 10 | *.sln text eol=crlf 11 | 12 | # Denote all files that are truly binary and should not be modified. 13 | *.png binary 14 | *.jpg binary -------------------------------------------------------------------------------- /.github/release.yml: -------------------------------------------------------------------------------- 1 | # .github/release.yml 2 | 3 | changelog: 4 | exclude: 5 | labels: 6 | - ignore-for-release 7 | authors: 8 | - lumac 9 | categories: 10 | - title: Breaking Changes 🛠 11 | labels: 12 | - Semver-Major 13 | - breaking-change 14 | - title: Exciting New Features 🎉 15 | labels: 16 | - Semver-Minor 17 | - enhancement 18 | - title: Other Changes 19 | labels: 20 | - "*" -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Implement security through a pipeline using Azure DevOps 2 | 3 | This repo contains the instructions and assets required to complete the exercises in the [Implement security through a pipeline using DevOps](https://learn.microsoft.com/training/paths/implement-security-through-pipeline-using-devops/) learning path on Microsoft Learn. 4 | 5 | ## Reporting issues 6 | 7 | If you encounter any problems in the exercises, please report them as **issues** in this repo. 8 | -------------------------------------------------------------------------------- /index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Implement security through a pipeline using Azure DevOps exercises 3 | permalink: index.html 4 | layout: home 5 | --- 6 | 7 | # Implement security through a pipeline using Azure DevOps exercises 8 | 9 | The following exercises are designed to support the modules on [Implement security through a pipeline using DevOps](https://learn.microsoft.com/training/paths/implement-security-through-pipeline-using-devops/). 10 | 11 | {% assign labs = site.pages | where_exp:"page", "page.url contains '/Instructions/Labs'" %} 12 | {% for activity in labs %} 13 | - [{{ activity.lab.title }}]({{ site.github.url }}{{ activity.url }}) 14 | {% endfor %} 15 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | > **Note** 2 | > Replace issue name LAB00:QUICK_DESCRIPTION, for example "LAB01: My new issue" (or same name as linked Issue) 3 | 4 | ## Related Issue 5 | 6 | **Link related Github Issue** 🢂 Fixes # . (Include issue number after #) 7 | 8 | ## Checklist 9 | 10 | Mark completed with "x" between brackets, "[x]", or checking the box once the PR is created: 11 | 12 | - [ ] Has related GitHub Issue 💥 [Create Issue](https://github.com/MicrosoftLearning/ProjectSpike/blob/main/.github/CONTRIBUTING.md) 📝 13 | - [ ] Tested it 14 | - [ ] Read the PR collaboration guide 👓 [Collaboration Guide](https://github.com/MicrosoftLearning/ProjectSpike/blob/main/.github/CONTRIBUTING.md) 15 | 16 | Changes proposed in this pull request: 17 | 18 | - 19 | - 20 | - 21 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Sidney Andrews 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feedback.yml: -------------------------------------------------------------------------------- 1 | name: Feedback Report 2 | description: File a feedback report 3 | title: "M00-LAB00: QUICK_DESCRIPTION" 4 | labels: ["feedback"] 5 | body: 6 | - type: markdown 7 | attributes: 8 | value: | 9 | # Thanks for taking the time to fill out this feedback report! 10 | 11 | > **Note** 12 | > Replace feedback name LAB00:QUICK_DESCRIPTION, for example "LAB01: My new feedback" 13 | - type: input 14 | id: contact 15 | attributes: 16 | label: Contact Details 17 | description: How can we get in touch with you if we need more info 😉? 18 | placeholder: ex. email@example.com 19 | validations: 20 | required: false 21 | - type: textarea 22 | id: what-happened 23 | attributes: 24 | label: What should we change? 25 | description: What should we change? 26 | placeholder: Tell us your suggestion! 27 | value: SUGGESTION 28 | validations: 29 | required: true 30 | - type: textarea 31 | id: Screenshots 32 | attributes: 33 | label: Relevant screenshots 34 | description: Please copy and paste any relevant screenshots 📸 35 | value: paste here 😉 36 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug.yml: -------------------------------------------------------------------------------- 1 | name: Bug Report 2 | description: File a bug report 3 | title: "M00-LAB00: QUICK_DESCRIPTION" 4 | labels: ["bug"] 5 | body: 6 | - type: markdown 7 | attributes: 8 | value: | 9 | # Thanks for taking the time to fill out this bug report! 10 | 11 | > **Note** 12 | > Replace issue name LAB00:QUICK_DESCRIPTION, for example "LAB01: My new issue" (or same name as linked Issue) 13 | - type: input 14 | id: contact 15 | attributes: 16 | label: Contact Details 17 | description: How can we get in touch with you if we need more info 😉? 18 | placeholder: ex. email@example.com 19 | validations: 20 | required: false 21 | - type: textarea 22 | id: what-happened 23 | attributes: 24 | label: What happened? 25 | description: What happened? 26 | placeholder: Tell us what you see! 27 | value: | 28 | Lab/Demo: 00 29 | Exercise : 00 30 | Task: 00 31 | Step: 00 32 | 33 | Description of issue: 34 | 35 | Repro steps: 36 | 1. 37 | 1. 38 | 1. 39 | validations: 40 | required: true 41 | - type: textarea 42 | id: Screenshots 43 | attributes: 44 | label: Relevant screenshots 45 | description: Please copy and paste any relevant screenshots 📸 46 | value: paste here 😉 47 | -------------------------------------------------------------------------------- /_build.yml: -------------------------------------------------------------------------------- 1 | name: '$(Date:yyyyMMdd)$(Rev:.rr)' 2 | jobs: 3 | - job: build_markdown_content 4 | displayName: 'Build Markdown Content' 5 | workspace: 6 | clean: all 7 | pool: 8 | vmImage: 'ubuntu-latest' 9 | container: 10 | image: 'microsoftlearning/markdown-build:latest' 11 | steps: 12 | - task: Bash@3 13 | displayName: 'Build Content' 14 | inputs: 15 | targetType: inline 16 | script: | 17 | cp /{attribution.md,template.docx,package.json,package.js} . 18 | npm install 19 | node package.js --version $(Build.BuildNumber) 20 | - task: GitHubRelease@0 21 | displayName: 'Create GitHub Release' 22 | inputs: 23 | gitHubConnection: 'github-microsoftlearning-organization' 24 | repositoryName: '$(Build.Repository.Name)' 25 | tagSource: manual 26 | tag: 'v$(Build.BuildNumber)' 27 | title: 'Version $(Build.BuildNumber)' 28 | releaseNotesSource: input 29 | releaseNotes: '# Version $(Build.BuildNumber) Release' 30 | assets: '$(Build.SourcesDirectory)/out/*.zip' 31 | assetUploadMode: replace 32 | - task: PublishBuildArtifacts@1 33 | displayName: 'Publish Output Files' 34 | inputs: 35 | pathtoPublish: '$(Build.SourcesDirectory)/out/' 36 | artifactName: 'Lab Files' 37 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Microsoft Learning Repositories 2 | 3 | MCT contributions are a key part of keeping the lab and demo content current as the Azure platform changes. We want to make it as easy as possible for you to contribute changes to the lab files. Here are a few guidelines to keep in mind as you contribute changes. 4 | 5 | ## GitHub Use & Purpose 6 | 7 | Microsoft Learning is using GitHub to publish the lab steps and lab scripts for courses that cover cloud services like Azure. Using GitHub allows the course’s authors and MCTs to keep the lab content current with Azure platform changes. Using GitHub allows the MCTs to provide feedback and suggestions for lab changes, and then the course authors can update lab steps and scripts quickly and relatively easily. 8 | 9 | > When you prepare to teach these courses, you should ensure that you are using the latest lab steps and scripts by downloading the appropriate files from GitHub. GitHub should not be used to discuss technical content in the course, or how to prep. It should only be used to address changes in the labs. 10 | 11 | It is strongly recommended that MCTs and Partners access these materials and in turn, provide them separately to students. Pointing students directly to GitHub to access Lab steps as part of an ongoing class will require them to access yet another UI as part of the course, contributing to a confusing experience for the student. An explanation to the student regarding why they are receiving separate Lab instructions can highlight the nature of an always-changing cloud-based interface and platform. Microsoft Learning support for accessing files on GitHub and support for navigation of the GitHub site is limited to MCTs teaching this course only. 12 | 13 | > As an alternative to pointing students directly to the GitHub repository, you can point students to the GitHub Pages website to view the lab instructions. The URL for the GitHub Pages website can be found at the top of the repository. 14 | 15 | To address general comments about the course and demos, or how to prepare for a course delivery, please use the existing MCT forums. 16 | 17 | ## Additional Resources 18 | 19 | A user guide has been provided for MCTs who are new to GitHub. It provides steps for connecting to GitHub, downloading and printing course materials, updating the scripts that students use in labs, and explaining how you can help ensure that this course’s content remains current. 20 | 21 | 22 | -------------------------------------------------------------------------------- /Instructions/Labs/APL2001_M07_L07_Configure_Pipelines_to_Securely_Use_Variables_and_Parameters.md: -------------------------------------------------------------------------------- 1 | --- 2 | lab: 3 | title: 'Configure pipelines to securely use variables and parameters' 4 | module: 'Module 7: Configure pipelines to securely use variables and parameters' 5 | --- 6 | 7 | # Configure pipelines to securely use variables and parameters 8 | 9 | In this lab, you will learn how to configure pipelines to securely use variables and parameters. 10 | 11 | These exercises take approximately **20** minutes. 12 | 13 | ## Before you start 14 | 15 | You'll need an Azure subscription, Azure DevOps organization, and the eShopOnWeb application to follow the labs. 16 | 17 | - Follow the steps to [validate your lab environment](APL2001_M00_Validate_Lab_Environment.md). 18 | 19 | ## Instructions 20 | 21 | ### Exercise 1: Ensure parameter and variable types 22 | 23 | #### Task 1: (skip if done) Import and run the CI pipeline 24 | 25 | Let's start by importing the CI pipeline named [eshoponweb-ci.yml](https://github.com/MicrosoftLearning/eShopOnWeb/blob/main/.ado/eshoponweb-ci.yml). 26 | 27 | 1. Navigate to the Azure DevOps portal at `https://aex.dev.azure.com` and open your organization. 28 | 29 | 1. Open the **eShopOnWeb** project in Azure DevOps. 30 | 31 | 1. Go to **Pipelines > Pipelines**. 32 | 33 | 1. Select the **Create Pipeline** button. 34 | 35 | 1. Select **Azure Repos Git (Yaml)**. 36 | 37 | 1. Select the **eShopOnWeb** repository. 38 | 39 | 1. Select **Existing Azure Pipelines YAML File**. 40 | 41 | 1. Select the **/.ado/eshoponweb-ci.yml** file then click on **Continue**. 42 | 43 | 1. Select the **Run** button to run the pipeline. 44 | 45 | > **Note**: Your pipeline will take a name based on the project name. You will rename it to easier identify the pipeline. 46 | 47 | 1. Go to **Pipelines > Pipelines** and select the recently created pipeline. Select the ellipsis and then select **Rename/move** option. 48 | 49 | 1. Name it **eshoponweb-ci** and select **Save**. 50 | 51 | #### Task 2: Ensure parameter types for YAML pipelines 52 | 53 | In this task, you will set parameter and parameter types for the pipeline. 54 | 55 | 1. Go to **Pipelines > Pipelines** and select the **eshoponweb-ci** pipeline. 56 | 57 | 1. Select **Edit**. 58 | 59 | 1. Add the following parameters above the jobs sections to the top of the YAML file: 60 | 61 | ```yaml 62 | parameters: 63 | - name: dotNetProjects 64 | type: string 65 | default: '**/*.sln' 66 | - name: testProjects 67 | type: string 68 | default: 'tests/UnitTests/*.csproj' 69 | 70 | jobs: 71 | - job: Build 72 | pool: eShopOnWebSelfPool 73 | steps: 74 | 75 | ``` 76 | 77 | 1. Replace the hardcoded paths in the "Restore", "Build", and "Test" tasks with the parameters you just created. 78 | 79 | - **Replace projects**: `**/*.sln` with projects: `${{ parameters.dotNetProjects }}` in the `Restore` and `Build` tasks. 80 | - **Replace projects**: `tests/UnitTests/*.csproj` with projects: `${{ parameters.testProjects }}` in the `Test` task 81 | 82 | The "Restore", "Build", and "Test" tasks in the steps section of the YAML file should look like this: 83 | 84 | ```yaml 85 | steps: 86 | - task: DotNetCoreCLI@2 87 | displayName: Restore 88 | inputs: 89 | command: 'restore' 90 | projects: ${{ parameters.dotNetProjects }} 91 | feedsToUse: 'select' 92 | 93 | - task: DotNetCoreCLI@2 94 | displayName: Build 95 | inputs: 96 | command: 'build' 97 | projects: ${{ parameters.dotNetProjects }} 98 | 99 | - task: DotNetCoreCLI@2 100 | displayName: Test 101 | inputs: 102 | command: 'test' 103 | projects: ${{ parameters.testProjects }} 104 | 105 | ``` 106 | 107 | 1. Click on **Validate and save** to save the changes, then click on **Save**. 108 | 109 | 1. Navigate to **Pipelines > Pipelines** and open the **eshoponweb-ci** pipeline that is running triggered automatically. 110 | 111 | 1. Verify that the pipeline run completes successfully. 112 | 113 | ![Screenshot of the pipeline run with parameters.](media/pipeline-parameters-run.png) 114 | 115 | #### Task 3: Securing variables and parameters 116 | 117 | In this task, you will secure the variables and parameters from your pipeline by using variable groups. 118 | 119 | 1. Go to **Pipelines > Library**. 120 | 121 | 1. Select the **+ Variable group** button to create a new variable group named `BuildConfigurations`. 122 | 123 | 1. Add a variable named `buildConfiguration` and set its value to `Release`. 124 | 125 | 1. Save the variable group. 126 | 127 | ![Screenshot of the variable group with BuildConfigurations.](media/eshop-variable-group.png) 128 | 129 | 1. Select the **Pipeline permissions** button and select the **+** button to add a new pipeline. 130 | 131 | 1. Select the **eshoponweb-ci** pipeline to allow the pipeline to use the variable group. 132 | 133 | ![Screenshot of the pipeline permissions.](media/pipeline-permissions.png) 134 | 135 | > **Note**: You can also set specific users or groups to be able to edit the variable group by clicking on the **Security** button. 136 | 137 | 1. Go to **Pipelines > Pipelines**. 138 | 139 | 1. Open **eshoponweb-ci** pipeline and select **Edit**. 140 | 141 | 1. At the top of the yml file, right under the parameters, reference the variable group by adding the following: 142 | 143 | ```yaml 144 | variables: 145 | - group: BuildConfigurations 146 | ``` 147 | 148 | 1. In the "Build" task, add the configuration parameter to the task to utilize the build configuration from the variable group. 149 | 150 | ```yaml 151 | command: 'build' 152 | projects: ${{ parameters.dotNetProjects }} 153 | configuration: $(buildConfiguration) 154 | ``` 155 | 156 | 1. Click on **Validate and save** to save the changes, then click on **Save**. 157 | 158 | 1. Open the **eshoponweb-ci** pipeline run. It should run successfully with the build configuration set to "Release". You can verify this by looking at the logs of the "Build" task. 159 | 160 | > **Note**: If you don't see the build configuration set to "Release" in the logs, enable the system diagnostics and rerun the pipeline to see the configuration value. 161 | 162 | > **Note**: Following this approach, you can secure your variables and parameters by using variable groups without having to hardcode them in YAML files. 163 | 164 | #### Task 4: Validating mandatory variables and parameters 165 | 166 | In this task, you will validate the mandatory variables before the pipeline executes. 167 | 168 | 1. Go to **Pipelines > Pipelines**. 169 | 170 | 1. Open **eshoponweb-ci** pipeline and select **Edit**. 171 | 172 | 1. In the steps section, at its very beginning (following the **steps:** line), add a new script task to validate the mandatory variables before the pipeline executes. 173 | 174 | ```yaml 175 | - script: | 176 | IF NOT DEFINED buildConfiguration ( 177 | ECHO Error: buildConfiguration variable is not set 178 | EXIT /B 1 179 | ) 180 | displayName: 'Validate Variables' 181 | ``` 182 | 183 | > **Note**: This is a simple validation to check if the variable is set. If the variables not set, the script will fail and the pipeline will stop. You can add more complex validation to check the value of the variable or if it is set to a specific value. 184 | 185 | 1. Click on **Validate and save** to save the changes, then click on **Save**. 186 | 187 | 1. Open the **eshoponweb-ci** pipeline run. It will run successfully because the buildConfiguration variable is set in the variable group. 188 | 189 | 1. To test the validation, remove the buildConfiguration variable from the variable group, or rename the variable, and run the pipeline again. It should fail with the following error: 190 | 191 | ```yaml 192 | Error: buildConfiguration variable is not set 193 | ``` 194 | 195 | ![Screenshot of the pipeline run with validation failing.](media/pipeline-validation-fail.png) 196 | 197 | 1. Add the variable buildConfiguration variable back to the variable group and run the pipeline again. It should run successfully. 198 | 199 | > [!IMPORTANT] 200 | > Remember to delete the resources created in the Azure portal to avoid unnecessary charges. 201 | 202 | ## Review 203 | 204 | In this lab you learned how to configure pipelines to securely use variables and parameters, and how to validate mandatory variables and parameters. 205 | -------------------------------------------------------------------------------- /Instructions/Labs/APL2001_M05_L05_Extend_a_Pipeline_to_Use_Multiple_Templates.md: -------------------------------------------------------------------------------- 1 | --- 2 | lab: 3 | title: 'Extend a pipeline to use multiple templates' 4 | module: 'Module 5: Extend a pipeline to use multiple templates' 5 | --- 6 | 7 | # Extend a pipeline to use multiple templates 8 | 9 | In this lab, explore the importance of extending a pipeline to multiple templates and how to do it using Azure DevOps. This lab covers fundamental concepts and best practices for creating a multi-stage pipeline, creating a variables template, creating a job template, and creating a stage template. 10 | 11 | These exercises take approximately **20** minutes. 12 | 13 | ## Before you start 14 | 15 | You'll need an Azure subscription, Azure DevOps organization, and the eShopOnWeb application to follow the labs. 16 | 17 | - Follow the steps to [validate your lab environment](APL2001_M00_Validate_Lab_Environment.md). 18 | 19 | ## Instructions 20 | 21 | ### Exercise 1: Create a multi-stage YAML pipeline 22 | 23 | In this exercise, you will create a multi-stage YAML pipeline in Azure DevOps. 24 | 25 | #### Task 1: Create a multi-stage main YAML pipeline 26 | 27 | 1. Navigate to the Azure DevOps portal at `https://aex.dev.azure.com` and open your organization. 28 | 29 | 1. Open the **eShopOnWeb** project. 30 | 31 | 1. Go to **Pipelines > Pipelines**. 32 | 33 | 1. Click on the **New Pipeline** button. 34 | 35 | 1. Select **Azure Repos Git (Yaml)**. 36 | 37 | 1. Select the **eShopOnWeb** repository. 38 | 39 | 1. Select **Starter pipeline**. 40 | 41 | 1. Replace the content of the **azure-pipelines.yml** file with the following code: 42 | 43 | ```yaml 44 | trigger: 45 | - main 46 | 47 | pool: 48 | vmImage: 'windows-latest' 49 | 50 | stages: 51 | - stage: Dev 52 | jobs: 53 | - job: Build 54 | steps: 55 | - script: echo Build 56 | - stage: Test 57 | jobs: 58 | - job: Test 59 | steps: 60 | - script: echo Test 61 | - stage: Production 62 | jobs: 63 | - job: Deploy 64 | steps: 65 | - script: echo Deploy 66 | ``` 67 | 68 | 1. Select **Save and run**. Choose to commit directly to the main branch and select **Save and run** again. 69 | 70 | 1. You will see the pipeline running with the three stages (Dev, Test, and Production) and the corresponding jobs. Wait until the pipeline finishes and navigate back to the **Pipelines** page. 71 | 72 | ![Screenshot of the pipeline running with the three stages and the corresponding jobs](media/eshoponweb-pipeline-multi-stage.png) 73 | 74 | 1. Select **...** (More options) on the right side of the pipeline you just created and select **Rename/move**. 75 | 76 | 1. Rename the pipeline to **eShopOnWeb-MultiStage-Main** and select **Save**. 77 | 78 | #### Task 2: Create a variables template 79 | 80 | 1. Go to **Repos > Files**. 81 | 82 | 1. Expand the **.ado** folder and click on **New file**. 83 | 84 | 1. Name the file **eshoponweb-variables.yml** and click on **Create**. 85 | 86 | 1. Add the following code to the file: 87 | 88 | ```yaml 89 | variables: 90 | resource-group: 'YOUR-RESOURCE-GROUP-NAME' 91 | location: 'centralus' 92 | templateFile: 'infra/webapp.bicep' 93 | subscriptionid: 'YOUR-SUBSCRIPTION-ID' 94 | azureserviceconnection: 'YOUR-AZURE-SERVICE-CONNECTION-NAME' 95 | webappname: 'YOUR-WEB-APP-NAME' 96 | ``` 97 | 98 | 1. Replace the values of the variables with the values of your environment: 99 | 100 | - Replace **YOUR-RESOURCE-GROUP-NAME** with the name of the resource group you want to use in this lab, for example, **rg-eshoponweb-secure**. 101 | - Set the value of the **location** variable to the name of the Azure region you want to deploy your resources, for example, **centralus**. 102 | - Replace **YOUR-SUBSCRIPTION-ID** with your Azure subscription id. 103 | - Replace **YOUR-AZURE-SERVICE-CONNECTION-NAME** with **azure subs** 104 | - Replace **YOUR-WEB-APP-NAME** with a globally unique name of the web app to be deployed, for example, the string **eshoponweb-lab-multi-123456** followed by a random six-digit number. 105 | 106 | 1. Select **Commit**, in the commit comment text box, enter `[skip ci]`, and then select **Commit**. 107 | 108 | > **Note**: By adding the `[skip ci]` comment to the commit, you will prevent automatic pipeline execution, which, at this point, runs by default following every change to the repo. 109 | 110 | #### Task 3: Prepare the pipeline to use templates 111 | 112 | 1. In the Azure DevOps portal, on the **eShopOnWeb** project page, go to **Repos**. 113 | 114 | 1. In the root directory of the repo, select **azure-pipelines.yml** which contains the definition of the **eShopOnWeb-MultiStage-Main** pipeline. 115 | 116 | 1. Click on the **Edit** button. 117 | 118 | 1. Replace the content of the **azure-pipelines.yml** file with the following code: 119 | 120 | ```yaml 121 | trigger: 122 | - main 123 | variables: 124 | - template: .ado/eshoponweb-variables.yml 125 | 126 | stages: 127 | - stage: Dev 128 | jobs: 129 | - template: .ado/eshoponweb-ci.yml 130 | - stage: Test 131 | jobs: 132 | - template: .ado/eshoponweb-cd-webapp-code.yml 133 | - stage: Production 134 | jobs: 135 | - job: Deploy 136 | steps: 137 | - script: echo Deploy to Production or Swap 138 | ``` 139 | 140 | 1. Select **Commit**, in the commit comment text box, enter `[skip ci]`, and then select **Commit**. 141 | 142 | #### Task 4: Updating CI/CD templates 143 | 144 | 1. In the **Repos** of the **eShopOnWeb** project, select the **.ado** directory and select the **eshoponweb-ci.yml** file. 145 | 146 | 1. Click on the **Edit** button. 147 | 148 | 1. Remove everything above the **jobs** section. 149 | 150 | ```yaml 151 | #NAME THE PIPELINE SAME AS FILE (WITHOUT ".yml") 152 | # trigger: 153 | # - main 154 | 155 | resources: 156 | repositories: 157 | - repository: self 158 | trigger: none 159 | 160 | stages: 161 | - stage: Build 162 | displayName: Build .Net Core Solution 163 | ``` 164 | 165 | 1. Select **Commit**, in the commit comment text box, enter `[skip ci]`, and then select **Commit**. 166 | 167 | 1. In the **Repos** of the **eShopOnWeb** project, select the **.ado** directory and select the **eshoponweb-cd-webapp-code.yml** file. 168 | 169 | 1. Click on the **Edit** button. 170 | 171 | 1. Remove everything above the **jobs** section. 172 | 173 | ```yaml 174 | # NAME THE PIPELINE SAME AS FILE (WITHOUT ".yml") # 175 | # Trigger CD when CI executed successfully 176 | 177 | resources: 178 | pipelines: 179 | - pipeline: eshoponweb-ci 180 | source: eshoponweb-ci # given pipeline name 181 | trigger: true 182 | 183 | repositories: 184 | - repository: eShopSecurity 185 | type: git 186 | name: eShopSecurity/eShopSecurity # name of the project and repository 187 | 188 | variables: 189 | - template: eshoponweb-secure-variables.yml@eShopSecurity # name of the template and repository 190 | 191 | stages: 192 | - stage: Test 193 | displayName: Testing WebApp 194 | jobs: 195 | - deployment: Test 196 | pool: eShopOnWebSelfPool 197 | environment: Test 198 | strategy: 199 | runOnce: 200 | deploy: 201 | steps: 202 | - script: echo Hello world! Testing environments! 203 | 204 | - stage: Deploy 205 | displayName: Deploy to WebApp 206 | ``` 207 | 208 | 1. Replace the existing content of the **#download artifacts** step with: 209 | 210 | ```yaml 211 | - download: current 212 | artifact: Website 213 | - download: current 214 | artifact: Bicep 215 | ``` 216 | 217 | 1. Select **Commit**, in the commit comment text box, enter `[skip ci]`, and then select **Commit**. 218 | 219 | #### Task 5: Run the main pipeline 220 | 221 | 1. Go to **Pipelines > Pipelines**. 222 | 223 | 1. Open the **eShopOnWeb-MultiStage-Main** pipeline. 224 | 225 | 1. Select **Run pipeline**. 226 | 227 | > **Note**: If you receive a message that the pipeline needs permission to access a resource before this run can continue, select **View** and then select **Permit** and **Permit** again to allow the pipeline to run. 228 | 229 | > **Note**: If any jobs in the Deploy stage fail, navigate to the pipeline run page and select **Rerun failed jobs***. 230 | 231 | 1. Wait until the pipeline finishes and check the results. 232 | 233 | ![Screenshot of the pipeline running with the three stages and the corresponding jobs](media/multi-stage-completed.png) 234 | 235 | > [!IMPORTANT] 236 | > Remember to delete the resources created in the Azure portal to avoid unnecessary charges. 237 | 238 | ## Review 239 | 240 | In this lab, you learned how to extend a pipeline into multiple templates by using Azure DevOps. This lab covered fundamental concepts and best practices for creating a multi-stage pipeline, creating a variables template, a job template, and a stage template. 241 | -------------------------------------------------------------------------------- /Instructions/Labs/APL2001_M00_Validate_Lab_Environment.md: -------------------------------------------------------------------------------- 1 | --- 2 | lab: 3 | title: 'Validate your lab environment' 4 | module: 'Module 0: Welcome' 5 | --- 6 | 7 | # Validate your lab environment 8 | 9 | In preparation for the labs, it is crucial to have your environment correctly set up. This page will guide you through the setup process, ensuring all prerequisites are met. 10 | 11 | - The labs require **Microsoft Edge** or an [Azure DevOps-supported browser.](https://learn.microsoft.com/azure/devops/server/compatibility?view=azure-devops#web-portal-supported-browsers) 12 | 13 | - **Set up an Azure Subscription:** If you don't already have an Azure subscription, create one by following the instructions on this page or visit [https://azure.microsoft.com/free](https://azure.microsoft.com/free) to sign up for a free. 14 | 15 | - **Set up an Azure DevOps organization:** If you don't already have an Azure DevOps organization that you can use for the labs, create one by following the instructions on this page, or at [Create an organization or project collection](https://learn.microsoft.com/azure/devops/organizations/accounts/create-organization). 16 | 17 | - [Git for Windows download page](https://gitforwindows.org/). This will be installed as part of prerequisites for this lab. 18 | 19 | - [Visual Studio Code](https://code.visualstudio.com/). This will be installed as part of prerequisites for this lab. 20 | 21 | - [Azure CLI](https://learn.microsoft.com/cli/azure/install-azure-cli). Install the Azure CLI on the self-hosted agent machines. 22 | 23 | - [.NET SDK - Latest version](https://dotnet.microsoft.com/download/visual-studio-sdks). Install the .NET SDK on the self-hosted agent machines. 24 | 25 | ## Instructions to create an Azure DevOps Organization (you only have to do this once) 26 | 27 | > **Note**: Start at step 3, if you do already have a **personal Microsoft Account** setup and an active Azure Subscription linked to that account. 28 | 29 | 1. Use a private browser session to get a new **personal Microsoft Account (MSA)** at `https://account.microsoft.com`. 30 | 31 | 1. Using the same browser session, sign up for a free Azure subscription at `https://azure.microsoft.com/free`. 32 | 33 | 1. Open a browser and navigate to Azure portal at `https://portal.azure.com`, then search at the top of the Azure portal screen for **Azure DevOps**. In the resulting page, click **Azure DevOps organizations**. 34 | 35 | 1. Next, click on the link labelled **My Azure DevOps Organizations** or navigate directly to `https://aex.dev.azure.com`. 36 | 37 | 1. On the **We need a few more details** page, select **Continue**. 38 | 39 | 1. In the drop-down box on the left, choose **Default Directory**, instead of **Microsoft Account**. 40 | 41 | 1. If prompted (*"We need a few more details"*), provide your name, e-mail address, and location and click **Continue**. 42 | 43 | 1. Back at `https://aex.dev.azure.com` with **Default Directory** selected click the blue button **Create new organization**. 44 | 45 | 1. Accept the *Terms of Service* by clicking **Continue**. 46 | 47 | 1. If prompted (*"Almost done"*), leave the name for the Azure DevOps organization at default (it needs to be a globally unique name) and pick a hosting location close to you from the list. 48 | 49 | 1. Once the newly created organization opens in **Azure DevOps**, select **Organization settings** in the bottom left corner. 50 | 51 | 1. At the **Organization settings** screen select **Billing** (opening this screen takes a few seconds). 52 | 53 | 1. Select **Setup billing** and on the right-hand side of the screen, select your **Azure Subscription** and then select **Save** to link the subscription with the organization. 54 | 55 | 1. Once the screen shows the linked Azure Subscription ID at the top, change the number of **Paid parallel jobs** for **MS Hosted CI/CD** from 0 to **1**. Then select **SAVE** button at the bottom. 56 | 57 | > **Note**: You may **wait a couple of minutes before using the CI/CD capabilities** so that the new settings are reflected in the backend. Otherwise, you will still see the message *"No hosted parallelism has been purchased or granted"*. 58 | 59 | 1. In **Organization Settings**, go to section **Pipelines** and click **Settings**. 60 | 61 | 1. Toggle the switch to **Off** for **Disable creation of classic build pipelines** and **Disable creation of classic release pipelines** 62 | 63 | > **Note**: The **Disable creation of classic release pipelines** switch sets to **On** hides classic release pipeline creation options such as the **Release** menu in the **Pipeline** section of DevOps projects. 64 | 65 | 1. In **Organization Settings**, go to section **Security** and click **Policies**. 66 | 67 | 1. Toggle the switch to **On** for **Allow public projects** 68 | 69 | > **Note**: Extensions used in some labs might require a public project to allow using the free version. 70 | 71 | ## Instructions to create and configure the Azure DevOps project (you only have to do this once) 72 | 73 | > **Note**: make sure you completed the steps to create your Azure DevOps Organization before continuing with these steps. 74 | 75 | To follow all lab instructions, you'll need set up a new Azure DevOps project, create a repository that's based on the [eShopOnWeb](https://github.com/MicrosoftLearning/eShopOnWeb) application, and create a service connection to your Azure subscription. 76 | 77 | ### Create the team project 78 | 79 | First, you'll create an **eShopOnWeb** Azure DevOps project to be used by several labs. 80 | 81 | 1. Open your browser and navigate to your Azure DevOps organization. 82 | 83 | 1. Select the **New Project** option and use the following settings: 84 | - name: **eShopOnWeb** 85 | - visibility: **Private** 86 | - Advanced: Version Control: **Git** 87 | - Advanced: Work Item Process: **Scrum** 88 | 89 | 1. Select **Create**. 90 | 91 | ![Create Project](media/create-project.png) 92 | 93 | ### Import eShopOnWeb git repository 94 | 95 | Now, you'll import the eShopOnWeb into your git repository. 96 | 97 | 1. Open your browser and navigate to your Azure DevOps organization. 98 | 99 | 1. Open the previously created **eShopOnWeb** project. 100 | 101 | 1. Select the **Repos > Files**, **Import a Repository** and then select **Import**. 102 | 103 | 1. On the **Import a Git Repository** window, paste the following URL `https://github.com/MicrosoftLearning/eShopOnWeb` and select **Import**: 104 | 105 | ![Import Repository](media/import-repo.png) 106 | 107 | 1. The repository is organized the following way: 108 | 109 | - **.ado** folder contains Azure DevOps YAML pipelines. 110 | - **.devcontainer** folder container setup to develop using containers (either locally in VS Code or GitHub Codespaces). 111 | - **.azure** folder contains Bicep & ARM infrastructure as code templates. 112 | - **.github** folder container YAML GitHub workflow definitions. 113 | - **src** folder contains the .NET 8 website used on the lab scenarios. 114 | 115 | 1. Leave the web browser window open. 116 | 117 | 1. Go to **Repos > Branches**. 118 | 119 | 1. Hover on the **main** branch then click the ellipsis on the right of the column. 120 | 121 | 1. Click on **Set as default branch**. 122 | 123 | ### Create a service connection to access Azure resources 124 | 125 | Next, you will create a service connection in Azure DevOps which will allow you to deploy and access resources in your Azure subscription. 126 | 127 | 1. Start a web browser, navigate to the Azure DevOps portal with the **eShopOnWeb** project open and select **Project settings** in the bottom left corner of the portal. 128 | 129 | 1. Select the **Service connections** under Pipelines, and then select **Create service connection** button. 130 | 131 | ![Screenshot of the new service connection creation button.](media/new-service-connection.png) 132 | 133 | 1. On the **New service connection** blade, select **Azure Resource Manager** and **Next** (may need to scroll down). 134 | 135 | 1. Select **Workload Identity federation (automatic)** and **Next**. 136 | 137 | > **Note**: You can also use **Workload identity federation (manual)** if you prefer to manually configure the service connection. Follow the steps in the [Azure DevOps documentation](https://learn.microsoft.com/azure/devops/pipelines/library/connect-to-azure) to create the service connection manually. 138 | 139 | 1. Fill in the empty fields using the information: 140 | - **Subscription**: Select your Azure subscription. 141 | - **Resource group**: Select the resource group where you want to deploy resources. 142 | - **Service connection name**: Type **`azure subs`**. This name will be referenced in YAML pipelines to access your Azure subscription. 143 | 144 | 1. Make sure the **Grant access permission to all pipelines** option is unchecked and select **Save**. 145 | 146 | > **Note:** The **Grant access permission to all pipelines** option is not recommended for production environments. It is only used in this lab to simplify the configuration of the pipeline. 147 | 148 | > **Note**: If you see an error message indicating you don't have the necessary permissions to create a service connection, try again, or configure the service connection manually. 149 | 150 | You have now completed the necessary prerequisite steps to continue with the labs. 151 | -------------------------------------------------------------------------------- /Instructions/Labs/APL2001_M04_L04_Configure_and_Validate_Permissions.md: -------------------------------------------------------------------------------- 1 | --- 2 | lab: 3 | title: 'Configure and validate permissions' 4 | module: 'Module 4: Configure and validate permissions' 5 | --- 6 | 7 | # Configure and validate permissions 8 | 9 | In this lab, you'll set up a secure environment that adheres to the principle of least privilege, ensuring that members can access only the resources they need to perform their tasks and minimize potential security risks. This involves configuring and validating user and pipeline permissions and setting up approval and branch checks in Azure DevOps. 10 | 11 | These exercises take approximately **20** minutes. 12 | 13 | ## Before you start 14 | 15 | You'll need an Azure subscription, Azure DevOps organization, and the eShopOnWeb application to follow the labs. 16 | 17 | - Follow the steps to [validate your lab environment](APL2001_M00_Validate_Lab_Environment.md). 18 | - Install a self-hosted agent following the lab [Configure agents and agent pools for secure pipelines](APL2001_M02_L02_Configure_Agents_And_Agent_Pools_for_Secure_Pipelines.md) or the steps in [Install a self-hosted agent](https://learn.microsoft.com/azure/devops/pipelines/agents/windows-agent). 19 | 20 | ## Instructions 21 | 22 | ### Exercise 0: (skip if done) Import and run CI/CD Pipelines 23 | 24 | In this exercise, you will import and run the CI/CD pipelines in the Azure DevOps project. 25 | 26 | #### Task 1: (skip if done) Import and run the CI pipeline 27 | 28 | Let's start by importing the CI pipeline named [eshoponweb-ci.yml](https://github.com/MicrosoftLearning/eShopOnWeb/blob/main/.ado/eshoponweb-ci.yml). 29 | 30 | 1. Navigate to the Azure DevOps portal at `https://aex.dev.azure.com` and open your organization. 31 | 32 | 1. Open the **eShopOnWeb** project in Azure DevOps. 33 | 34 | 1. Go to **Pipelines > Pipelines**. 35 | 36 | 1. Select the **Create Pipeline** button. 37 | 38 | 1. Select **Azure Repos Git (Yaml)**. 39 | 40 | 1. Select the **eShopOnWeb** repository. 41 | 42 | 1. Select **Existing Azure Pipelines YAML File**. 43 | 44 | 1. Select the **/.ado/eshoponweb-ci.yml** file then click on **Continue**. 45 | 46 | 1. Select the **Run** button to run the pipeline. 47 | 48 | > **Note**: Your pipeline will take a name based on the project name. You will rename it to easier identify the pipeline. 49 | 50 | 1. Go to **Pipelines > Pipelines** and select the recently created pipeline. Select the ellipsis and then select **Rename/move** option. 51 | 52 | 1. Name it **eshoponweb-ci** and select **Save**. 53 | 54 | #### Task 2: (skip if done) Import and run the CD pipeline 55 | 56 | > **Note**: In this task, you will import and run the CD pipeline named [eshoponweb-cd-webapp-code.yml](https://github.com/MicrosoftLearning/eShopOnWeb/blob/main/.ado/eshoponweb-cd-webapp-code.yml). 57 | 58 | 1. Go to **Pipelines > Pipelines**. 59 | 60 | 1. Select **New pipeline** button. 61 | 62 | 1. Select **Azure Repos Git (Yaml)**. 63 | 64 | 1. Select the **eShopOnWeb** repository. 65 | 66 | 1. Select **Existing Azure Pipelines YAML File**. 67 | 68 | 1. Select the **/.ado/eshoponweb-cd-webapp-code.yml** file then select **Continue**. 69 | 70 | 1. In the YAML pipeline definition, set the variables section to: 71 | 72 | ```yaml 73 | variables: 74 | resource-group: 'YOUR-RESOURCE-GROUP-NAME' 75 | location: 'centralus' 76 | templateFile: 'infra/webapp.bicep' 77 | subscriptionid: 'YOUR-SUBSCRIPTION-ID' 78 | azureserviceconnection: 'YOUR-AZURE-SERVICE-CONNECTION-NAME' 79 | webappname: 'YOUR-WEB-APP-NAME' 80 | ``` 81 | 82 | 1. Replace the values of the variables with the values of your environment: 83 | 84 | - Replace **YOUR-RESOURCE-GROUP-NAME** with the name of the resource group you want to use in this lab, for example, **rg-eshoponweb-secure**. 85 | - Set the value of the **location** variable to the name of the Azure region you want to deploy your resources, for example, **centralus**. 86 | - Replace **YOUR-SUBSCRIPTION-ID** with your Azure subscription id. 87 | - Replace **YOUR-AZURE-SERVICE-CONNECTION-NAME** with **azure subs** 88 | - Replace **YOUR-WEB-APP-NAME** with a globally unique name of the web app to be deployed, for example, the string **eshoponweb-lab-multi-123456** followed by a random six-digit number. 89 | 90 | 1. Select **Save and Run** and choose to commit directly to the main branch. 91 | 92 | 1. Select **Save and Run** again. 93 | 94 | 1. Open the pipeline run. If you receive the message "This pipeline needs permission to access a resource before this run can continue to Deploy to WebApp", select **View**, **Permit** and **Permit** again. This is needed to allow the pipeline to create the Azure App Service resource. 95 | 96 | ![Screenshot of the permit access from the YAML pipeline.](media/pipeline-deploy-permit-resource.png) 97 | 98 | 1. The deployment may take a few minutes to complete, wait for the pipeline to execute. The pipeline is triggered following the completion of the CI pipeline and it includes the following tasks: 99 | 100 | - **AzureResourceManagerTemplateDeployment**: Deploys the Azure App Service web app using bicep template. 101 | - **AzureRmWebAppDeployment**: Publishes the Web site to the Azure App Service web app. 102 | 103 | > **Note**: In case the deployment fails, navigate to the pipeline run page and select **Rerun failed jobs** to invoke another pipeline run. 104 | 105 | > **Note**: Your pipeline will take a name based on the project name. Let's **rename** it for identifying the pipeline better. 106 | 107 | 1. Go to **Pipelines > Pipelines** and select the recently created pipeline. Select the ellipsis and then select **Rename/move** option. 108 | 109 | 1. Name it **eshoponweb-cd-webapp-code** and click on **Save**. 110 | 111 | ### Exercise 1: Configure and validate approval and branch checks 112 | 113 | In this exercise, you will configure and validate approval and branch checks for the CD pipeline. 114 | 115 | #### Task 1: Create an environment and add approvals and checks 116 | 117 | 1. In the Azure DevOps portal, from the **eShopOnWeb** project page, select **Pipelines > Environments**. 118 | 119 | 1. Select **Create environment**. 120 | 121 | 1. Name the environment **Test**, select **None** as the resource, and select **Create**. 122 | 123 | 1. In the **Test** environment, select the **Approvals and checks** tab. 124 | 125 | 1. Select **Approvals**. 126 | 127 | 1. In the **Approvers** text box, enter your user name. 128 | 129 | 1. If not enabled, check the box labeled "Allow approvers to approve their own runs." 130 | 131 | 1. Give the instructions **Approve the deployment to Test** and select **Create**. 132 | 133 | ![Screenshot of the environment approvals with instructions.](media/add-environment-approvals.png) 134 | 135 | 1. Click on **+ Add new** button, select **Branch control**, and then select **Next**. 136 | 137 | 1. In the **Allowed branches** field, leave the default and select **Create**. You can add more branches if you want. 138 | 139 | ![Screenshot of the environment branch control with the main branch.](media/add-environment-branch-control.png) 140 | 141 | 1. Create another environment named **Production** and perform the same steps to add approvals and branch control. To differentiate the environments, add the instructions **Approve the deployment to Production** and set the allowed branches to **refs/heads/main**. 142 | 143 | > **Note**: You could add more environments and configure approvals and branch control for them. Additionally, you could configure **Security** to add users or groups to the environment with such roles as *User*, *Creator* or *Reader*. 144 | 145 | #### Task 2: Configure the CD pipeline to use the new environment 146 | 147 | 1. In the Azure DevOps portal, from the **eShopOnWeb** project page, select **Pipelines > Pipelines**. 148 | 149 | 1. Open the **eshoponweb-cd-webapp-code** pipeline. 150 | 151 | 1. Select **Edit**. 152 | 153 | 1. Select the line above the **#download artifacts** comment, up to the **stages:** line in the pipeline YAML file and replace the content with the following code: 154 | 155 | ```yaml 156 | stages: 157 | - stage: Test 158 | displayName: Testing WebApp 159 | jobs: 160 | - deployment: Test 161 | pool: eShopOnWebSelfPool 162 | environment: Test 163 | strategy: 164 | runOnce: 165 | deploy: 166 | steps: 167 | - script: echo Hello world! Testing environments! 168 | - stage: Deploy 169 | displayName: Deploy to WebApp 170 | jobs: 171 | - deployment: Deploy 172 | pool: eShopOnWebSelfPool 173 | environment: Production 174 | strategy: 175 | runOnce: 176 | deploy: 177 | steps: 178 | - checkout: self 179 | ``` 180 | 181 | > **Note**: You will need to shift all the lines following the code above six spaces to the right to ensure that YAML indentation rules are satisfied. 182 | 183 | Your pipeline should look like this: 184 | 185 | ![Screenshot of the pipeline with the new deployment.](media/pipeline-add-yaml-deployment.png) 186 | 187 | > [!IMPORTANT] 188 | > Confirm that the **pool** name is the same as the one you created in the previous lab. 189 | 190 | 1. Click on **Validate and save**, choose to commit directly to the main branch, and then click on **Save**. 191 | 192 | 1. Your pipeline will trigger automatically. Open the pipeline run. 193 | 194 | > **Note**: If you receive a message "This pipeline needs permission to access a resource before this run can continue to Testing WebApp" select **View**, **Permit** and **Permit** again. 195 | 196 | 1. Open the **Testing WebApp** stage of the pipeline and note the message **1 approval needs your review before this run can continue to Testing WebApp**. Select **Review** and select **Approve**. 197 | 198 | ![Screenshot of the pipeline with the Test stage to be approved".](media/pipeline-test-environment-approve.png) 199 | 200 | 1. Wait for the pipeline to finish, open the pipeline log and check that the **Testing WebApp** stage was executed successfully. 201 | 202 | ![Screenshot of the pipeline log with the Testing WebApp stage executed successfully".](media/pipeline-test-environment-success.png) 203 | 204 | 1. Back to the pipeline and you will see the stage **Deploy to WebApp** waiting for approval. Select **Review** and **Approve** as you did before for the **Testing WebApp** stage. 205 | 206 | > **Note**: If you receive a message "This pipeline needs permission to access a resource before this run can continue to Deploy to WebApp" select **View**, **Permit** and **Permit** again. 207 | 208 | 1. Wait for the pipeline to finish and check that the **Deploy to WebApp** stage was executed successfully. 209 | 210 | ![Screenshot of the pipeline with the Deploy to WebApp stage to be approved".](media/pipeline-deploy-environment-success.png) 211 | 212 | > **Note**: You should be able to run the pipeline successfully with the approvals and branch checks in both environments, Test and Production. 213 | 214 | > [!IMPORTANT] 215 | > Remember to delete the resources created in the Azure portal to avoid unnecessary charges. 216 | 217 | ## Review 218 | 219 | In this lab, you have learned how to set up a secure environment that adheres to the principle of least privilege, ensuring that members can access only the resources they need to perform their tasks and minimize potential security risks. You configured and validated user and pipeline permissions and set up approval and branch checks in Azure DevOps. 220 | -------------------------------------------------------------------------------- /Instructions/Labs/APL2001_M06_L06_Integrate_Azure_Key_Vault_With_Azure_Pipelines.md: -------------------------------------------------------------------------------- 1 | --- 2 | lab: 3 | title: 'Integrate Azure Key Vault with Azure Pipelines' 4 | module: 'Module 6: Configure secure access to Azure Repos from pipelines' 5 | --- 6 | 7 | # Integrate Azure Key Vault with Azure Pipelines 8 | 9 | Azure Key Vault provides secure storage and management of sensitive data, such as keys, passwords, and certificates. Azure Key Vault includes support for hardware security modules and a range of encryption algorithms and key lengths. By using Azure Key Vault, you can minimize the possibility of disclosing sensitive data through source code, a common mistake developers make. Access to Azure Key Vault requires proper authentication and authorization, supporting fine-grained permissions to its content. 10 | 11 | In this lab, you will see how you can integrate Azure Key Vault with Azure Pipelines by using the following steps: 12 | 13 | - Create an Azure Key vault to store an ACR password as a secret. 14 | - Configure permissions to allow the service principal to read the secret. 15 | - Configure the pipeline to retrieve the password from the Azure Key vault and pass it on to subsequent tasks. 16 | 17 | These exercises take approximately **30** minutes. 18 | 19 | ## Before you start 20 | 21 | You'll need an Azure subscription, Azure DevOps organization, and the eShopOnWeb application to follow the labs. 22 | 23 | - Follow the steps to [validate your lab environment](APL2001_M00_Validate_Lab_Environment.md). 24 | 25 | In this lab, you will: 26 | 27 | - Deploy resources on your Azure subscription. 28 | - Obtain read access to Azure Key Vault secrets. 29 | 30 | ## Instructions 31 | 32 | ### Exercise 1: Setup CI pipeline to build eShopOnWeb container 33 | 34 | In this exercise, you'll setup a CI YAML pipeline for: 35 | 36 | - Creating an Azure Container Registry to store the container images 37 | - Using Docker Compose to build and push **eshoppublicapi** and **eshopwebmvc** container images. Only **eshopwebmvc** container will be deployed. 38 | 39 | #### Task 1: Setup and run CI pipeline 40 | 41 | In this task, you will import an existing CI YAML pipeline definition, modify it, and run it. The pipeline will create an Azure Container Registry (ACR) and build/publish the eShopOnWeb container images. 42 | 43 | 1. Navigate to the Azure DevOps portal at `https://aex.dev.azure.com` and open your organization. 44 | 45 | 1. Navigate to the Azure DevOps **eShopOnWeb** project. Go to **Pipelines > Pipelines** and select **New pipeline**. 46 | 47 | 1. On the **Where is your code?** page, select **Azure Repos Git (YAML)** and select the **eShopOnWeb** repository. 48 | 49 | 1. On the **Configure your pipeline** page, select **Existing Azure Pipelines YAML file**. Provide the following path **/.ado/eshoponweb-ci-dockercompose.yml** and select **Continue**. 50 | 51 | ![Screenshot of the Pipeline selection from the YAML file.](media/select-ci-container-compose.png) 52 | 53 | 1. In the YAML pipeline definition, in the variables section, perform the following actions: 54 | 55 | - Replace **AZ400-EWebShop-NAME** by **rg-eshoponweb-secure** 56 | - Set the value of the location variable to the name of an Azure region you've been using in the previous labs of this course (for example **centralus**) 57 | - Replace **YOUR-SUBSCRIPTION-ID** with your Azure subscription Id 58 | 59 | 1. Select **Save and Run** and choose to commit directly to the main branch. 60 | 61 | 1. Select **Save and Run** again. 62 | 63 | > **Note**: If you choose to create a new branch, you will need to create a pull request to merge the changes to the main branch. 64 | 65 | 1. Open the pipeline. If you see the message "This pipeline needs permission to access a resource before this run can continue to Create ACR for images", select **View**, **Permit** and **Permit** again. The pipeline will be run in a few minutes. 66 | 67 | ![Screenshot of the permit access from the YAML pipeline.](media/pipeline-permit-resource.png) 68 | 69 | 1. Wait for the pipeline run to complete. This might take a few minutes. The build definition consists of the following tasks: 70 | 71 | - **AzureResourceManagerTemplateDeployment** uses **bicep** to create an Azure Container registry. 72 | - **PowerShell** task take the bicep output (acr login server) and creates pipeline variable. 73 | - **DockerCompose** task builds and pushes the container images for eShopOnWeb to the Azure Container registry . 74 | 75 | 1. Your pipeline will by default have the name based on the project name. Rename it to **eshoponweb-ci-dockercompose** in order to identify the pipeline better. 76 | 77 | 1. Once the pipeline run completes, use the web browser to navigate to the Azure Portal, open the **rg-eshoponweb-secure** resource group, and select the entry representing the Azure Container Registry (ACR) deployed by the pipeline. 78 | 79 | > **Note**: In order to view repositories in the registry, you need to grant to your user account a role that provides such access. You will use for this purpose the AcrPull role. 80 | 81 | 1. On the Container registry page, select **Access control (IAM)**, select **+ Add** and, in the drop-down list, select **Add role assignment**. 82 | 83 | 1. On the **Role** tab of the **Add role assignment** page, select **AcrPull** and then select **Next**. 84 | 85 | 1. On the **Members** tab, click **+ Select members**, select your user account, click **Select**, and then select **Next**. 86 | 87 | 1. Select **Review + assign** and, once the assignment successfully completes, refresh the browser page. 88 | 89 | 1. Back on the Container registry page, in the vertical menu bar on the left, in the **Services** section, select **Repositories**. 90 | 91 | 1. Verify that the registry contains images **eshoppublicapi** and **eshopwebmvc**. You will only use **eshopwebmvc** in the deploy phase. 92 | 93 | ![Screenshot of the container images in ACR from the Azure Portal.](media/azure-container-registry.png) 94 | 95 | 1. On the **Settings**, select **Access Keys**, enable the **Admin user** checkbox, and copy the **username** and **Registry name** values, which will be used in the following task, as you will add it as a secret to Azure Key Vault. 96 | 97 | ![Screenshot of the ACR password from the Access Keys setting.](media/acr-password.png) 98 | 99 | 1. On the same page, record the value of **Registry name**. You will need it later in this lab. 100 | 101 | #### Task 2: Create an Azure Key Vault 102 | 103 | In this task, you will create an Azure Key vault by using the Azure portal. 104 | 105 | For this lab scenario, we will have an Azure Container Instance (ACI) that pull and runs a container image stored in Azure Container Registry (ACR). We intend to store the password for the ACR as a secret in the Azure Key vault. 106 | 107 | 1. In the Azure portal, in the **Search resources, services, and docs** text box, type **Key vaults** and press the **Enter** key. 108 | 109 | 1. Select **Key vaults** blade, click on **Create key vault**. 110 | 111 | 1. On the **Basics** tab of the **Create key vault** blade, specify the following settings and click on **Next**: 112 | 113 | | Setting | Value | 114 | | --- | --- | 115 | | Subscription | the name of the Azure subscription you are using in this lab | 116 | | Resource group | the resource group name **rg-eshoponweb-secure** | 117 | | Key vault name | any unique valid name, like **ewebshop-kv** | 118 | | Region | the same Azure region you chose earlier in this lab | 119 | | Pricing tier | **Standard** | 120 | | Days to retain deleted vaults | **7** | 121 | | Purge protection | **Disable purge protection** | 122 | 123 | 1. Click on **Next: Access configuration**. 124 | 125 | 1. Select **Vault access policy** in the **Permission model** section. 126 | 127 | 1. In the **Access Policies** section, select **+ Create** to setup a new policy. 128 | 129 | > **Note**: You need to secure access to your key vaults by allowing only authorized applications and users. To access the data from the vault, you will need to provide read (Get/List) permissions to the previously created service principal that you will be using for authentication in the pipeline. 130 | 131 | - On the **Permission** blade, check **Get** and **List** permissions below **Secret Permission**. Select **Next**. 132 | - On the **Principal** blade, search and select your user, select **Next** and **Next** again. 133 | - On the **Review + create** blade, select **Create** 134 | 135 | 1. Back on the **Create a Key Vault** blade, select **Review + Create > Create** 136 | 137 | > **Note**: Wait for the Azure Key vault to be provisioned. This should take less than 1 minute. 138 | 139 | 1. On the **Your deployment is complete** blade, select **Go to resource**. 140 | 141 | 1. On the Azure Key vault blade, in the vertical menu on the left side of the blade, in the **Objects** section, select **Secrets**. 142 | 143 | 1. On the **Secrets** blade, select **Generate/Import**. 144 | 145 | 1. On the **Create a secret** blade, specify the following settings and select **Create** (leave others with their default values): 146 | 147 | | Setting | Value | 148 | | --- | --- | 149 | | Upload options | **Manual** | 150 | | Name | **acr-secret** | 151 | | Value | ACR access password copied in previous task | 152 | 153 | 1. Wait for the secret to be created. 154 | 155 | #### Task 3: Create a Variable Group connected to Azure Key Vault 156 | 157 | In this task, you will create a Variable Group in Azure DevOps that will retrieve the ACR password secret from Key Vault using the Service Connection (Service Principal) 158 | 159 | 1. Navigate to the Azure DevOps portal at `https://aex.dev.azure.com` and open your organization. 160 | 161 | 1. Navigate to the Azure DevOps project **eShopOnWeb**. 162 | 163 | 1. In the vertical navigational pane of the Azure DevOps portal, select **Pipelines > Library**. Select **+ Variable Group**. 164 | 165 | 1. On the **New variable group** blade, specify the following settings: 166 | 167 | | Setting | Value | 168 | | --- | --- | 169 | | Variable Group Name | **eshopweb-vg** | 170 | | Link secrets from Azure key vault as variables | **enable** | 171 | | Azure subscription | **Available Azure service connection > azure subs** | 172 | | Key vault name | the name you assigned to the Azure Key vault in the previous task | 173 | 174 | 1. Click on the **Authorize** button. 175 | 176 | 1. Under **Variables**, select **+ Add** and select the **acr-secret** secret. Select **OK**. 177 | 178 | 1. Select **Save**. 179 | 180 | ![Screenshot of the variable group creation.](media/vg-create.png) 181 | 182 | #### Task 4: Setup CD pipeline to deploy container in Azure Container Instance(ACI) 183 | 184 | In this task, you will import a CD pipeline, customize it and run it for deploying the container image created before in an Azure Container Instance. 185 | 186 | 1. In the Azure DevOps portal displaying the **eShopOnWeb** project, select **Pipelines > Pipelines** and then select **New Pipeline**. 187 | 188 | 1. On the **Where is your code?** page, select **Azure Repos Git (YAML)** and then select the **eShopOnWeb** repository. 189 | 190 | 1. On the **Configure your pipeline** page, select **Existing Azure Pipelines YAML file**. Provide the path **/.ado/eshoponweb-cd-aci.yml** and select **Continue**. 191 | 192 | 1. In the YAML pipeline definition, in the variable section, perform the following actions: 193 | 194 | - Set the value of the location variable to the name of an Azure region you used earlier in this lab, for example **centralus**. 195 | - Replace **YOUR-SUBSCRIPTION-ID** with your Azure subscription Id 196 | - Replace **az400eshop-NAME** with a globally unique name of the Azure Container instance to be deployed, for example, the string **eshoponweb-lab-docker** followed by a random six-digit number. 197 | - Replace **YOUR-ACR** and **ACR-USERNAME** with your ACR registry name you recorded earlier in this lab. 198 | - Replace **AZ400-EWebShop-NAME** with the name of the resource group you created earlier in this lab (**rg-eshoponweb-secure**). 199 | 200 | 1. Select **Save and Run** and then select **Save and Run** again. 201 | 202 | 1. Open the pipeline and note the message "This pipeline needs permission to access 2 resources before this run can continue to Docker Compose to ACI". Select **View** and then select **Permit** twice (for each resource) to allow the pipeline to run. 203 | 204 | 1. Wait for the pipeline run to complete. This might take a few minutes. The build definition consists of a single task **AzureResourceManagerTemplateDeployment**, which deploys the Azure Container Instance (ACI) using a bicep template and provides the ACR login parameters to allow the ACI to download the previously created container image. 205 | 206 | 1. Your pipeline will take a name based on the project name. Rename it to **eshoponweb-cd-aci** in order to easier identify its purpose. 207 | 208 | > [!IMPORTANT] 209 | > Remember to delete the resources created in the Azure portal to avoid unnecessary charges. 210 | 211 | ## Review 212 | 213 | In this lab, you integrated Azure Key Vault with an Azure DevOps pipeline by using the following steps: 214 | 215 | - Provided access to Azure Key vault's secrets and Azure resources from Azure DevOps. 216 | - Ran two YAML pipelines imported from a Git repository. 217 | - Configured pipeline to retrieve the password from the Azure Key vault using a variable group and re-used it on subsequent tasks. 218 | -------------------------------------------------------------------------------- /Instructions/Labs/APL2001_M01_L01_Configure_a_Project_and_Repository_Structure_to_Support_Secure_Pipelines.md: -------------------------------------------------------------------------------- 1 | --- 2 | lab: 3 | title: 'Configure a project and repository structure to support secure pipelines' 4 | module: 'Module 1: Configure a project and repository structure to support secure pipelines' 5 | --- 6 | 7 | # Configure a project and repository structure to support secure pipelines 8 | 9 | In this lab, you will learn how to configure a project and repository structure in Azure DevOps to support secure pipelines. This lab covers best practices for organizing projects and repositories, assigning permissions, and managing secure files. 10 | 11 | These exercises take approximately **30** minutes. 12 | 13 | ## Before you start 14 | 15 | You'll need an Azure subscription, Azure DevOps organization, and the eShopOnWeb application to follow the labs. 16 | 17 | - Follow the steps to [validate your lab environment](APL2001_M00_Validate_Lab_Environment.md). 18 | 19 | ## Instructions 20 | 21 | ### Exercise 1: Configure a secure project structure 22 | 23 | In this exercise, you will configure a secure project structure by creating a new project and assigning it project permissions. Separating responsibilities and resources into different projects or repositories with specific permissions supports security. 24 | 25 | #### Task 1: Create a new team project 26 | 27 | 1. Navigate to the Azure DevOps portal at `https://aex.dev.azure.com` and open your organization. 28 | 29 | 1. Open your **organization settings** at the bottom left corner of the portal and then **Projects** under the General section. 30 | 31 | 1. Select the **New Project** option and use the following settings: 32 | 33 | - name: **eShopSecurity** 34 | - visibility: **Private** 35 | - Advanced: Version Control: **Git** 36 | - Advanced: Work Item Process: **Scrum** 37 | 38 | ![Screenshot of the new project dialog with the specified settings.](media/new-team-project.png) 39 | 40 | 1. Select **Create** to create the new project. 41 | 42 | 1. You can now switch between the different projects by clicking on the Azure DevOps icon in the upper left corner of the Azure DevOps portal. 43 | 44 | ![Screenshot of the Azure DevOps team projects eShopOnWeb and eShopSecurity.](media/azure-devops-projects.png) 45 | 46 | You can manage permissions and settings for each project separately by going to the Project settings menu and selecting the appropriate team project. If you have multiple users or teams working on different projects, you can also assign permissions to each project separately. 47 | 48 | #### Task 2: Create a new repository and assign project permissions 49 | 50 | 1. Select the organization name in the upper left corner of the Azure DevOps portal and select the new **eShopSecurity** project. 51 | 52 | 1. Select the **Repos** menu. 53 | 54 | 1. Select the **Initialize** button to initialize the new repository by adding the README.md file. 55 | 56 | 1. Open the **Project settings** menu in the lower left corner of the portal and select **Repositories** under the Repos section. 57 | 58 | 1. Select the new **eShopSecurity** repository and select the **Security** tab. 59 | 60 | > **Note**: Ensure that you select the Security tab in the specific repository only, and not for all repositories in the project. If you select all repositories, you may lose access to other repositories in the project. 61 | 62 | 1. Remove the Inherit permissions from parent by unchecking the **Inheritance** toggle button. 63 | 64 | 1. Select the **Contributors** group and select the **Deny** dropdown for all permissions except **Manage permissions** and **Read**. This will prevent all users from the Contributors group from accessing the repository. 65 | 66 | > **Note**: In a real world scenario, you will deny the manage permissions to the Contributors group as well. For this lab, we are allowing the Contributors group to manage permissions to allow you to complete the lab. 67 | 68 | 1. Select your user under Users and select the **Allow** button to allow all permissions. 69 | 70 | > **Note**: If you don't see your name in the **Users** section, enter your name in the **Search for users or groups** text box and select it in the list of results. 71 | 72 | ![Screenshot of the repository security settings with allow for read and deny for all other permissions.](media/repository-security.png) 73 | 74 | 1. Your changes will be saved automatically. 75 | 76 | Now only the user you assigned permissions and the administrators can access the repository. This is useful when you want to allow specific users to access the repository and run pipelines from the eShopOnWeb project. 77 | 78 | ### Exercise 2: Configure a pipeline and template structure to support secure pipelines 79 | 80 | #### Task 1: Import and run the CI pipeline 81 | 82 | Let's start by importing the CI pipeline named [eshoponweb-ci.yml](https://github.com/MicrosoftLearning/eShopOnWeb/blob/main/.ado/eshoponweb-ci.yml). 83 | 84 | 1. Navigate to the Azure DevOps portal at `https://aex.dev.azure.com` and open your organization. 85 | 86 | 1. Open the **eShopOnWeb** project in Azure DevOps. 87 | 88 | 1. Go to **Pipelines > Pipelines**. 89 | 90 | 1. Select the **Create Pipeline** button. 91 | 92 | 1. Select **Azure Repos Git (Yaml)**. 93 | 94 | 1. Select the **eShopOnWeb** repository. 95 | 96 | 1. Select **Existing Azure Pipelines YAML File**. 97 | 98 | 1. Select the **/.ado/eshoponweb-ci.yml** file then click on **Continue**. 99 | 100 | 1. Select the **Run** button to run the pipeline. 101 | 102 | > **Note**: Your pipeline will take a name based on the project name. You will rename it to easier identify the pipeline. 103 | 104 | 1. Go to **Pipelines > Pipelines** and select the recently created pipeline. Select the ellipsis and then select **Rename/move** option. 105 | 106 | 1. Name it **eshoponweb-ci** and select **Save**. 107 | 108 | #### Task 2: Import and run the CD pipeline 109 | 110 | > **Note**: In this task, you will import and run the CD pipeline named [eshoponweb-cd-webapp-code.yml](https://github.com/MicrosoftLearning/eShopOnWeb/blob/main/.ado/eshoponweb-cd-webapp-code.yml). 111 | 112 | 1. Go to **Pipelines > Pipelines**. 113 | 114 | 1. Select **New pipeline** button. 115 | 116 | 1. Select **Azure Repos Git (Yaml)**. 117 | 118 | 1. Select the **eShopOnWeb** repository. 119 | 120 | 1. Select **Existing Azure Pipelines YAML File**. 121 | 122 | 1. Select the **/.ado/eshoponweb-cd-webapp-code.yml** file then select **Continue**. 123 | 124 | 1. In the YAML pipeline definition, set the variables section to: 125 | 126 | ```yaml 127 | variables: 128 | resource-group: 'YOUR-RESOURCE-GROUP-NAME' 129 | location: 'centralus' 130 | templateFile: 'infra/webapp.bicep' 131 | subscriptionid: 'YOUR-SUBSCRIPTION-ID' 132 | azureserviceconnection: 'YOUR-AZURE-SERVICE-CONNECTION-NAME' 133 | webappname: 'YOUR-WEB-APP-NAME' 134 | ``` 135 | 136 | 1. Replace the values of the variables with the values of your environment: 137 | 138 | - Replace **YOUR-RESOURCE-GROUP-NAME** with the name of the resource group you want to use in this lab, for example, **rg-eshoponweb-secure**. 139 | - Set the value of the **location** variable to the name of the Azure region you want to deploy your resources, for example, **centralus**. 140 | - Replace **YOUR-SUBSCRIPTION-ID** with your Azure subscription id. 141 | - Replace **YOUR-AZURE-SERVICE-CONNECTION-NAME** with **azure subs** 142 | - Replace **YOUR-WEB-APP-NAME** with a globally unique name of the web app to be deployed, for example, the string **eshoponweb-lab-multi-123456** followed by a random six-digit number. 143 | 144 | 1. Select **Save and Run** and choose to commit directly to the main branch. 145 | 146 | 1. Select **Save and Run** again. 147 | 148 | 1. Open the pipeline run. If you receive the message "This pipeline needs permission to access a resource before this run can continue to Deploy to WebApp", select **View**, **Permit** and **Permit** again. This is needed to allow the pipeline to create the Azure App Service resource. 149 | 150 | ![Screenshot of the permit access from the YAML pipeline.](media/pipeline-deploy-permit-resource.png) 151 | 152 | 1. The deployment may take a few minutes to complete, wait for the pipeline to execute. The pipeline is triggered following the completion of the CI pipeline and it includes the following tasks: 153 | 154 | - **AzureResourceManagerTemplateDeployment**: Deploys the Azure App Service web app using bicep template. 155 | - **AzureRmWebAppDeployment**: Publishes the Web site to the Azure App Service web app. 156 | 157 | > **Note**: In case the deployment fails, navigate to the pipeline run page and select **Rerun failed jobs** to invoke another pipeline run. 158 | 159 | > **Note**: Your pipeline will take a name based on the project name. Let's **rename** it for identifying the pipeline better. 160 | 161 | 1. Go to **Pipelines > Pipelines** and select the recently created pipeline. Select the ellipsis and then select **Rename/move** option. 162 | 163 | 1. Name it **eshoponweb-cd-webapp-code** and click on **Save**. 164 | 165 | Now you should have two pipelines running in your eShopOnWeb project. 166 | 167 | ![Screenshot of the successful executed CI/CD pipelines.](media/pipeline-successful-executed.png) 168 | 169 | #### Task 3: Move the CD pipeline variables to a YAML template 170 | 171 | In this task, you will create a YAML template to store the variables used in the CD pipeline. This will allow you to reuse the template in other pipelines. 172 | 173 | 1. Go to **Repos** and then **Files**. 174 | 175 | 1. Expand the **.ado** folder and select **New file**. 176 | 177 | 1. Name the file **eshoponweb-secure-variables.yml** and select **Create**. 178 | 179 | 1. Add the variables section used in the CD pipeline to the new file. The file should look like the following: 180 | 181 | ```yaml 182 | variables: 183 | resource-group: 'rg-eshoponweb-secure' 184 | location: 'southcentralus' #the name of the Azure region you want to deploy your resources 185 | templateFile: 'infra/webapp.bicep' 186 | subscriptionid: 'YOUR-SUBSCRIPTION-ID' 187 | azureserviceconnection: 'azure subs' #the name of the service connection to your Azure subscription 188 | webappname: 'eshoponweb-lab-secure-XXXXXX' #the globally unique name of the web app 189 | ``` 190 | 191 | > **Important**: Replace the values of the variables with the values of your environment (resource group, location, subscription ID, Azure service connection, and web app name). 192 | 193 | 1. Select **Commit**, in the commit comment text box, enter `[skip ci]`, and then select **Commit**. 194 | 195 | > **Note**: By adding the `[skip ci]` comment to the commit, you will prevent automatic pipeline execution, which, at this point, runs by default following every change to the repo. 196 | 197 | 1. From the list of files in the repo, open the **eshoponweb-cd-webapp-code.yml** pipeline definition, and replace the variables section with the following: 198 | 199 | ```yaml 200 | variables: 201 | - template: eshoponweb-secure-variables.yml 202 | ``` 203 | 204 | 1. Select **Commit**, accept the default comment, and then select **Commit** to run the pipeline again. 205 | 206 | 1. Verify that the pipeline run completed successfully. 207 | 208 | Now you have a YAML template with the variables used in the CD pipeline. You can reuse this template in other pipelines in scenarios where you need to deploy the same resources. Also, your operations team can control the resource group and location where the resources are deployed and other information in your template values and you don't need to make any changes to your pipeline definition. 209 | 210 | #### Task 4: Move the YAML templates to a separate repository and project 211 | 212 | In this task, you will move the YAML templates to a separate repository and project. 213 | 214 | 1. In your eShopSecurity project, go to **Repos > Files**. 215 | 216 | 1. Create a new file named **eshoponweb-secure-variables.yml**. 217 | 218 | 1. Copy the content of the file **.ado/eshoponweb-secure-variables.yml** from the eShopOnWeb repository to the new file. 219 | 220 | 1. Commit the changes. 221 | 222 | 1. Open the **eshoponweb-cd-webapp-code.yml** pipeline definition in the eShopOnWeb repo. 223 | 224 | 1. Add the following to the resources section before the variables section in the pipeline definition: 225 | 226 | ```yaml 227 | repositories: 228 | - repository: eShopSecurity 229 | type: git 230 | name: eShopSecurity/eShopSecurity #name of the project and repository 231 | ``` 232 | 233 | 1. Replace the variables section with the following: 234 | 235 | ```yaml 236 | variables: 237 | - template: eshoponweb-secure-variables.yml@eShopSecurity #name of the template and repository 238 | ``` 239 | 240 | ![Screenshot of the pipeline definition with the new variables and resource sections.](media/pipeline-variables-resource-section.png) 241 | 242 | 1. Select **Commit**, accept the default comment, and then select **Commit** to run the pipeline again. 243 | 244 | 1. Navigate to the pipeline run and verify that the pipeline is using the YAML file from the eShopSecurity repository. 245 | 246 | ![Screenshot of the pipeline execution using the YAML template from the eShopSecurity repository.](media/pipeline-execution-using-template.png) 247 | 248 | Now you have the YAML file in a separate repository and project. You can reuse this file in other pipelines in scenarios where you need to deploy the same resources. Also, your operations team can control the resource group, location, security and where the resources are deployed and other information by modifying values in the YAML file and you don't need to make any changes to your pipeline definition. 249 | 250 | > [!IMPORTANT] 251 | > Remember to delete the resources created in the Azure portal to avoid unnecessary charges. 252 | 253 | ## Review 254 | 255 | In this lab, you learned how to configure and organize a secure project and repository structure in Azure DevOps. By managing permissions effectively, you can ensure that the right users have access to the resources they need while maintaining the security and integrity of your DevOps pipelines and processes. 256 | -------------------------------------------------------------------------------- /Instructions/Labs/APL2001_M03_L03_Managed_Identity_for_Projects_and_Pipelines.md: -------------------------------------------------------------------------------- 1 | --- 2 | lab: 3 | title: 'Managed identity for projects and pipelines' 4 | module: 'Module 3: Manage identity for projects, pipelines, and agents' 5 | --- 6 | 7 | # Managed identity for projects and pipelines 8 | 9 | Managed identities offer a secure method for controlling access to Azure resources. Azure handles these identities automatically, allowing you to verify access to services compatible with Azure AD authentication. This means you won't need to embed credentials into your code, enhancing security. In Azure DevOps, managed identities can authenticate Azure resources within your self-hosted agents, simplifying access control without compromising security. 10 | 11 | In this lab, you'll create a managed identity and use it in Azure DevOps YAML pipelines running on self-hosted agents to deploy Azure resources. 12 | 13 | The lab takes approximately **30** minutes. 14 | 15 | ## Before you start 16 | 17 | You'll need an Azure subscription, Azure DevOps organization, and the eShopOnWeb application to follow the labs. 18 | 19 | - Verify that you have a Microsoft account or a Microsoft Entra account with the Contributor or the Owner role in the Azure subscription. For details, refer to [List Azure role assignments using the Azure portal](https://learn.microsoft.com/azure/role-based-access-control/role-assignments-list-portal) and [View and assign administrator roles in Azure Active Directory](https://learn.microsoft.com/azure/active-directory/roles/manage-roles-portal). 20 | 21 | ## Prerequisites 22 | 23 | Complete the labs: 24 | 25 | - Follow the steps to [validate your lab environment](APL2001_M00_Validate_Lab_Environment.md). 26 | - [Configure a project and repository structure to support secure pipelines](APL2001_M01_L01_Configure_a_Project_and_Repository_Structure_to_Support_Secure_Pipelines.md) 27 | - [Configure agents and agent pools for secure pipelines](APL2001_M02_L02_Configure_Agents_And_Agent_Pools_for_Secure_Pipelines.md) 28 | 29 | ## Instructions 30 | 31 | ### Exercise 0: (skip if done) Import and run CI/CD Pipelines 32 | 33 | In this exercise, you will import and run the CI/CD pipelines in the Azure DevOps project. 34 | 35 | #### Task 1: (skip if done) Import and run the CI pipeline 36 | 37 | Let's start by importing the CI pipeline named [eshoponweb-ci.yml](https://github.com/MicrosoftLearning/eShopOnWeb/blob/main/.ado/eshoponweb-ci.yml). 38 | 39 | 1. Navigate to the Azure DevOps portal at `https://aex.dev.azure.com` and open your organization. 40 | 41 | 1. Open the **eShopOnWeb** project in Azure DevOps. 42 | 43 | 1. Go to **Pipelines > Pipelines**. 44 | 45 | 1. Select the **Create Pipeline** button. 46 | 47 | 1. Select **Azure Repos Git (Yaml)**. 48 | 49 | 1. Select the **eShopOnWeb** repository. 50 | 51 | 1. Select **Existing Azure Pipelines YAML File**. 52 | 53 | 1. Select the **/.ado/eshoponweb-ci.yml** file then click on **Continue**. 54 | 55 | 1. Select the **Run** button to run the pipeline. 56 | 57 | > **Note**: Your pipeline will take a name based on the project name. You will rename it to easier identify the pipeline. 58 | 59 | 1. Go to **Pipelines > Pipelines** and select the recently created pipeline. Select the ellipsis and then select **Rename/move** option. 60 | 61 | 1. Name it **eshoponweb-ci** and select **Save**. 62 | 63 | #### Task 2: (skip if done) Import and run the CD pipeline 64 | 65 | > **Note**: In this task, you will import and run the CD pipeline named [eshoponweb-cd-webapp-code.yml](https://github.com/MicrosoftLearning/eShopOnWeb/blob/main/.ado/eshoponweb-cd-webapp-code.yml). 66 | 67 | 1. Go to **Pipelines > Pipelines**. 68 | 69 | 1. Select **New pipeline** button. 70 | 71 | 1. Select **Azure Repos Git (Yaml)**. 72 | 73 | 1. Select the **eShopOnWeb** repository. 74 | 75 | 1. Select **Existing Azure Pipelines YAML File**. 76 | 77 | 1. Select the **/.ado/eshoponweb-cd-webapp-code.yml** file then select **Continue**. 78 | 79 | 1. In the YAML pipeline definition, set the variables section to: 80 | 81 | ```yaml 82 | variables: 83 | resource-group: 'YOUR-RESOURCE-GROUP-NAME' 84 | location: 'centralus' 85 | templateFile: 'infra/webapp.bicep' 86 | subscriptionid: 'YOUR-SUBSCRIPTION-ID' 87 | azureserviceconnection: 'YOUR-AZURE-SERVICE-CONNECTION-NAME' 88 | webappname: 'YOUR-WEB-APP-NAME' 89 | ``` 90 | 91 | 1. Replace the values of the variables with the values of your environment: 92 | 93 | - Replace **YOUR-RESOURCE-GROUP-NAME** with the name of the resource group you want to use in this lab, for example, **rg-eshoponweb-secure**. 94 | - Set the value of the **location** variable to the name of the Azure region you want to deploy your resources, for example, **centralus**. 95 | - Replace **YOUR-SUBSCRIPTION-ID** with your Azure subscription id. 96 | - Replace **YOUR-AZURE-SERVICE-CONNECTION-NAME** with **azure subs** 97 | - Replace **YOUR-WEB-APP-NAME** with a globally unique name of the web app to be deployed, for example, the string **eshoponweb-lab-multi-123456** followed by a random six-digit number. 98 | 99 | 1. Select **Save and Run** and choose to commit directly to the main branch. 100 | 101 | 1. Select **Save and Run** again. 102 | 103 | 1. Open the pipeline run. If you receive the message "This pipeline needs permission to access a resource before this run can continue to Deploy to WebApp", select **View**, **Permit** and **Permit** again. This is needed to allow the pipeline to create the Azure App Service resource. 104 | 105 | ![Screenshot of the permit access from the YAML pipeline.](media/pipeline-deploy-permit-resource.png) 106 | 107 | 1. The deployment may take a few minutes to complete, wait for the pipeline to execute. The pipeline is triggered following the completion of the CI pipeline and it includes the following tasks: 108 | 109 | - **AzureResourceManagerTemplateDeployment**: Deploys the Azure App Service web app using bicep template. 110 | - **AzureRmWebAppDeployment**: Publishes the Web site to the Azure App Service web app. 111 | 112 | > **Note**: In case the deployment fails, navigate to the pipeline run page and select **Rerun failed jobs** to invoke another pipeline run. 113 | 114 | > **Note**: Your pipeline will take a name based on the project name. Let's **rename** it for identifying the pipeline better. 115 | 116 | 1. Go to **Pipelines > Pipelines** and select the recently created pipeline. Select the ellipsis and then select **Rename/move** option. 117 | 118 | 1. Name it **eshoponweb-cd-webapp-code** and click on **Save**. 119 | 120 | ### Exercise 1: Configure managed identity in Azure pipelines 121 | 122 | In this exercise, you will use a managed identity to configure a new service connection and incorporate it the CI/CD pipelines. 123 | 124 | #### Task 1: Set the managed identity in the Azure subscription 125 | 126 | 1. In your browser, open the Azure Portal at `https://portal.azure.com`. 127 | 128 | 1. In the Azure portal, navigate to the page displaying the Azure VM **eshoponweb-vm** you deployed in the [previous lab](APL2001_M02_L02_Configure_Agents_And_Agent_Pools_for_Secure_Pipelines.md). 129 | 130 | 1. On the **eshoponweb-vm** Azure VM page, in the toolbar, select **Start** to start it, in case it is stopped. 131 | 132 | 1. On the **eshoponweb-vm** Azure VM page, in the vertical menu on the left side, in the **Security** section, select **Identity**. 133 | 134 | 1. On the **Identity** page, verify that the **Status** is to **On** and select **Azure role assignments**. 135 | 136 | 1. Select the **Add role assignment** button, and perform the following actions: 137 | 138 | | Setting | Action | 139 | | -- | -- | 140 | | **Scope** drop-down list | Select **Subscription**. | 141 | | **Subscription** drop-down list | Select your Azure subscription. | 142 | | **Role** drop-down list | Select the **Contributor** role. | 143 | 144 | > **Note**: The subscription scope is necessary to accommodate deployments in the subsequent labs. 145 | 146 | 1. Select the **Save** button. 147 | 148 | ![Screenshot of the add role assignment pane.](media/add-role-assignment.png) 149 | 150 | #### Task 2: Create a managed identity-based service connection 151 | 152 | 1. Switch to the web browser displaying the **eShopOnWeb** project in the Azure DevOps portal at `https://aex.dev.azure.com`. 153 | 154 | 1. In the **eShopOnWeb** project, navigate to **Project settings > Service connections**. 155 | 156 | 1. Select the **New service connection** button and select **Azure Resource Manager**. 157 | 158 | 1. Select **Managed Identity (agent-assigned)** as the **Authentication method**. 159 | 160 | 1. Set the scope level to **Subscription** and provide the information from the Azure portal, including the **Subscription Id**, **Subscription name**, and **Tenant Id**. 161 | 162 | > **Note**: You can find the **Subscription Id** in the Azure portal by navigating to the **Subscriptions** blade and selecting the subscription you are using. The **Tenant Id** can be found in the **Microsoft Entra ID** blade. 163 | 164 | 1. In **Service connection name** type **azure subs managed**. This name will be referenced in YAML pipelines when accessing your Azure subscription. 165 | 166 | 1. Select **Save**. 167 | 168 | #### Task 3: Update the CI pipeline to use the self-hosted agent pool 169 | 170 | In this task, you will update the CI pipeline to use the self-hosted agent pool. 171 | 172 | 1. Switch to the browser window displaying the **eShopOnWeb** project in the Azure DevOps portal. 173 | 174 | 1. On the **eShopOnWeb** project page, navigate to **Pipelines > Pipelines**. 175 | 176 | 1. Select the **eshoponweb-ci** pipeline and select **Edit**. 177 | 178 | 1. In the **jobs** subsection of the **stages** section, update the value of the **pool** property to reference the self-hosted agent pool **eShopOnWebSelfPool** you configured in this task, so it has the following format: 179 | 180 | ```yaml 181 | jobs: 182 | - job: Build 183 | pool: eShopOnWebSelfPool 184 | steps: 185 | - task: DotNetCoreCLI@2 186 | ``` 187 | 188 | 1. Select **Validate and save** and choose to commit directly to the main branch. 189 | 190 | 1. Select **Save** again. 191 | 192 | 1. Select to **Run** the pipeline, and then click on **Run** again. 193 | 194 | 1. Verify that the build job is running on the **eShopOnWebSelfAgent** agent and it completes successfully. 195 | 196 | > **Note**: If you see the message **The agent request is not running because all potential agents are running other requests. Current position in queue: 1**, you can wait for the agent to become available or you can stop the agent job that is running. It may be the CD pipeline that is running automatically. 197 | 198 | > **Note**: If you see the message "This pipeline needs permission to access a resource before this run can continue to Build .Net Core Solution" in the pipeline run page, select **View**, **Permit** and **Permit** again. This is needed to allow the pipeline to use the self-hosted agent pool. 199 | 200 | #### Task 4: Update the CD pipeline to use the self-hosted agent pool and the managed identity-based service connection 201 | 202 | In this task, you will update the CD pipeline to use the managed identity-based service connection and the self-hosted agent pool. 203 | 204 | 1. Switch to the browser window displaying the **eShopSecurity** project in the Azure DevOps portal. 205 | 206 | > **Note**: **eShopSecurity** is the name of the project you created in the [first lab](APL2001_M01_L01_Configure_a_Project_and_Repository_Structure_to_Support_Secure_Pipelines.md). 207 | 208 | 1. On the **eShopSecurity** project page, navigate to **Repos > Files**. 209 | 210 | 1. Select the **eshoponweb-secure-variables.yml** file and click on the **Edit** button. 211 | 212 | 1. In the variables section, update the **azureserviceconnection** variable to use the name of the service connection you created in the previous task, **azure subs managed**. 213 | 214 | ```yaml 215 | azureserviceconnection: 'azure subs managed' 216 | ``` 217 | 218 | 1. Click on the **Commit** button, and choose to commit directly to the main branch. 219 | 220 | 1. Click on the **Commit** button again. 221 | 222 | 1. Switch to the **eShopOnWeb** project. 223 | 224 | 1. On the **eShopOnWeb** project page, navigate to **Pipelines > Pipelines**. 225 | 226 | 1. Select the **eshoponweb-cd-webapp-code** pipeline and select **Edit**. 227 | 228 | 1. In the **jobs** subsection of the **stages** section, update the value of the **pool** property to reference the self-hosted agent pool you created in the previous lab, **eShopOnWebSelfPool**, so it has the following format: 229 | 230 | ```yaml 231 | jobs: 232 | - job: Deploy 233 | pool: eShopOnWebSelfPool 234 | steps: 235 | #download artifacts 236 | - download: eshoponweb-ci 237 | ``` 238 | 239 | 1. Click on the **Validate and save** button and choose to commit directly to the main branch. 240 | 241 | 1. Click on **Save** again. 242 | 243 | 1. Navigate to the **Pipelines > Pipelines** and select the **eshoponweb-cd-webapp-code** pipeline already running from the previous task. 244 | 245 | 1. Click on the pipeline run and **Cancel**. Click on the **Yes** button to confirm. 246 | 247 | > **Note**: You will run the pipeline enable system diagnostics to see the logs of the pipeline. 248 | 249 | 1. Click to **Run new** pipeline, check the "Enable system diagnostics" checkbox and click on the **Run** button. 250 | 251 | 1. Open the pipeline run. 252 | 253 | > **Note**: If you see the message "This pipeline needs permission to access 2 resources before this run can continue to Deploy to WebApp", select on **View**, **Permit** and **Permit** again for all resources. This is needed to allow the pipeline to use the service connection and the self-hosted agent pool. 254 | 255 | 1. The deployment may take a few minutes to complete, wait for the pipeline to execute. 256 | 257 | > [!IMPORTANT] 258 | > If the pipeline fails because of the AZ CLI error, you may need to restart your self-hosted agent and re-run the pipeline. 259 | > To restart the agent, in the Azure portal, navigate to the page displaying the Azure VM **eshoponweb-vm** you deployed in the previous lab, connect to the VM using the **Connect** button, and restart the Azure Pipelines Agent service name starting with vstsagent. Right-click on the agent service and select **Restart**. 260 | 261 | 1. You should see from the pipeline logs that the pipeline is using the managed identity. 262 | 263 | ![Screenshot of the pipeline logs using the Managed Identity.](media/pipeline-logs-managed-identity.png) 264 | 265 | > **Note**: After the pipeline finishes, you can use the Azure portal to verify the state of the App Service web app resources. 266 | 267 | > [!IMPORTANT] 268 | > Remember to delete the resources created in the Azure portal to avoid unnecessary charges. 269 | 270 | ## Review 271 | 272 | In this lab, you learned how to use a managed identity assigned to self-hosted agents in Azure DevOps YAML pipelines. 273 | -------------------------------------------------------------------------------- /Instructions/Labs/APL2001_M02_L02_Configure_Agents_And_Agent_Pools_for_Secure_Pipelines.md: -------------------------------------------------------------------------------- 1 | --- 2 | lab: 3 | title: Configure agents and agent pools for secure pipelines 4 | module: 'Module 2: Configure secure access to pipeline resources' 5 | --- 6 | 7 | # Configure agents and agent pools for secure pipelines 8 | 9 | In this lab, you will learn how to configure Azure DevOps agents and agent Pools and manage permissions for those pools. Azure DevOps Agent Pools provide the resources to run your build and release pipelines. 10 | 11 | These exercises take approximately **25** minutes. 12 | 13 | ## Before you start 14 | 15 | You'll need an Azure subscription, Azure DevOps organization, and the eShopOnWeb application to follow the labs. 16 | 17 | - Follow the steps to [validate your lab environment](APL2001_M00_Validate_Lab_Environment.md). 18 | 19 | ## Instructions 20 | 21 | You'll create agents and configure self-hosted agents using Windows. If you want to configure agents on Linux or MacOS, follow the instructions in the [Azure DevOps documentation](https://docs.microsoft.com/azure/devops/pipelines/agents/v2-linux). 22 | 23 | During the configuration, keep in mind the following: 24 | 25 | - **Maintain separate agents per project**: Each agent can only be tied to one pool. While sharing agent pools across projects can save on infrastructure costs, it also creates the risk of lateral movement. Therefore, it's best to have separate agent pools with dedicated agents for each project to prevent cross-contamination. 26 | - **Utilize low-privileged accounts for running agents**: Running an agent under an identity with direct access to Azure DevOps resources can pose security threats. Operating the agent under a non-privileged local account like Network Service is advisable, which minimizes the risk. 27 | - **Beware of misleading group names**: The "Project Collection Service Accounts" group in Azure DevOps is a potential security risk. Running agents using an identity that's part of this group and backed by Azure AD can jeopardize the security of your entire Azure DevOps organization. 28 | - **Avoid high-privileged accounts for self-hosted agents**: Using high-privileged accounts to run self-hosted agents, particularly for accessing secrets or production environments, can expose your system to severe threats if a pipeline is compromised. 29 | - **Prioritize security**: To safeguard your systems, use the least privileged account to run self-hosted agents. For instance, consider using your machine account or a managed service identity. It's also advisable to allow Azure Pipelines to handle access to secrets and environments. 30 | 31 | ### Exercise 1: Create agents and configure agent pools 32 | 33 | In this exercise, you will create an Azure virtual machine (VM) and use it to create an agent and configure agent pools. 34 | 35 | #### Task 1: Create and connect to an Azure VM 36 | 37 | 1. In your browser, open the Azure Portal at `https://portal.azure.com`. If prompted, sign in by using an account with the Owner role in your Azure subscription. 38 | 39 | 1. In the **Search resources, services and docs (G+/)** box, type **Virtual Machines** and select it from the dropdown list. 40 | 41 | 1. Select the **Create** button. 42 | 43 | 1. Select the **Azure virtual machine with preset configuration**. 44 | 45 | ![Screenshot of the create virtual machine with preset configuration.](media/create-virtual-machine-preset.png) 46 | 47 | 1. Select the **Dev/Test** as the workload environment and the **General purpose** as the workload type. 48 | 49 | 1. Select the **Continue to create a VM** button, on the **Basics** tab perform the following actions and then select **Management**: 50 | 51 | | Setting | Action | 52 | | -- | -- | 53 | | **Subscription** drop-down list | Select your Azure subscription. | 54 | | **Resource group** section | Create a new resource group named **rg-eshoponweb-agentpool**. | 55 | | **Virtual machine name** text box | Enter name of your preference, for example, **eshoponweb-vm**. | 56 | | **Region** drop-down list | You can choose your closest [azure](https://azure.microsoft.com/explore/global-infrastructure/geographies) region. For example, “eastus”, “eastasia”, “westus”, etc. | 57 | | **Availability options** drop-down list | Select **No infrastructure redundancy required**. | 58 | | **Security type** drop-down list | Select with the **Trusted launch virtual machines** option. | 59 | | **Image** drop-down list | Select the **Windows Server 2022 Datacenter: Azure Edition - x64 Gen2** image. | 60 | | **Size** drop-down list | Select the cheapest **Standard** size for testing purposes. | 61 | | **Username** text box | Enter the username of your preference | 62 | | **Password** text box | Enter the password of your preference | 63 | | **Public inbound ports** section | Select **Allow selected ports**. | 64 | | **Select inbound ports** drop-down list | Select **RDP (3389)**. | 65 | 66 | 1. On the **Management** tab, in the **Identity** section, select the **Enable system assigned managed identity** checkbox and then select **Review + create**: 67 | 68 | 1. On the **Review + create** tab, select **Create**. 69 | 70 | > **Note**: Wait for the provisioning process to complete. This should take about 2 minutes. 71 | 72 | 1. In the Azure portal, navigate to the page displaying configuration of the newly created Azure VM. 73 | 74 | 1. On the Azure VM page, select **Connect**, in the drop-down menu, select **Connect**, then select **Download RDP file**. 75 | 76 | 1. Use the downloaded RDP file to establish a Remote Desktop session to the operating system running in the Azure VM. 77 | 78 | #### Task 2: Create an agent pool 79 | 80 | 1. In the Remote Desktop session to the Azure VM, start Microsoft Edge web browser. 81 | 82 | 1. In the web browser, navigate to the Azure DevOps portal at `https://aex.dev.azure.com` and sign in to access your organization. 83 | 84 | > **Note**: If it is your first time accessing the Azure DevOps portal, you may need to create your profile. 85 | 86 | 1. Open the **eShopOnWeb** project, and select **Project settings** from the left-side bottom menu. 87 | 88 | 1. From **Pipelines > Agent Pools**, select the **Add pool** button. 89 | 90 | 1. Choose the **Self-hosted** pool type. 91 | 92 | 1. Provide a name for the agent pool, such as **eShopOnWebSelfPool**, and add an optional description. 93 | 94 | 1. Leave the **Grant access permission to all pipelines** option unchecked. 95 | 96 | ![Screenshot showing add agent pool options with self-hosted type.](media/create-new-agent-pool-self-hosted-agent.png) 97 | 98 | > **Note**: Granting access permission to all pipelines is not recommended for production environments. It is only used in this lab to simplify the configuration of the pipeline. 99 | 100 | 1. Select **Create** button to create the agent pool. 101 | 102 | #### Task 3: Download and extract the agent installation files 103 | 104 | 1. In the Azure DevOps portal, select the newly created agent pool and then select the **Agents** tab. 105 | 106 | 1. Select the **New agent** button and then **Download** button from the **Download agent** in the new pop-up window. 107 | 108 | > **Note**: Follow the installation instructions to install the agent and make note of the downloaded version in the file name (ex: vsts-agent-win-x64-3.246.0.zip) 109 | 110 | 1. Start a PowerShell session and run the following commands to create a folder named **agent**. 111 | 112 | ```powershell 113 | mkdir agent ; cd agent 114 | ``` 115 | 116 | > **Note**: Make sure you are in the folder where you want to install the agent, for example, C:\agent. 117 | 118 | 1. Run the following command to extract the content of the downloaded agent installer files: 119 | 120 | ```powershell 121 | Add-Type -AssemblyName System.IO.Compression.FileSystem ; [System.IO.Compression.ZipFile]::ExtractToDirectory("$HOME\Downloads\vsts-agent-win-x64-3.246.0.zip", "$PWD") 122 | ``` 123 | 124 | > **Note**: If you downloaded the agent to a different location (or the downloaded version differs), adjust the above command accordingly. 125 | 126 | #### Task 4: Create a PAT token 127 | 128 | > **Note**: Before configuring the agent, you need to create a PAT token (unless you have an existing one). To create a PAT token, follow the steps below: 129 | 130 | 1. Within the Remote Desktop session to the Azure VM, open another browser window, navigate to the Azure DevOps portal at `https://aex.dev.azure.com`, and access your organization and project. 131 | 132 | 1. Select **User settings** from the right-side top menu (directly to the left of your user's avatar icon). 133 | 134 | 1. Select the **Personal access tokens** menu item. 135 | 136 | ![Screenshot showing the personal access tokens menu.](media/personal-access-token-menu.png) 137 | 138 | 1. Select the **New Token** button. 139 | 140 | 1. Provide a name for the token, such as **eShopOnWebToken**. 141 | 142 | 1. Select the Azure DevOps organization for you want to use the token. 143 | 144 | 1. Set the expiration date for the token (only used to configure the agent). 145 | 146 | 1. Select the custom defined scope. 147 | 148 | 1. Select to show all scopes. 149 | 150 | 1. Select the **Agent Pools (Read & Manage)** scope. 151 | 152 | 1. Select the **Create** button to create the token. 153 | 154 | 1. Copy the token value and save it in a safe place (you will not be able to see it again. You can only regenerate the token). 155 | 156 | ![Screenshot showing the personal access token configuration.](media/personal-access-token-configuration.png) 157 | 158 | > [!IMPORTANT] 159 | > Use the least privilege option, **Agent Pools (Read & Manage)**, only for the agent configuration. Also, make sure you set the minimum expiration date for the token if that is the only purpose of the token. You can create another token with the same privileges if you need to configure the agent again. 160 | 161 | #### Task 5: Configure the agent 162 | 163 | 1. Within the Remote Desktop session to the Azure VM, switch back to the PowerShell window. If necessary, change the current directory to the one into which you extracted the agent installation files earlier in this exercise. 164 | 165 | 1. To configure your agent to run unattended, invoke the following command: 166 | 167 | ```powershell 168 | .\config.cmd 169 | ``` 170 | 171 | > **Note**: If you want to run the agent interactively, use `.\run.cmd` instead. 172 | 173 | 1. To configure the agent, perform the following actions when prompted: 174 | 175 | - Enter the URL of the Azure DevOps organization (**server URL**) in the format `https://aex.dev.azure.com`{your organization name}. 176 | - Accept the default authentication type (**PAT**). 177 | - Enter the value of the PAT token you created in the previous step. 178 | - Enter the agent pool name **`eShopOnWebSelfPool`** you created earlier in this exercise. 179 | - Enter the agent name **`eShopOnWebSelfAgent`**. 180 | - Accept the default agent work folder (_work). 181 | - Enter **Y** to configure the agent to run as service. 182 | - Enter **Y** to enable SERVICE_SID_TYPE_UNRESTRICTED for the agent service. 183 | - Enter **NT AUTHORITY\SYSTEM** to set the security context for the service. 184 | 185 | > [!IMPORTANT] 186 | > In general, you should follow the principle of least privilege when configuring the service security context. 187 | 188 | - Accept the default option (**N**) to allow the service to start immediately after configuration is finished. 189 | 190 | ![Screenshot showing the agent configuration.](media/agent-configuration.png) 191 | 192 | > **Note**: The agent configuration process will take a few minutes to complete. Once it is done, you will see a message indicating that the agent is running as a service. 193 | 194 | > [!IMPORTANT] If you see an error message indicating that the agent is not running, you may need to start the service manually. To do this, open the **Services** applet in the Windows Control Panel, locate the service named **Azure DevOps Agent (eShopOnWebSelfAgent)**, and start it. 195 | 196 | > [!IMPORTANT] If your agent fails to start, you may need to choose a different folder for the agent work directory. To do this, re-run the agent configuration script and choose a different folder. 197 | 198 | 1. Check the agent status by switching to the web browser displaying the Azure DevOps portal, navigating to the agent pool and clicking on the **Agents** tab. You should see the new agent in the list. 199 | 200 | ![Screenshot showing the agent status.](media/agent-status.png) 201 | 202 | > **Note**: For more details on Windows agents, see: [Self-hosted Windows agents](https://learn.microsoft.com/azure/devops/pipelines/agents/windows-agent) 203 | 204 | > [!IMPORTANT] 205 | > In order for the agent to be able to build and deploy Azure resources from the Azure DevOps pipelines (which you will step through in the upcoming labs), you need to install Azure CLI within the operating system of the Azure VM that is hosting the agent. 206 | 207 | 1. Start a web browser and navigate to the page [Install Azure CLI on Windows](https://learn.microsoft.com/cli/azure/install-azure-cli-windows?tabs=azure-cli#install-or-update). 208 | 209 | 1. Download and install Azure CLI. 210 | 211 | 1. (Optional) If you prefer, run the following PowerShell command to install Azure CLI: 212 | 213 | ```powershell 214 | $ProgressPreference = 'SilentlyContinue'; Invoke-WebRequest -Uri https://aka.ms/installazurecliwindows -OutFile .\AzureCLI.msi; Start-Process msiexec.exe -Wait -ArgumentList '/I AzureCLI.msi /quiet'; Remove-Item .\AzureCLI.msi 215 | ``` 216 | 217 | > **Note**: If you are using a different version of the Azure CLI, you may need to adjust the above command accordingly. 218 | 219 | 1. In the web browser navigate to the page Microsoft .NET 8.0 SDK installer page at `https://dotnet.microsoft.com/en-us/download/dotnet/thank-you/sdk-8.0.403-windows-x64-installer`. 220 | 221 | > [!IMPORTANT] 222 | > You need to install the .NET 8.0 SDK (or higher) on the Azure VM that is hosting the agent. This is required to build the eShopOnWeb application in the upcoming labs. Any other tools or SDKs required for the application build should also be installed on the Azure VM. 223 | 224 | 1. Download and install Microsoft .NET 8.0 SDK. 225 | 226 | ### Exercise 2: Create and configure agent pool security 227 | 228 | In this exercise, you will configure security for the agent pool. 229 | 230 | #### Task 1: Create a new security group 231 | 232 | 1. Within the Remote Desktop session to the Azure VM, in the web browser displaying the Azure DevOps portal, in the **Project settings** pane, in the **General** section, select **Permissions**. 233 | 234 | 1. Select the **New Group** button. 235 | 236 | 1. Provide a name for the group, such as **eShopOnWeb Security Group**. 237 | 238 | 1. Select the **Create** button to create the group. 239 | 240 | ![Screenshot showing the security group creation.](media/create-security-group.png) 241 | 242 | #### Task 2: Configure the security group 243 | 244 | 1. In the web browser window displaying the Azure Devops portal, select the new group to display its **Permissions** tab. 245 | 246 | 1. Deny unnecessary permissions for the group, such as **Rename team project**, **Permanently delete work items**, or any other permissions you don't want the group to have since we assume it will be used only for the agent pool. 247 | 248 | ![Screenshot showing the security group settings.](media/security-group-settings.png) 249 | 250 | > [!IMPORTANT] 251 | > If you leave permissions you don't want the group to have, scripts or tasks running on the agent can use the group permissions to perform actions you don't want them to perform. 252 | 253 | #### Task 3: Manage agent pool permissions 254 | 255 | In this task, you will manage permissions for the agent pool. 256 | 257 | 1. In the web browser window displaying the Azure Devops portal, in the **Project settings** of the **eShopOnWeb** project, in the **Pipelines** section, select **Agent pools**. 258 | 259 | 1. Select the **eShopOnWebSelfPool** agent pool. 260 | 261 | 1. In the agent pool details view, select the **Security** tab. 262 | 263 | 1. Select the **Add** button and add the new group **eShopOnWeb Security Group** to the agent pool's user permissions. 264 | 265 | 1. Choose the appropriate role for the user or group, such as Agent Pool Reader, User or Administrator. In this case, choose **User**. 266 | 267 | 1. Select **Add** to apply the permissions. 268 | 269 | ![Screenshot showing the agent pool security configuration.](media/agent-pool-security.png) 270 | 271 | You are now ready to securely use the agent pool in your pipelines. You can use the new group to add users and manage permissions for the agent pool. You can reconfigure the installed self-hosted agent using the new group to ensure that the agent has the necessary permissions to run the pipelines and no more. For example, you can add a user to the group and configure the agent to run as that user. 272 | 273 | For more details on agent pools, see: [Agent pools](https://learn.microsoft.com/azure/devops/pipelines/agents/pools-queues). 274 | 275 | > [!IMPORTANT] 276 | > Remember to delete the resources created in the Azure portal to avoid unnecessary charges. 277 | 278 | ## Review 279 | 280 | In this lab, you learned how to configure Azure DevOps self-hosted agent and agent pools and manage permissions for those pools. By managing permissions effectively, you can ensure that the right users have access to the resources they need while maintaining the security and integrity of your DevOps processes. 281 | --------------------------------------------------------------------------------