Рубрики
Uncategorized

Azure DevOps Terraform Provider

Не так давно была выпущена первая версия поставщика Terraform Terraform Azure Devops. В этой арти … с меткой терраформ, лазурной, DevOps, IAC.

Не так давно была выпущена первая версия поставщика Terraform Terraform Azure Devops. В этой статье я покажу вам несколько примеров, какие функции в настоящее время поддерживаются с точки зрения сборки сборки и того, как использовать поставщика, а также в сочетании с Azure. Поставщик является последним «строительным блоком» для многих людей, работающих в пространстве «Инфраструктура в качестве кода» для создания сред (включая GIT Repo, сервисные соединения, конвейеры сборки + выпуск и т. Д.) полностью автоматически.

Поставщик был выпущен в июне 2020 года в версии 0,0,1 , но, честно говоря: этот набор функций уже довольно богат на этой ранней стадии.

Особенности, которые я хотел бы обсудить с помощью примеров, заключаются в следующем:

  • Создайте проект DevOps, включая размещенный GIT Repo.
  • Создание конвейера сборки
  • Использование переменных и групп переменных
  • Создание Azure Service Connection и использование переменных/секретов из Azure KeyVault

Пример 1: Основное использование

Поставщик Azure DevOps может быть интегрирован в сценарий, как и любой другой поставщик Terraform. Все, что требуется, это URL для организации DevOps и Персональный токен доступа ( pat ), с помощью которого провайдер может аутентифицировать себя против Azure DevOps.

Пэт может быть легко создан с помощью пользовательского интерфейса Azure DevOps, создав новый токен через Настройки пользователя -> Персональный токен доступа -> новый токен Анкет Ради простоты, в этом примере я даю «полный доступ» к нему … конечно, это должно быть адаптировано для ваших собственных целей.

Создайте токен личного доступа

Документация поставщика Terraform содержит информацию о разрешениях, необходимых для соответствующего ресурса.

Определение соответствующих областей

После того, как токен доступа был создан, поставщик Azure DevOps может быть указан в сценарии Terraform следующим образом:

provider "azuredevops" {
  version               = ">= 0.0.1"
  org_service_url       = var.orgurl
  personal_access_token = var.pat
}

Две переменные Orgurl и Пэт Должен быть выставлен как переменные среды:

$ export TF_VAR_orgurl = "https://dev.azure.com/"
$ export TF_VAR_pat = ""

Таким образом, это в основном все, что нужно для работы с Terraform и Azure DevOps. Давайте начнем с создания нового проекта и репозитория GIT. Для этого необходимы два ресурса, azurevops_project и azurevops_git_repository :

resource "azuredevops_project" "project" {
  project_name       = "Terraform DevOps Project"
  description        = "Sample project to demonstrate AzDevOps <-> Terraform integragtion"
  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"
  }
}

Кроме того, нам также нужен начальный трубопровод, который будет запускается на git push к Мастер Анкет В трубопроводе вы обычно работаете с переменными, которые поступают из разных источников. Это могут быть переменные трубопровода, значения из группы переменной или из внешних источников, таких как Azure Keyvault. Первое, простое определение сборки использует переменные трубопровода ( mypipelinevar ):

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
  }
}

Соответствующее определение трубопровода выглядит следующим образом:

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'

Трубопровод просто выполняет некоторые сценарии — для демонстрационных целей — и выводит переменную Хранится в определении консоли Анкет

Запустив сценарий Terraform, он создает проект Azure DevOps, репозиторий GIT и определение сборки.

Azure DevOps Project

GIT Repository

Трубопровод

Как только файл azure_pipeline.yaml Обсуждается выше, выдвигается в репо, соответствующий трубопровод запускается, и результаты можно найти на соответствующем этапе сборки:

Бегущий трубопровод

Выход конвейера сборки

Пример 2: Используя переменные группы

Обычно переменные не хранятся непосредственно в определении трубопровода, а скорее помещаются в Azure DevOps переменные группы . Это позволяет вам хранить отдельные переменные в центре в Azure DevOps, а затем ссылаться и использовать их в разных трубопроводах.

К счастью, переменные группы также могут быть созданы с использованием Terraform. Для этого ресурс azurevops_variable_group используется. В нашем сценарии это выглядит так:

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"
  }

}

Первая часть сценария Terraform создает группу переменных в Azure DevOps (имя: my-viable-group ), включая две переменные ( var1 и var2 ), вторая часть-определение сборки-использует группу переменных, так что переменные можно получить в соответствующем файле трубопровода ( Azure-Pipeline-With-Vargroup.yaml ).

У него следующий контент:

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'

Если вы запустите сценарий Terraform, будут созданы соответствующие ресурсы Azure DevOps: переменная группа и трубопровод.

Переменная группа

Если вы отправите файл сборки YAML в репо, трубопровод будет выполнен, и вы должны увидеть значения двух переменных в виде вывода на консоли сборки.

Вывод переменных из группы переменной

Пример 3: Использование подключений Azure Keyvault и Azure DevOps

По соображениям безопасности критические значения не хранятся непосредственно в определении трубопровода и в группах переменных Azure DevOps. Вы обычно используете внешнее хранилище, как Azure Keyvault Анкет К счастью, с Azure DevOps у вас есть возможность напрямую доступ к существующему Azure Keyvault и доступа к секретам, которые затем доступны в качестве переменных в вашем конвейере сборки.

