Skip to content

Latest commit

 

History

History
66 lines (46 loc) · 4.23 KB

README.md

File metadata and controls

66 lines (46 loc) · 4.23 KB

Azure Pipelines

Brief notes and considerations when automating infrastructure with Terraform and Azure DevOps.

Pipeline Overview

Pipeline Triggers Terraform Backend Detect Drift Deploys
ci.yaml main branch
dev branch
feat/* branch
fix/* branch
• Pull Requests to main
local/none No No
detect-drift.yaml main branch
• Pull Requests to release
• Scheduled nightly
Azure Storage Yes No
cd.yaml release branch Azure Storage No* Yes

*The CD pipeline does not check for drift because this is checked at the pull request.

Security Considerations

Terraform State in Azure Blob Storage

Terraform state is always in plain text, which is why it is stored in Azure Blob Storage with public access disabled.

  • This storage account is NOT managed by Terraform
  • This project prefers Shared Access Signtures (SAS) tokens over Access Keys in order to:
    • Apply principle of least privilege
    • Use short-lived tokens for CI/CD because we trust for headless actors less

Pipeline Secrets and Azure Key Vault Integration

Example

Variable in YAML Description Naming Convention
kv-tf-state-blob-account Name of secret in Key Vault. The $(…) macro syntax means it will be fetched and processed into template before pipeline runs. Custom kv- prefix for easier debugging
$TF_STATE_BLOB_ACCOUNT_NAME Mapped environment variable Linux: uppercase with underscores
variables:
  - group: e2e-gov-demo-kv

steps:
- bash: |    
    terraform init \
      -backend-config="storage_account_name=$TF_STATE_BLOB_ACCOUNT_NAME" \
      -backend-config="container_name=$TF_STATE_BLOB_CONTAINER_NAME" \
      -backend-config="key=$TF_STATE_BLOB_FILE" \
      -backend-config="sas_token=$TF_STATE_BLOB_SAS_TOKEN"
  displayName: Terraform Init
  env:
    TF_STATE_BLOB_ACCOUNT_NAME:   $(kv-tf-state-blob-account)
    TF_STATE_BLOB_CONTAINER_NAME: $(kv-tf-state-blob-container)
    TF_STATE_BLOB_FILE:           $(kv-tf-state-blob-file)
    TF_STATE_BLOB_SAS_TOKEN:      $(kv-tf-state-sas-token)

Why is there an Azure AD "Superadmins" Group?

In this example "superadmins" refers to privileged accounts at the organization level, e.g. central IT infrastructure admins.

This project creates Azure Key Vaults, which require access policies for the Data Plane. This means you want to create the Key Vault and give yourself access.

If our CI/CD agent creates the Key Vault, it can assign itself access. But what if we as an infrastructure administrator also want access? If you give yourself access outside of Terraform, it can create configuration drift that conflicts with Terraform state. Using Access Policies, you can assign the Access Policy to an Azure AD group instead of an account (service principal or user principal).

N.B. This is not relevant if you use the Azure RBAC model for Azure Key Vault. At time of this writing (November 2020), this feature is still in preview, which is why this project uses access policies.