diff --git a/CONCEPT.md b/CONCEPT.md
deleted file mode 100644
index be94b8e..0000000
--- a/CONCEPT.md
+++ /dev/null
@@ -1,126 +0,0 @@
-# Concept - Multi-tier Governance
-
-Status: Draft
-Author: Julie Ng
-Last Updated: March 2021
-
-### Abstract
-
-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. Other deployment methods must also be secured and governance applied.
-
-By 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.
-
-## Example Scenario, Business Requirements
-
-This demo is open source and intended to be used as a **Teaching Tool** for organizations who are new to DevOps and need to create a governance model for deploying to Azure. Please read this carefully to understand the decisions behind the model used in this sample repository.
-
-Any governance model must be tied to the organization's business rules, which are reflected in any technical implementation of access controls. This example model uses a fictitious company with common requirements:
-
-- **Business Units**
- The organization has many vertical business units, e.g. "fruits" and "vegetables", which operate largely independently.
-- **Central-IT**
- There is a central IT team, specializing in cloud infrastructure that manages shared services used by business units. This team is called [Cloud Center of Excellence](https://docs.microsoft.com/en-us/azure/cloud-adoption-framework/organize/cloud-center-of-excellence) in Microsoft's [Cloud Adoption Framework (CAF)](https://docs.microsoft.com/en-us/azure/cloud-adoption-framework) terminology.
-- **AAD Groups**
- Every team has a subset of developers called "admins" with elevated privileges.
-- **Deployment Environments**
- Every team has 2 environments
- - Production - only admins have elevated privileges
- - Non-production - all developers have elevated privileges (to encourage experimentation and innovation)
-- **Automation Goals**
- Every application should implement DevOps, not just continuous integration (CI) but also (CD), i.e. deployments can be automatically triggered via changes to the git repository.
-- **Cloud Journey - so far**
- The organization started with an isolated project model to accelerate the journey to the cloud. But now they are exploring options to break silos and encourage collaboration by creating the "collaboration" and "supermarket" projects.
-
-## CI/CD Automation Workflow
-
-The following diagram illustrates a baseline CI/CD workflow with [Azure DevOps](https://dev.azure.com). The red lock icon indicates security permissions which must be configured by the user. Not configuring or mis-configuring permissions will leave your workloads vulnerable.
-
-![End to End Governance](./images/e2e-governance-scm-to-arm.svg)
-
-TODO: introduce x-axis for "layers"
-
-To successfully secure your workloads, you must leverage a combination of security permissions configurations and human checks in your workflow. RBAC will prevent individual developers from making destructive changes. Build pipelines, however often run with privileged identities and will happily destroy your workloads if instructed to do so in the pipeline code. To prevent this from happening, you should configure [branch policies](https://docs.microsoft.com/en-us/azure/devops/repos/git/branch-policies?view=azure-devops) on your repository to require human approval before accepting changes that trigger automation pipelines.
-
-| Deployment Step | Responsibility | Description |
-|:--|:--|:--|
-| **Pull Requests** | User | Engineers should peer review their work especially the Pipeline code. |
-| **Branch Protection** | [Shared](https://docs.microsoft.com/en-us/azure/security/fundamentals/shared-responsibility) | Configure [Azure DevOps](https://docs.microsoft.com/en-us/azure/devops/repos/git/branch-policies?view=azure-devops) or [GitHub](https://docs.github.com/en/free-pro-team@latest/github/administering-a-repository/about-protected-branches) to reject changes that do not meet certain standards, e.g. CI checks and peer reviews (via pull requests). |
-| **Pipeline as Code** | User | A build server will happily delete your production environment if the pipeline code instructs it to do so. Prevent this using a combination of pull requests and branch protection rules. |
-| **[Service Connections](https://docs.microsoft.com/en-us/azure/devops/pipelines/library/service-endpoints?view=azure-devops&tabs=yaml)** | [Shared](https://docs.microsoft.com/en-us/azure/security/fundamentals/shared-responsibility) | Configure Azure DevOps to restrict access to these credentials. |
-| **Azure Resources** | [Shared](https://docs.microsoft.com/en-us/azure/security/fundamentals/shared-responsibility) | Configure RBAC in the Azure Resource Manager. |
-
-Before examining the governance layers in detail, please consider the use case and assumptions of this example organization.
-
----
-
-## Layer - Safeguard your Source Code with Branch Policies
-
-Because your source code defines and triggers deployments, your first line of defense is to secure your source code management (SCM) repository. In practice, this is achieved by using the [Pull Request workflow](https://docs.microsoft.com/en-us/azure/devops/repos/git/pull-requests-overview?view=azure-devops) and in combination with [branch policies](#) which define checks and requirements before code can be accepted.
-
-![Pull Request Workflow](./images/flow-git-pr-worflow.svg)
-
-When planning your end to end governance model, your privileged users, e.g. `veggies-admins` will be responsible for configuring branch protection. Common branch protection checks to secure your deployments include:
-
-- **Require CI build to pass**
- Useful for establishing baseline code quality, e.g. code linting, unit tests and even security checks e.g. virus and credential scans.
-
-- **Require peer review**
- Have another human double check that code works as intended. Be extra careful when changes are made to pipeline code. Combine with CI builds to make peer reviews less tedious.
-
-#### What happens if a developer tries to push directly to production?
-
-Remember that git is distributed SCM system. A developer may choose to commit directly to their local `production` branch. But when configured, this push can be rejected by the git server. For example:
-
-```
-remote: Resolving deltas: 100% (3/3), completed with 3 local objects.
-remote: error: GH006: Protected branch update failed for refs/heads/main.
-remote: error: Required status check "continuous-integration" is expected.
-To https://github.com/Azure-Samples/devops-governance
- ! [remote rejected] main -> main (protected branch hook declined)
-error: failed to push some refs to 'https://github.com/Azure-Samples/devops-governance'
-```
-
-Please note the workflow above is vendor agnostic. The pull request and branch protection features are available from multiple SCM providers including [Azure Repos](https://azure.microsoft.com/services/devops/repos/), [GitHub](https://github.com) and [GitLab](https://gitlab.com).
-
-Once the code has been accepted into a protected branch the next layer of access controls will be applied by the build server, e.g. [Azure Pipelines](https://azure.microsoft.com/services/devops/pipelines/).
-
----
-
-## Layer - Secure Access to your Deployment Environments
-
-To deploy to Azure, Azure Pipelines needs access to your Azure resources. When deploying to Azure from a headless CI/CD agent, use a [service principal](https://docs.microsoft.com/en-us/azure/active-directory/develop/app-objects-and-service-principals) to which you also apply role based access controls. For example, create separate service principals for your production and non-production environments.
-
-### What is a Service Connection?
-
-In Azure DevOps, a [Service Connection](https://docs.microsoft.com/azure/devops/pipelines/library/service-endpoints?view=azure-devops&tabs=yaml) is essentially credentials used to access external resources, e.g. ARM, GitHub or Docker Hub. Because we are deploying to Azure, our Service Connections will be Service Principals.
-
-
-
-(TODO: replace image)
-
-_Note: the ["Environments"](https://docs.microsoft.com/azure/devops/pipelines/process/environments?view=azure-devops) feature in Azure DevOps serves more as a logical boundary and is useful for [audits and deployment histories](https://docs.microsoft.com/en-us/azure/devops/pipelines/process/environments?view=azure-devops#deployment-history-within-environments). For details, see this [purple footnote](https://docs.microsoft.com/en-us/azure/devops/pipelines/process/environments?view=azure-devops#user-permissions)._
-
-
-### Securing Service Connections
-
-At a minimum configure [User](https://docs.microsoft.com/en-us/azure/devops/pipelines/library/service-endpoints?view=azure-devops&tabs=yaml#user-permissions), [Project](https://docs.microsoft.com/en-us/azure/devops/pipelines/library/service-endpoints?view=azure-devops&tabs=yaml#project-level-permissions) and [Pipeline](https://docs.microsoft.com/en-us/azure/devops/pipelines/library/service-endpoints?view=azure-devops&tabs=yaml#pipeline-permissions) permissions for your Service Connection. This sets who or which pipeline can use the credentials underneath. Additionally we can in the Azure DevOps UI configure _under which conditions_ these credentials can be used by applying [Approvals and Checks](https://docs.microsoft.com/azure/devops/pipelines/process/approvals?view=azure-devops&tabs=check-pass).
-
-
-When you configure a check, the Azure DevOps service will perform this check before giving the job (and required credentials) to a headless CI/CD agent to run. Common checks include:
-
-- **Manual Approval**
- Depending on your business processes, it may be useful to require additional human approval for example from a business owner before deploying to your production environment.
-
-- **Required Template**
- If your organization has required security measures e.g. credential scanning or open source license audits, you can use the "required template" option to ensure these steps are run before deploying. For details see [Azure Pipelines > Security Best Practices > Set Required Template](https://docs.microsoft.com/en-us/azure/devops/pipelines/security/templates?view=azure-devops#set-required-templates).
-
-Note that these checks are often only applied to production environments, but not before to encourage innovation and experimentation by developers.
-
----
-
-## Layer - Apply RBAC to ARM Resources
-
-![Azure Pipelines - Deploy to ARM](./images/flow-ado-deploy.svg)
-
-Finally our deployment reaches ARM with the [RBAC options](https://docs.microsoft.com/en-us/azure/role-based-access-control/overview) you're already familiar with.
-
diff --git a/README.md b/README.md
index 9b03d07..bb7a110 100644
--- a/README.md
+++ b/README.md
@@ -7,33 +7,33 @@ This demo project deploys Azure resources and bootstraps Azure DevOps projects t
| [![CD - Build Status](https://dev.azure.com/julie-msft/e2e-governance-demo/_apis/build/status/continuous-deployment-v2?branchName=deploy)](https://dev.azure.com/julie-msft/e2e-governance-demo/_build/latest?definitionId=34&branchName=deploy) | Deployment Azure Resources and Azure DevOps |
| [![Detect Drift - Build Status](https://dev.azure.com/julie-msft/e2e-governance-demo/_apis/build/status/detect-drift-v2?branchName=deploy)](https://dev.azure.com/julie-msft/e2e-governance-demo/_build/latest?definitionId=35&branchName=deploy) | Detect Configuration Drift (scheduled nightly) |
-### Table of Contents
+### Contents
-- #### [Concept - End to End Governance](./README.md)
- - Use Case, Requirements
- - Azure AD Groups and Role Based Access Controls (RBAC)
- - Securing environments - Production vs Non-production
- - Multi-tiered Governance - Access Controls
-
-- #### [Deploy Example with Terraform](./TERRAFORM.md)
- - Prerequisites
- - Azure Resource Manager (ARM) - Service Principal
- - Azure AD - Tenant, Service Principal
- - Azure DevOps - Organization, Personal Access Token (PAT)
- - Setup and Install
- - Deploy
+- [What is End to End Governance?](#what-is-end-to-end-governance)
+- [Deploy Example with Terraform →](./DEPLOY.md)
+- [Understanding this demo](#understanding-this-demo)
-## Abstract - Did You Close the Security Backdoor?
+## 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](./images/e2e-governance-overview.svg)](./CONCEPT.md)
+[![End to End Governance](./images/e2e-governance-overview.svg)](https://aka.ms/architecture-e2e-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.
-## How to Use this Demo
+### 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:
+
+- [Azure Architecture Center - End-to-end governance in Azure when using CI/CD](https://aka.ms/architecture-e2e-governance)
+ More technical documentation with step by step walkthrough of diagram above and how to leverage Azure AD as single identity provider for unified RBAC.
+
+- [Cloud Adoption Framework - End-to-end governance from DevOps to Azure](https://aka.ms/caf-e2e-devops)
+ Explains Role Assignments and the planning required for organizations in their cloud journey to create end to end governance.
+
+## Understanding this Demo
The Terraform Infrastructure as Code in this repository will bootstrap various resources for you:
@@ -42,16 +42,18 @@ The Terraform Infrastructure as Code in this repository will bootstrap various r
- Service Principals
- Azure DevOps Projects incl. Service Connections, Security Group Assignments, etc.
-Preview of the Azure DevOps organization created by this code sample. Icons by [Smashicons](https://www.flaticon.com/authors/smashicons) not included.
-
-
-
-#### Note: Random Generated Suffix
+#### 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](https://aka.ms/architecture-e2e-governance), you can remove their access from multiple environments and resources simply by removing their membership to AAD group(s).
+
+[![Multiple Role Assignments](./images/2021-06-role-assignments.svg)](https://aka.ms/caf-e2e-devops)
+
Note: the `-all` groups are currently not in use but was introduced to address a conceptual problem (see [#12](https://github.com/Azure/devops-governance/issues/12)):
- Azure Resource Manager uses an [_additive_ permissions](https://docs.microsoft.com/en-us/azure/role-based-access-control/overview#multiple-role-assignments) model
@@ -75,6 +77,10 @@ In the future when we bootstrap the `supermarket` project, we will need the `-al
The project structure illustrates different governance models and their trade-offs.
+
+
+_Screenshot of the Azure DevOps organization created by this code sample. Icons by [Smashicons](https://www.flaticon.com/authors/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.
diff --git a/images/2021-06-aac-article.png b/images/2021-06-aac-article.png
new file mode 100644
index 0000000..ca7e390
Binary files /dev/null and b/images/2021-06-aac-article.png differ
diff --git a/images/2021-06-caf-article.png b/images/2021-06-caf-article.png
new file mode 100644
index 0000000..304ce30
Binary files /dev/null and b/images/2021-06-caf-article.png differ
diff --git a/images/2021-06-role-assignments.svg b/images/2021-06-role-assignments.svg
new file mode 100644
index 0000000..3688004
--- /dev/null
+++ b/images/2021-06-role-assignments.svg
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/images/ado-service-connections-environments.svg b/images/ado-service-connections-environments.svg
deleted file mode 100644
index ff4372e..0000000
--- a/images/ado-service-connections-environments.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/images/e2e-governance-scm-to-arm.svg b/images/e2e-governance-scm-to-arm.svg
deleted file mode 100644
index 6eba2e5..0000000
--- a/images/e2e-governance-scm-to-arm.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/images/flow-ado-deploy.svg b/images/flow-ado-deploy.svg
deleted file mode 100644
index 3a123df..0000000
--- a/images/flow-ado-deploy.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/images/flow-git-pr-worflow.svg b/images/flow-git-pr-worflow.svg
deleted file mode 100644
index b948acd..0000000
--- a/images/flow-git-pr-worflow.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/images/identity-security-principals.png b/images/identity-security-principals.png
deleted file mode 100644
index debbd6b..0000000
Binary files a/images/identity-security-principals.png and /dev/null differ