Конечно, Azure DevOps должны быть аутентифицированы/авторизованы против Azure для этого. Azure DevOps использует концепцию Сервисные соединения Для этого. Сервисные соединения используются для доступа, например Bitbucket, Github, Jira, Jenkis … или — как в нашем случае — Lazure. Вы определяете пользователя — для Azure это Служба директора — который используется трубопроводами DevOps для выполнения различных задач — в нашем примере, получая секрет от Keyvault.

Чтобы продемонстрировать этот сценарий, сначала должны быть настроены различные вещи:

  • Создание принципала приложения/службы в Azure Active Directory, который используется Azure DevOps для аутентификации
  • Создание Azure Keyvault (включая группу ресурсов)
  • Разрешение директора службы в Azure Keyvault иметь возможность читать Секреты (Нет доступа к записи!)
  • Создание секрета, который будет использоваться в переменной группе/трубопроводе

С Azure Provider , Terraform предлагает возможность управлять услугами Azure. Мы будем использовать его для создания ресурсов, упомянутых выше.

Приложение AAD + директор службы

Прежде всего, нам нужен директор службы, который может использоваться Azure DevOps для аутентификации против Azure. Соответствующий сценарий Terraform выглядит так:

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  = 24
}

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-12-31T00:00:00Z"
}

resource "azurerm_role_assignment" "contributor" {
  principal_id         = azuread_service_principal.azdevopssp.id
  scope                = "/subscriptions/${data.azurerm_client_config.current.subscription_id}"
  role_definition_name = "Contributor"
}

С помощью сценария, показанного выше, генерируются как приложение AAD, так и принципал сервиса. Обратите внимание, что директору службы назначается роль Участник — На уровне подписки см. Область назначение. Это должно быть ограничено соответственно в ваших собственных проектах (например, для соответствующей группы ресурсов)!

Azure Keyvault

Keyvault создается так же, как и предыдущие ресурсы. Важно отметить, что пользователю, работающему против Azure, предоставляется полный доступ к секретам в KeyVault. Далее в сценарии разрешения для принципала услуги Azure DevOps также предоставляются в Keyvault — но в этом случае только Прочитайте разрешения ! И последнее, но не менее важное, соответствующий секрет, называемый kvmysupersecretsecret создан, который мы можем использовать для проверки интеграции.

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         = "kvmysupersecretsecret"
  value        = "KeyVault for the Win!"
}

Если вы выполнили шаги, описанные выше, результатом в Azure является недавно созданный Keyvault, содержащий один секрет:

Azure Keyvault

Сервисное соединение

Теперь нам нужна интеграция в Azure DevOps, потому что мы, наконец, хотим получить доступ к недавно созданному секрету в трубопроводе. Azure DevOps — это «по природе», способная получить доступ к Keyvault и секретам, которые он содержит. Однако для этого вы должны выполнить некоторые ручные шаги — когда не использовать Terraform — чтобы обеспечить доступ к Azure. К счастью, теперь они могут быть автоматизированы с Terraform. Следующие ресурсы используются для создания сервисного соединения с Azure в Azure DevOps и для предоставления доступа к нашему проекту:

## 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 = "dechrist - Microsoft Azure Internal Consumption"
}

## 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 
}

Сервисное соединение

Создание группы переменных Azure DevOps и определение трубопровода

Последний шаг, необходимый для использования KeyVault в конвейере, — это создание соответствующей группы переменной и «ссылки» существующего секрета.

## Pipeline with access to kv secret

resource "azuredevops_variable_group" "kvintegratedvargroup" {
  project_id   = azuredevops_project.project.id
  name         = "kvintegratedvargroup"
  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    = "kvmysupersecretsecret"
  }
}

Группа переменных с интеграцией KeyVault

Тестовый трубопровод

Все предпосылки сейчас на месте, но нам все еще нужен трубопровод, с помощью которого мы можем проверить сценарий.

Сценарий для создания трубопровода:

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.kvintegratedvargroup.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"
  }
}

Определение трубопровода ( azure-pipeline-with-keyvault.yaml ):

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'

Если вы запустили сценарий Terraform и выдвинули файл трубопровода в репо, вы получите следующий результат в следующей сборке (секрет не Показан в консоли по соображениям безопасности, конечно!):

Вывод: группа интегрированных переменных KeyVault

Заворачивать

Настройка новых проектов Azure DevOps не всегда была самой легкой задачей, так как иногда требовались ручные шаги. С выпуском первой версии поставщика Terraform для Azure DevOps это изменилось почти резко:) Теперь вы можете — как один из последних строительных блоков для автоматизации в проекте DEV — создать много вещей через Terraform в Azure DevOps. В примере, показанном здесь, доступ к Azure Keyvault, включая создание соответствующего сервисного соединения, может быть достигнут. Тем не менее, здесь был показан только один модуль — откровенно говоря, один для задачи, которая «раздражала» меня время от времени, так как большая часть этого должна была быть создана вручную, прежде чем иметь поставщика терраформ. Поставщик также может управлять политиками филиалов, настраивать группы, членство в группе и т. Д. С этим первым релизом вы все еще «в начале путешествия», но, на мой взгляд, это «очень хороший старт», с которым вы можете добиться многого.

Мне любопытно, что будет поддержано дальше!

Пример файлов можно найти здесь: https://gist.github.com/cdennig/4866a74b341a0079b5a59052fa735dbc

Оригинал: «https://dev.to/cdennig/azure-devops-terraform-provider-22fb»