Coder Social home page Coder Social logo

azure / devops-governance Goto Github PK

View Code? Open in Web Editor NEW
182.0 20.0 91.0 1.32 MB

Example end-to-end Governance Model from CI/CD to Azure Resource Manager. Use this project to deploy example AAD, ARM and Azure DevOps resources to learn about e2e RBAC.

License: MIT License

HCL 98.69% Makefile 1.31%
azure azure-devops infra-as-code rbac governance terraform azure-active-directory azure-keyvault azure-pipelines ci-cd

devops-governance's Introduction

Governance on Azure Demo - from DevOps to ARM

This demo project deploys Azure resources and bootstraps Azure DevOps projects to illustrate end-to-end RBAC, including best practices and pitfalls. It follows principles from Microsoft's Cloud Adoption Framework (CAF).

Status Description
CD - Build Status Deployment Azure Resources and Azure DevOps
Detect Drift - Build Status Detect Configuration Drift (scheduled nightly)

Contents

What is End to End Governance?

When developing a governance model for your organization, it is important to remember that Azure Resource Management (ARM) is only one way to manage resources.

End to End Governance

When introducing automation via CI/CD pipelines, be aware that the Role Based Access Control (RBAC) model must be applied at multiple layers. This code sample deploys many of these layers and show how they can be configured together in a unified governance model.

In a nutshell, you can achieve this by leveraging Azure Active Directory and connecting all role assignments (both Azure DevOps and ARM) to this single identity management plane.

Official Documentation

This repository features the code to deploy the infrastructure and bootstrap Azure DevOps. For more about the concept of end to end governance, please see:

Understanding this Demo

The Terraform Infrastructure as Code in this repository will bootstrap various resources for you:

  • Azure Resources (ARM)
  • Azure AD Groups
  • Service Principals
  • Azure DevOps Projects incl. Service Connections, Security Group Assignments, etc.

Random Generated Suffix

When run Terraform will create the following resources. Note: random suffix used to ensure globally unique names, e.g. u6t7 but are omitted here for clarity.

Azure AD Groups

The key to end to end governance is to have multiple role assignments (with different role definitions and different resource scopes to the same Azure AD groups) as illustrated below.

To understand the benefits, imagine if you had to remove a contractor after completion of a project. If you use the concept described in this project and in the accompanying official Microsoft documentation, you can remove their access from multiple environments and resources simply by removing their membership to AAD group(s).

Multiple Role Assignments

