Last active
March 20, 2023 15:07
-
-
Save cdennig/4866a74b341a0079b5a59052fa735dbc to your computer and use it in GitHub Desktop.
Azure DevOps Terraform with KeyVault + Service Connection
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
trigger: | |
- master | |
pool: | |
vmImage: 'ubuntu-latest' | |
variables: | |
- group: kvintegratedvargroup | |
steps: | |
- script: echo Hello, world! | |
displayName: 'Run a one-line script' | |
- script: | | |
echo KeyVault secret value: $(kvmysupersecretsecret) | |
displayName: 'Run a multi-line script' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
trigger: | |
- master | |
pool: | |
vmImage: 'ubuntu-latest' | |
variables: | |
- group: my-variable-group | |
steps: | |
- script: echo Hello, world! | |
displayName: 'Run a one-line script' | |
- script: | | |
echo Var1: $(var1) | |
echo Var2: $(var2) | |
displayName: 'Run a multi-line script' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
trigger: | |
- master | |
pool: | |
vmImage: 'ubuntu-latest' | |
steps: | |
- script: echo Hello, world! | |
displayName: 'Run a one-line script' | |
- script: | | |
echo Pipeline is running | |
echo And here is the value of our pipeline variable | |
echo $(mypipelinevar) | |
displayName: 'Run a multi-line script' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
provider "azuredevops" { | |
version = ">= 0.0.1" | |
org_service_url = var.orgurl | |
personal_access_token = var.pat | |
} | |
resource "azuredevops_project" "project" { | |
project_name = "Terraform DevOps Project" | |
description = "Sample project to demonstrate AzDevOps <-> Terraform integration" | |
visibility = "private" | |
version_control = "Git" | |
work_item_template = "Agile" | |
} | |
resource "azuredevops_git_repository" "repo" { | |
project_id = azuredevops_project.project.id | |
name = "Sample Empty Git Repository" | |
initialization { | |
init_type = "Clean" | |
} | |
} | |
resource "azuredevops_build_definition" "build" { | |
project_id = azuredevops_project.project.id | |
name = "Sample Build Pipeline" | |
ci_trigger { | |
use_yaml = true | |
} | |
repository { | |
repo_type = "TfsGit" | |
repo_id = azuredevops_git_repository.repo.id | |
branch_name = azuredevops_git_repository.repo.default_branch | |
yml_path = "azure-pipeline.yaml" | |
} | |
variable { | |
name = "mypipelinevar" | |
value = "Hello From Az DevOps Pipeline!" | |
is_secret = false | |
} | |
} | |
### DEMO with var groups | |
resource "azuredevops_variable_group" "vars" { | |
project_id = azuredevops_project.project.id | |
name = "my-variable-group" | |
allow_access = true | |
variable { | |
name = "var1" | |
value = "value1" | |
} | |
variable { | |
name = "var2" | |
value = "value2" | |
} | |
} | |
resource "azuredevops_build_definition" "buildwithgroup" { | |
project_id = azuredevops_project.project.id | |
name = "Sample Build Pipeline with VarGroup" | |
ci_trigger { | |
use_yaml = true | |
} | |
variable_groups = [ | |
azuredevops_variable_group.vars.id | |
] | |
repository { | |
repo_type = "TfsGit" | |
repo_id = azuredevops_git_repository.repo.id | |
branch_name = azuredevops_git_repository.repo.default_branch | |
yml_path = "azure-pipeline-with-vargroup.yaml" | |
} | |
} | |
### DEMO with var groups AND KEYVAULT! | |
data "azurerm_client_config" "current" { | |
} | |
provider "azurerm" { | |
version = "~> 2.6.0" | |
features { | |
key_vault { | |
purge_soft_delete_on_destroy = true | |
} | |
} | |
} | |
## Service Principal for DevOps | |
resource "azuread_application" "azdevopssp" { | |
name = "azdevopsterraform" | |
} | |
resource "random_string" "password" { | |
length = 32 | |
special = true | |
} | |
resource "azuread_service_principal" "azdevopssp" { | |
application_id = azuread_application.azdevopssp.application_id | |
} | |
resource "azuread_service_principal_password" "azdevopssp" { | |
service_principal_id = azuread_service_principal.azdevopssp.id | |
value = random_string.password.result | |
end_date = "2024-01-01T00:00:00Z" | |
} | |
resource "azurerm_role_assignment" "main" { | |
principal_id = azuread_service_principal.azdevopssp.id | |
scope = "/subscriptions/${data.azurerm_client_config.current.subscription_id}" | |
role_definition_name = "Contributor" | |
} | |
## KeyVault | |
resource "azurerm_resource_group" "rg" { | |
name = "myazdevops-rg" | |
location = "westeurope" | |
} | |
resource "azurerm_key_vault" "keyvault" { | |
name = "myazdevopskv" | |
location = "westeurope" | |
resource_group_name = azurerm_resource_group.rg.name | |
enabled_for_disk_encryption = true | |
tenant_id = data.azurerm_client_config.current.tenant_id | |
soft_delete_enabled = true | |
purge_protection_enabled = false | |
sku_name = "standard" | |
access_policy { | |
tenant_id = data.azurerm_client_config.current.tenant_id | |
object_id = data.azurerm_client_config.current.object_id | |
secret_permissions = [ | |
"backup", | |
"get", | |
"list", | |
"purge", | |
"recover", | |
"restore", | |
"set", | |
"delete", | |
] | |
certificate_permissions = [ | |
] | |
key_permissions = [ | |
] | |
} | |
} | |
## Grant DevOps SP permissions | |
resource "azurerm_key_vault_access_policy" "azdevopssp" { | |
key_vault_id = azurerm_key_vault.keyvault.id | |
tenant_id = data.azurerm_client_config.current.tenant_id | |
object_id = azuread_service_principal.azdevopssp.object_id | |
secret_permissions = [ | |
"get", | |
"list", | |
] | |
} | |
## Create a secret | |
resource "azurerm_key_vault_secret" "mysecret" { | |
key_vault_id = azurerm_key_vault.keyvault.id | |
name = "kmysupersecretsecret" | |
value = "KeyVault for the Win!" | |
} | |
## Service Connection | |
resource "azuredevops_serviceendpoint_azurerm" "endpointazure" { | |
project_id = azuredevops_project.project.id | |
service_endpoint_name = "AzureRMConnection" | |
credentials { | |
serviceprincipalid = azuread_service_principal.azdevopssp.application_id | |
serviceprincipalkey = random_string.password.result | |
} | |
azurerm_spn_tenantid = data.azurerm_client_config.current.tenant_id | |
azurerm_subscription_id = data.azurerm_client_config.current.subscription_id | |
azurerm_subscription_name = "<SUBSCRIPTION_NAME>" | |
} | |
## Grant permission to use service connection | |
resource "azuredevops_resource_authorization" "auth" { | |
project_id = azuredevops_project.project.id | |
resource_id = azuredevops_serviceendpoint_azurerm.endpointazure.id | |
authorized = true | |
} | |
## Pipeline with access to kv secret | |
resource "azuredevops_variable_group" "kmyintegratedvargroup" { | |
project_id = azuredevops_project.project.id | |
name = "kmyintegratedvargroup" | |
description = "KeyVault integrated Variable Group" | |
allow_access = true | |
key_vault { | |
name = azurerm_key_vault.keyvault.name | |
service_endpoint_id = azuredevops_serviceendpoint_azurerm.endpointazure.id | |
} | |
variable { | |
name = "kmysupersecretsecret" | |
} | |
} | |
resource "azuredevops_build_definition" "buildwithkeyvault" { | |
project_id = azuredevops_project.project.id | |
name = "Sample Build Pipeline with KeyVault Integration" | |
ci_trigger { | |
use_yaml = true | |
} | |
variable_groups = [ | |
azuredevops_variable_group.kmyintegratedvargroup.id | |
] | |
repository { | |
repo_type = "TfsGit" | |
repo_id = azuredevops_git_repository.repo.id | |
branch_name = azuredevops_git_repository.repo.default_branch | |
yml_path = "azure-pipeline-with-keyvault.yaml" | |
} | |
} |
Happy to hear it helped you...and thanks for the updates 🙈😊
Thanks for sharing this, wished I came across it sooner.
This automates the first steps mentioned in
https://jacktracey.co.uk/terraform-with-azure-devops/
@IntergalacticBVBA you're welcome. There's also a blog post for this: https://partlycloudy.blog/2020/08/05/azure-devops-terraform-provider/
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Just what I needed - thank you, this saved me some hours!
I wanted to let you know of the following changes:
I updated "Terraform integragtion" to "Terraform integration"
I also updated
resource "azuredevops_variable_group" "kyintegratedvargroup"
to
resource "azuredevops_variable_group" "kvintegratedvargroup"