Note: the -all groups are currently not in use but was introduced to address a conceptual problem (see #12):

Group Name ARM Role Azure DevOps Role
fruits-all - -
fruits-devs Contributor Contributor
fruits-admins Owner Project Administrators
veggies-all - -
veggies-devs Contributor Contributor
veggies-admins Owner Project Administrators
infra-all - -
infra-devs Contributor Contributor
infra-admins Owner Project Administrators

In the future when we bootstrap the supermarket project, we will need the -all groups as well.

Azure DevOps Projects

The project structure illustrates different governance models and their trade-offs.

Preview of the Azure DevOps organization

Screenshot of the Azure DevOps organization created by this code sample. Icons by Smashicons not included.

  • "fruits" and "veggies" when isolated means less governance management - at the cost of less collaboration.
  • "supermarket" model prioritizes collaboration via shared Azure Boards - but requires more governance management, especially for repositories and pipelines.
Project Boards Repos Pipelines
project-fruits Yes Yes Yes
project-veggies Yes Yes Yes
collaboration Yes No No
central-it No Yes Yes
supermarket Yes Yes Yes

Azure Pipelines

  • Service Connection using Contributor Service Principal
  • Service Connection using Key Vault read-only Service Principal for Pipeline Secrets Integration

Note: At time of this writing there is no REST API (v6) for Key Vault Integration. Therefore it must be configured manually.

Azure Resource Groups as "Environments"

To reduce complexity for CI/CD automation of this open source repository, this project uses resource groups as a logical and security boundary for deployments.

  • fruits-dev-rg
  • fruits-prod-rg
  • veggies-dev-rg
  • veggies-prod-rg
  • infra-shared-rg

Be aware that in practice per Cloud Adoption Framework, these boundaries should be Azure Subscriptions, not Resource Groups.

Contributing

This demo was created with ♥ by the FastTrack engineer Julie Ng and based on previous experience as an Enterprise Architct and current experieince with Azure customers new to CI/CD and DevOps. After regularly breaking and fixing the demo in onboarding sessions, it was automated.

Learn more about FastTrack for Azure →

Code of Conduct

If you want to contribute, please first read the Microsoft Code of Conduct →

Bugs and Suggestions

The easiest way to contribute is to provide feedback.

Code Contributions

This project affects real Azure resources and leverages CI/CD to safeguard them. Therefore please read through all the sections below carefully for highest success of your contribution being accepted.

  • Use Conventional Commits

    Please use Conventional Commits so we can automate the Change Log. Thank you.

  • Create a Fork and Use small branches

    To get started, fork this repository. Please make your changes in your fork in a feature branch, ideally beginning with feat/* or fix/*

    Large Pull Requests can be a challenge to merge. Consider separating changes are you would into smaller bits like features and create separate pull requests for each.

  • Create a Pull Request

    Only Pull Requests with passing CI builds can be accepted for merging.

    When you are ready and checked you have met all code requirements described above, you can open a pull request. When you do so, a CI build should be automatically started. If you're having difficulty, please feel free to reach out for help by opening an issue or via Twitter @jng5.

License

This project is published under the MIT license. See LICENSE.md for details.

devops-governance's People

Contributors

julie-ng avatar microsoft-github-operations[bot] avatar microsoft-github-policy-service[bot] avatar microsoftopensource avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

devops-governance's Issues

Service Principals - remove manual passwords

Problem

Starting in AAD Provider 2.0, the ability to manually set a password will be disabled. In the future it will be randomly generated by Azure

Todo

Update code and configuration

Errors

 Warning: Attribute is deprecated
│
│   with module.service_principals.azuread_application_password.workspace_sp_secret,
│   on modules/service-principal/main.tf line 19, in resource "azuread_application_password" "workspace_sp_secret":
│   19:   value                 = random_password.secret.result
│
│ [NOTE] In version 2.0 of the AzureAD provider, this attribute will become read-only as it will no longer be possible to specify a password value. It will be generated by Azure
│ Active Directory and persisted to state for reuse in your Terraform configuration.
│
│ (and 5 more similar warnings elsewhere)

docs(deploy): terraform backend - remote vs local

Desired/Expected Functionality

Users who want to try this out should be able to run simple 3 command terraform init, plan and apply without having to create remote backend (Blob Storage) for Terraform state.

Problem

If you clone this repo and try to run it locally, Terraform will require that you create a remote backend because this repo uses a remote backend, see provider.tf

terraform {
  backend "azurerm" {}
  …
}

Currently the deploy docs say to use -backend=false flag, but it does not work for if it hasn't been initialised before. See https://www.terraform.io/docs/cli/commands/init.html

To skip backend configuration, use -backend=false. Note that some other init steps require an initialized backend, so it is recommended to use this flag only when the working directory was already previously initialized for a particular backend.

global.yaml environment variables not populated

This issue is for a: (mark with an x)

- [ ] bug report -> please search issues before submitting
- [ ] feature request
- [x] documentation issue or request

Minimal steps to reproduce

Create the same pipeline structure as the project:

│   cd.yaml
│   ci.yaml
│   main.tf
│   pr-main.yaml
│   pr-production.yaml
│   provider.tf
│   README.md
│   schedule-drift.yaml
│   var.tf
│
├───stages
│       ci.yaml
│       pull-request.yaml
│
├───steps
│       confirm-kv-loaded.yaml
│       debug-vars.yaml
│       terraform-init.yaml
│       terraform-plan.yaml
│
└───vars
        global.yaml

Any log messages given by the failure

In Azure DevOps pipeline, running it against the main branch, the isMain is not populated in the Debug - Branch Variables step and I get the following:


---------
Debugging
---------
isMain: 
isProduction: 
Build.SourceBranch: refs/heads/main
Finishing: Debug - Branch Variables

Expected/desired behavior

I expect the isMain: true

Versions

Task         : Bash
Description  : Run a Bash script on macOS, Linux, or Windows
Version      : 3.189.0
Author       : Microsoft Corporation
Help         : https://docs.microsoft.com/azure/devops/pipelines/tasks/utility/bash

Mention any other details that might be useful


The pipeline is fails at "Debug - Key Vault loaded?" step

--------------------------------
Confirm Key Vault 🔑 Integration
--------------------------------
KV_DEBUG_ENV: ***

⛔️ Key Vault not loaded
Please double check configuration Variable Groups in Azure Pipelines UI and that the YAML pipeline is running against the 'main' or 'production' branch.
##[error]Bash exited with code '1'.
Finishing: Debug - Key Vault loaded?

although $KV_DEBUG_ENV" != '$(kv-debug-env)

Bootstrap Repositories and scoped permissions

Currently the Azure DevOps projects are empty. In order to illustrate securing service connections by securing git repos, we need to:

  • Bootstrap repos using azuredevops_git_repository Terraform resource
  • Apply appropriate Admin or Contributor permissions per group
  • Apply branch policy to default branching requiring minimum reviewers. Don't do pipeline run, because then we would have to create a pipeline too…

Random Azure DevOps Errors

Symptom

Sometimes when IaC is changed, the following messages are returned when running terraform apply and even terraform destroy

module.arm_environments["infra_shared"].azurerm_resource_group.workspace: Still destroying... [id=/subscriptions/6e3d4b6a-31b2-423b-a19a-...22/resourceGroups/infra-shared-nsh0-rg, 40s elapsed]
module.arm_environments["fruits_dev"].azurerm_resource_group.workspace: Still destroying... [id=/subscriptions/6e3d4b6a-31b2-423b-a19a-...2822/resourceGroups/fruits-dev-nsh0-rg, 40s elapsed]
module.arm_environments["fruits_prod"].azurerm_resource_group.workspace: Still destroying... [id=/subscriptions/6e3d4b6a-31b2-423b-a19a-...822/resourceGroups/fruits-prod-nsh0-rg, 40s elapsed]
module.arm_environments["veggies_prod"].azurerm_resource_group.workspace: Destruction complete after 46s
module.arm_environments["fruits_dev"].azurerm_resource_group.workspace: Destruction complete after 46s
module.arm_environments["infra_shared"].azurerm_resource_group.workspace: Destruction complete after 46s
module.arm_environments["veggies_dev"].azurerm_resource_group.workspace: Destruction complete after 46s
module.arm_environments["fruits_prod"].azurerm_resource_group.workspace: Destruction complete after 45s

Error: TF50258: An error occurred finding the group. There is no group with the security identifier (SID) S-1-9-1551374245-1204400969-2402986413-2179408616-3-1909980924-2329286727-2170054555-31303424.



Error: TF50258: An error occurred finding the group. There is no group with the security identifier (SID) S-1-9-1551374245-1204400969-2402986413-2179408616-3-1128492131-4123986507-3057368717-147136582.



Error: TF50258: An error occurred finding the group. There is no group with the security identifier (SID) S-1-9-1551374245-1204400969-2402986413-2179408616-3-3734241186-3076090954-2678173946-3324452108.



Error: TF50258: An error occurred finding the group. There is no group with the security identifier (SID) S-1-9-1551374245-1204400969-2402986413-2179408616-3-1909980924-2329286727-2170054555-31303424.



Error: TF50258: An error occurred finding the group. There is no group with the security identifier (SID) S-1-9-1551374245-1204400969-2402986413-2179408616-3-3466419570-1682021700-2205560075-2915369390.



Error: TF50258: An error occurred finding the group. There is no group with the security identifier (SID) S-1-9-1551374245-1204400969-2402986413-2179408616-3-3466419570-1682021700-2205560075-2915369390.



Error: TF50258: An error occurred finding the group. There is no group with the security identifier (SID) S-1-9-1551374245-1204400969-2402986413-2179408616-3-3466419570-1682021700-2205560075-2915369390.



Error: TF50258: An error occurred finding the group. There is no group with the security identifier (SID) S-1-9-1551374245-1204400969-2402986413-2179408616-3-1128492131-4123986507-3057368717-147136582.



Error: TF50258: An error occurred finding the group. There is no group with the security identifier (SID) S-1-9-1551374245-1204400969-2402986413-2179408616-3-3734241186-3076090954-2678173946-3324452108.



Error: TF50258: An error occurred finding the group. There is no group with the security identifier (SID) S-1-9-1551374245-1204400969-2402986413-2179408616-3-1909980924-2329286727-2170054555-31303424.



Error: TF50258: An error occurred finding the group. There is no group with the security identifier (SID) S-1-9-1551374245-1204400969-2402986413-2179408616-3-1909980924-2329286727-2170054555-31303424.



Error: TF50258: An error occurred finding the group. There is no group with the security identifier (SID) S-1-9-1551374245-1204400969-2402986413-2179408616-3-3466419570-1682021700-2205560075-2915369390.

Hypothesis

Terraform is deleting ADO Projects before security groups. So when Terraform tries to remove security groups, it cannot find them and those "security identifier (SID)" are not found in terraform state. So I assume it's a weird legacy Team Foundation Server (TFS) identified.

Action

Use depends_on to force terraform to remove ADO security groups before removing projects.

Cannot deploy Azure DevOps Demo in Windows 11 with WSL

Please provide us with the following information:

This issue is for a: (mark with an x)

- [x ] bug report -> please search issues before submitting
- [ ] feature request
- [ ] documentation issue or request

Minimal steps to reproduce

  1. Open WSL in Windows
  1. Follow all steps described in the deploy.md guide
  • az login with outlook.com account (admin in tenant)
  • az account set (the msdn subscription)
  • mv _override.tf.sample _override.tf
  • export AZDO_ORG_SERVICE_URL="https://dev.azure.com/ormikopo-devops-demo"
  • export AZDO_PERSONAL_ACCESS_TOKEN="..." (token with full access in ADO organization 'ormikopo-devops-demo'
  • terraform init
  • terraform plan
  • terraform apply

Any log messages given by the failure

Authorization/roleAssignments/48bd9431-898d-c96f-6b85-6c4db80038fb]
module.arm_environments["veggies_dev"].azurerm_role_assignment.rg_team_admins: Creation complete after 25s [id=/subscriptions/d7130c91-ee33-4fe2-8094-9eee918c70a6/resourceGroups/veggies-dev-5z86-rg/providers/Microsoft.Authorization/roleAssignments/27525561-5f47-dcc6-a306-0c0807501ea0]
module.arm_environments["veggies_prod"].azurerm_role_assignment.rg_sp: Creation complete after 23s [id=/subscriptions/d7130c91-ee33-4fe2-8094-9eee918c70a6/resourceGroups/veggies-prod-5z86-rg/providers/Microsoft.Authorization/roleAssignments/16444cd1-fe25-290c-bee6-6e9a45e1a15f]
module.arm_environments["veggies_prod"].azurerm_role_assignment.rg_team_devs: Creation complete after 25s [id=/subscriptions/d7130c91-ee33-4fe2-8094-9eee918c70a6/resourceGroups/veggies-prod-5z86-rg/providers/Microsoft.Authorization/roleAssignments/bf86d03a-c653-c599-76fb-d9e91c38c4de]
module.arm_environments["veggies_prod"].azurerm_role_assignment.rg_team_admins: Creation complete after 23s [id=/subscriptions/d7130c91-ee33-4fe2-8094-9eee918c70a6/resourceGroups/veggies-prod-5z86-rg/providers/Microsoft.Authorization/roleAssignments/30aca515-6b35-5c3f-eb01-e82b0c963984]
module.service_connections["infra_shared"].data.azurerm_client_config.current: Reading...
module.service_connections["veggies_dev"].data.azurerm_subscription.current: Reading...
module.service_connections["fruits_dev"].data.azurerm_client_config.current: Reading...
module.service_connections["infra_shared"].data.azurerm_subscription.current: Reading...
module.service_connections["fruits_prod"].data.azurerm_client_config.current: Reading...
module.service_connections["fruits_prod"].data.azurerm_client_config.current: Read complete after 0s [id=2022-06-10 08:39:33.2838608 +0000 UTC]
module.service_connections["veggies_dev"].data.azurerm_client_config.current: Reading...
module.service_connections["veggies_prod"].data.azurerm_client_config.current: Reading...
module.service_connections["fruits_prod"].data.azurerm_subscription.current: Reading...
module.service_connections["fruits_dev"].data.azurerm_subscription.current: Reading...
module.service_connections["fruits_dev"].data.azurerm_client_config.current: Read complete after 0s [id=2022-06-10 08:39:33.2843127 +0000 UTC]
module.service_connections["infra_shared"].data.azurerm_client_config.current: Read complete after 0s [id=2022-06-10 08:39:33.2855188 +0000 UTC]
module.service_connections["veggies_prod"].data.azurerm_subscription.current: Reading...
module.service_connections["veggies_prod"].data.azurerm_client_config.current: Read complete after 0s [id=2022-06-10 08:39:33.2877869 +0000 UTC]
module.service_connections["veggies_dev"].data.azurerm_client_config.current: Read complete after 0s [id=2022-06-10 08:39:33.2874753 +0000 UTC]
module.service_connections["veggies_prod"].data.azuredevops_project.team: Reading...
module.service_connections["infra_shared"].data.azuredevops_project.team: Reading...
module.service_connections["veggies_dev"].data.azuredevops_project.team: Reading...
module.service_connections["fruits_prod"].data.azuredevops_project.team: Reading...
module.service_connections["fruits_dev"].data.azuredevops_project.team: Reading...
module.service_connections["infra_shared"].data.azuredevops_project.team: Read complete after 1s [id=c04beb99-7d0b-4a0b-8081-08341d4aefed]
module.service_connections["fruits_prod"].data.azuredevops_project.team: Read complete after 1s [id=c5440b4d-f516-42ae-8136-3b6258c7446d]
module.service_connections["fruits_dev"].data.azuredevops_project.team: Read complete after 1s [id=c5440b4d-f516-42ae-8136-3b6258c7446d]
module.service_connections["veggies_dev"].data.azuredevops_project.team: Read complete after 1s [id=c21c27d4-1ee7-4538-a0af-4afe9f4a99c6]
module.service_connections["veggies_prod"].data.azuredevops_project.team: Read complete after 1s [id=c21c27d4-1ee7-4538-a0af-4afe9f4a99c6]
module.service_connections["fruits_prod"].data.azurerm_subscription.current: Read complete after 1s [id=/subscriptions/d7130c91-ee33-4fe2-8094-9eee918c70a6]
module.service_connections["fruits_dev"].data.azurerm_subscription.current: Read complete after 1s [id=/subscriptions/d7130c91-ee33-4fe2-8094-9eee918c70a6]
module.service_connections["infra_shared"].data.azurerm_subscription.current: Read complete after 1s [id=/subscriptions/d7130c91-ee33-4fe2-8094-9eee918c70a6]
module.service_connections["veggies_prod"].data.azurerm_subscription.current: Read complete after 1s [id=/subscriptions/d7130c91-ee33-4fe2-8094-9eee918c70a6]
module.service_connections["veggies_dev"].data.azurerm_subscription.current: Read complete after 1s [id=/subscriptions/d7130c91-ee33-4fe2-8094-9eee918c70a6]
module.service_connections["fruits_prod"].azuredevops_serviceendpoint_azurerm.workspace_endpoint: Creating...
module.service_connections["veggies_dev"].azuredevops_serviceendpoint_azurerm.workspace_endpoint: Creating...
module.service_connections["veggies_prod"].azuredevops_serviceendpoint_azurerm.workspace_endpoint: Creating...
module.service_connections["infra_shared"].azuredevops_serviceendpoint_azurerm.workspace_endpoint: Creating...
module.service_connections["fruits_dev"].azuredevops_serviceendpoint_azurerm.workspace_endpoint: Creating...
module.service_connections["fruits_prod"].azuredevops_serviceendpoint_azurerm.workspace_endpoint: Still creating... [10s elapsed]
module.service_connections["infra_shared"].azuredevops_serviceendpoint_azurerm.workspace_endpoint: Still creating... [10s elapsed]
module.service_connections["veggies_dev"].azuredevops_serviceendpoint_azurerm.workspace_endpoint: Still creating... [10s elapsed]
module.service_connections["veggies_prod"].azuredevops_serviceendpoint_azurerm.workspace_endpoint: Still creating... [10s elapsed]
module.service_connections["fruits_dev"].azuredevops_serviceendpoint_azurerm.workspace_endpoint: Still creating... [10s elapsed]
module.service_connections["fruits_prod"].azuredevops_serviceendpoint_azurerm.workspace_endpoint: Creation complete after 11s [id=b82b3ed1-7695-43c3-8545-9da7b4f07b2c]
module.service_connections["fruits_dev"].azuredevops_serviceendpoint_azurerm.workspace_endpoint: Creation complete after 11s [id=0eaa1f41-21a6-437d-98f4-3fb027211c73]
module.service_connections["veggies_prod"].azuredevops_serviceendpoint_azurerm.workspace_endpoint: Creation complete after 12s [id=f20b8d47-6116-41dd-891a-aa395719f22f]
module.service_connections["veggies_dev"].azuredevops_serviceendpoint_azurerm.workspace_endpoint: Creation complete after 12s [id=9cb1aae4-210b-44dc-94c5-69738dec330f]
module.service_connections["infra_shared"].azuredevops_serviceendpoint_azurerm.workspace_endpoint: Creation complete after 12s [id=936a31c8-a2e7-4e52-9a77-3886e10e35a2]

│ Error: REST call returned status code 400

│ with module.ado_collaboration_permissions_fruits.azuredevops_group.team_group,
│ on modules/azure-devops-permissions/main.tf line 16, in resource "azuredevops_group" "team_group":
│ 16: resource "azuredevops_group" "team_group" {



│ Error: REST call returned status code 400

│ with module.ado_team_permissions["fruits"].azuredevops_group.team_group,
│ on modules/azure-devops-permissions/main.tf line 16, in resource "azuredevops_group" "team_group":
│ 16: resource "azuredevops_group" "team_group" {



│ Error: REST call returned status code 503

│ with module.ado_supermarket_permissions_veggies.azuredevops_group.team_group,
│ on modules/azure-devops-permissions/main.tf line 16, in resource "azuredevops_group" "team_group":
│ 16: resource "azuredevops_group" "team_group" {



│ Error: REST call returned status code 400

│ with module.ado_supermarket_permissions_fruits.azuredevops_group.team_group,
│ on modules/azure-devops-permissions/main.tf line 16, in resource "azuredevops_group" "team_group":
│ 16: resource "azuredevops_group" "team_group" {



│ Error: REST call returned status code 400

│ with module.ado_team_permissions["infra"].azuredevops_group.team_group,
│ on modules/azure-devops-permissions/main.tf line 16, in resource "azuredevops_group" "team_group":
│ 16: resource "azuredevops_group" "team_group" {



│ Error: REST call returned status code 503

│ with module.ado_collaboration_permissions_veggies.azuredevops_group.admins_group,
│ on modules/azure-devops-permissions/main.tf line 39, in resource "azuredevops_group" "admins_group":
│ 39: resource "azuredevops_group" "admins_group" {

Expected/desired behavior

Deploy the terraform resources (ADO projects, Resource groups, service principals, groups, users, etc.)

Versions

Windows 11, Terraform 1.22

Mention any other details that might be useful


Thanks! We'll be in touch soon.

ACTION REQUIRED: Microsoft needs this private repository to complete compliance info

There are open compliance tasks that need to be reviewed for your devops-governance repo.

Action required: 4 compliance tasks

To bring this repository to the standard required for 2021, we require administrators of this and all Microsoft GitHub repositories to complete a small set of tasks within the next 60 days. This is critical work to ensure the compliance and security of your Azure-Samples GitHub organization.

Please take a few minutes to complete the tasks at: https://repos.opensource.microsoft.com/orgs/Azure-Samples/repos/devops-governance/compliance

  • The GitHub AE (GitHub inside Microsoft) migration survey has not been completed for this private repository
  • No Service Tree mapping has been set for this repo. If this team does not use Service Tree, they can also opt-out of providing Service Tree data in the Compliance tab.
  • No repository maintainers are set. The Open Source Maintainers are the decision-makers and actionable owners of the repository, irrespective of administrator permission grants on GitHub.
  • Classification of the repository as production/non-production is missing in the Compliance tab.

You can close this work item once you have completed the compliance tasks, or it will automatically close within a day of taking action.

If you no longer need this repository, it might be quickest to delete the repo, too.

GitHub inside Microsoft program information

More information about GitHub inside Microsoft and the new GitHub AE product can be found at https://aka.ms/gim.

FYI: current admins at Microsoft include @julie-ng

Bootstrap "Supermarket" permissions in Azure DevOps

Currently the supermarket is just an empty project and has no function. To demonstrate the end to end governance concept, we need to:

  • Create supermarket-admins AAD group
  • Assign Project Administrator permissions to fruits-all and veggies-all
  • Assign Contributor permissions to fruits-all and fruits-all
  • Assign Contributor permissions to fruits-all and veggies-all
  • Create shared fruits and veggies repo (default)
  • Create fruits-only repo and necessary additional permissions at repository scope

terraform: add random suffix to Azure resource names

  • As a demo maintainer
  • I need to add random suffix to resource names
  • so customers can successfully run demo without running into errors (because Azure requires storage account, key vault, etc. names to be globally unique)

Headless Owner service principal can escalate his privileges

This is a great project and documentation. In the accompanying article the recommendation is to create a headless owner role for the service principal.

{
  "Name": "Headless Owner",    
  "Description": "Can manage infrastructure.",
  "actions": [
    "*"
  ],
  "notActions": [
    "Microsoft.Authorization/*/Delete"
  ],
  "AssignableScopes": [
    "/subscriptions/{subscriptionId1}",
    "/subscriptions/{subscriptionId2}",
    "/providers/Microsoft.Management/managementGroups/{groupId1}"
  ]
}

However, even with these reduced permissions, as long as the Microsoft.Authorization/roleAssignments/Write permission is provided, the principal can elevate his own permissions and assign himself the Owner role and then proceed and remove any locks on resources.

Microsoft.Authorization/roleAssignments/Write is required if we want to be able to assign permissions to managed identities. Is there a way to achieve that, while avoiding providing owner access to the pipeline service account?

Could an Azure Policy help here to prevent what kind of access our custom role or service principal can assign? Or limit permission assignment only to managed identity principals?

Proof of concept script for escalation is below

# Create custom role
az role definition create --role-definition headless-owner.json

# create a resource group
az group create -n test-rg --location canadaeast

# create a lock
az lock create --name cant-delete --resource-group test-rg --lock-type CanNotDelete

# Create service principal with custom role
SPPWD=$(az ad sp create-for-rbac --name sp-pipeline --role "Headless Owner" --query password -o tsv)
SPUSER=$(az ad sp list --display-name sp-pipeline --query [].appId -o tsv)
SPID=$(az ad sp list --display-name sp-pipeline --query [].objectId -o tsv)

# Login using service principal
az login --service-principal -u $SPUSER -p $SPPWD --tenant <tenand-id>

# try to delete resource with a lock
az group delete -n test-rg --yes
# OK it fails

# try to remove the lock
az lock delete --name cant-delete --resource-group test-rg
# OK it fails

# Elevate our permissions to owner
az role assignment create --assignee-object-id $SPID --assignee-principal-type ServicePrincipal --role 'Owner' --scope "/subscriptions/<subscription id>"

# try to remove the lock again
az lock delete --name cant-delete --resource-group test-rg
az group delete -n test-rg --yes
# NOT OK was able to remove lock and delete resource group


# cleanup
az login #login with our regular user
az ad sp delete --id $SPID
az role definition delete --name "Headless Owner"

Fix overlapping roles in AzureDevOps that leads to unexpected permissions

Problem

There is a bug in the concept as it currently exists. As of today we rely on 2 AAD groups for actors, e.g. for the "Veggies" team, we have:

AAD Group name Membership
veggies All developers in team
veggies-admins A subset of users who have elevated permissions

Expected Result

The veggie admins have elevated privileges, e.g. Administrator Access even if they have overlapping role assignments (due to membership in multiple groups).

Actual Result

  • As expected: for Azure Resource Manager, veggie-admins will have Administrative permissions due to ARM's additive permissions model

  • Unexpectedly: in Azure DevOps, veggie-admins will only have Contributor access because Azure DevOps uses least permissions model, as this doc describes:

    User accounts that are assigned to more than one security group are restricted to those permissions granting the least access.

Solution

To get the behavior expect, we need to have three AAD groups per domain, for example:

  • veggies-all
  • veggies-dev
  • veggies-admin

In this way, we can avoid overlapping role assignments that result in unexpected behavior in Azure DevOps.

Tasks

  • Terraform: create 3 AAD groups per domain
  • Terraform: update assignments, paying extra attention to "supermarket" collaboration scenario
  • Concept: update text

Upgrade Azure AD provider to newest version

Upgrade Azure AD provider from v1 to v2

  • Upgrade Azure AD provider to latest v2 version
  • Fix breaking change - remove random password generation. Passwords now managed by Provider, which was a breaking change in Microsoft Graph API.

    The value field has become read-only as Azure Active Directory no longer accepts user-supplied password values. Passwords are instead auto-generated by Azure and exported with the value attribute by the resource.

  • Best Practice - add owners to created service principals per in documentation

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.