练习 - 预配 Azure 资源
在本练习中,你将配置自动化工作流以预配 Terraform 资源。
访问示例应用程序
在本练习中,你将通过一个模板来创建 GitHub 存储库,该模板包含预配 Terraform 的所有代码。
在 GitHub 上,转到存储库的主页:
https://github.com/MicrosoftDocs/mslearn-java-petclinic-simplified
在文件列表上方,选择“使用此模板”,然后选择“创建新存储库”。
在“存储库名称”框中,为你的存储库输入独一无二的名称。 请务必遵循 GitHub 存储库的命名约定。
确保选中“专用”选项,然后选择“创建存储库”。
工作流
在你刚才创建的存储库的项目目录中,你会看到一个名为 terraform 的目录,其中有一个名为 main.tf 的文件。
下面,让我们看看几个可以用来定义模块配置的部分:
- 提供程序:Terraform 配置文件从提供程序的规范开始。 使用 Azure 时,你在提供程序块中指定 Azure 提供程序 (
azurerm
)。 - Terraform:正在使用的 Terraform 版本。
- 数据:从现有服务中获取数据。
- 局部变量:使用函数和表达式生成新变量。
- 资源:描述资源和依赖项。
- 模块:可重用性和复杂性抽象。
若要预配应用程序和数据库,只需包括“提供程序”和“资源”部分即可。
接下来,打开 main.tf 文件,并查看大纲和注释:
provider "azurerm" {
version = "=2.20.0"
features {}
}
# Creates a resource group
resource "azurerm_resource_group" "main" {
name = var.resource_group
location = var.location
tags = {
"Terraform" = "true"
}
}
resource "random_password" "password" {
length = 32
special = true
override_special = "_%@"
}
# Creates a MySQL server
resource "azurerm_mysql_server" "main" {
name = "${azurerm_resource_group.main.name}-mysql-server"
location = azurerm_resource_group.main.location
resource_group_name = azurerm_resource_group.main.name
administrator_login = "petclinic"
administrator_login_password = random_password.password.result
sku_name = "B_Gen5_1"
storage_mb = 5120
version = "5.7"
auto_grow_enabled = true
backup_retention_days = 7
geo_redundant_backup_enabled = false
infrastructure_encryption_enabled = false
public_network_access_enabled = true
ssl_enforcement_enabled = true
ssl_minimal_tls_version_enforced = "TLS1_2"
}
# The database that your application will use
resource "azurerm_mysql_database" "main" {
name = "${azurerm_resource_group.main.name}_mysql_db"
resource_group_name = azurerm_resource_group.main.name
server_name = azurerm_mysql_server.main.name
charset = "utf8"
collation = "utf8_unicode_ci"
}
# Enables the 'Allow access to Azure services' check box
resource "azurerm_mysql_firewall_rule" "main" {
name = "${azurerm_resource_group.main.name}-mysql-firewall"
resource_group_name = azurerm_resource_group.main.name
server_name = azurerm_mysql_server.main.name
start_ip_address = "0.0.0.0"
end_ip_address = "0.0.0.0"
}
# Creates the plan that the service uses
resource "azurerm_app_service_plan" "main" {
name = "${var.application_name}-plan"
location = azurerm_resource_group.main.location
resource_group_name = azurerm_resource_group.main.name
kind = "Linux"
reserved = true
sku {
tier = "PremiumV2"
size = "P1v2"
}
}
# Creates the service definition
resource "azurerm_app_service" "main" {
name = var.application_name
location = azurerm_resource_group.main.location
resource_group_name = azurerm_resource_group.main.name
app_service_plan_id = azurerm_app_service_plan.main.id
https_only = true
site_config {
always_on = true
linux_fx_version = "JAVA|8-jre8"
}
# Contains application-specific environment variables
app_settings = {
"WEBSITES_ENABLE_APP_SERVICE_STORAGE" = "false"
"SPRING_PROFILES_ACTIVE" = "mysql"
"SPRING_DATASOURCE_URL" = "jdbc:mysql://${azurerm_mysql_server.main.fqdn}:3306/${azurerm_mysql_database.main.name}?useUnicode=true&characterEncoding=utf8&useSSL=true&useLegacyDatetimeCode=false&serverTimezone=UTC"
"SPRING_DATASOURCE_USERNAME" = "${azurerm_mysql_server.main.administrator_login}@${azurerm_mysql_server.main.name}"
"SPRING_DATASOURCE_PASSWORD" = azurerm_mysql_server.main.administrator_login_password
}
}
通过 Terraform 设置 GitHub Actions 工作流
让我们向你的 GitHub 工作流提供对你的 Azure 帐户的访问权限。
在 Azure CLI 中,运行以下命令来创建一个服务主体:
重要
将 <yourServicePrincipalName> 替换为要使用的服务主体名称。
az ad sp create-for-rbac --name "<yourServicePrincipalName>" --role contributor --scopes /subscriptions/<subscriptionId> --sdk-auth
前面的命令会返回以下 JSON。 复制它供下一步使用:
{
"clientId": "XXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXXX",
"clientSecret": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"subscriptionId": "XXXXXXXXX-XXXXX-XXXX-XXXX-XXXXXXXXXXXXX",
"tenantId": "XXXXXXXX-XXXXX-XXXX-XXXX-XXXXXXXXXXX",
...
}
GitHub 机密
GitHub 存储库有一项称为“机密”的功能,你可以使用该功能存储 Terraform 用来向 Azure 进行身份验证的敏感信息。
在前面的步骤中创建所需的 ID 和机密后,本单元中的下一步是将它们添加到 GitHub 项目中的“机密”存储。
对于本练习,你需要存储以下机密:
AZURE_CLIENT_ID
AZURE_CLIENT_SECRET
AZURE_SUBSCRIPTION_ID
AZURE_TENANT_ID
若要存储机密,请转到你的已分支的 GitHub 存储库,选择“设置”,选择“机密和变量”,然后在左侧窗格中选择“操作”。
使用创建服务主体时返回的值创建四个机密。
请确保在不带引号 (" ") 的情况下存储机密,如以下屏幕截图所示:
工作流文件
你的项目目录中有一个名为 .github/workflows 的目录,其中有一个名为 main.yml 的文件。
main.yml 文件是一个 GitHub 工作流。 它使用你刚才配置的机密将应用程序部署到 Azure 订阅。
在 main.yml 工作流文件中,你将发现以下内容:
name: TERRAFORM
on:
push:
branches: [ main ]
paths:
- 'terraform/**'
pull_request:
branches: [ main ]
paths:
- 'terraform/**'
workflow_dispatch:
jobs:
terraform:
runs-on: ubuntu-latest
env:
ARM_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
ARM_CLIENT_SECRET: ${{secrets.AZURE_CLIENT_SECRET}}
ARM_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
ARM_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
defaults:
run:
working-directory: ./terraform
steps:
- uses: actions/checkout@v2
- name: Setup Terraform
uses: hashicorp/setup-terraform@v1
- name: Terraform Init
run: terraform init
- name: Terraform Plan
run: terraform plan
- name: Terraform Apply
run: terraform apply -auto-approve
此工作流执行以下操作:
- 检查配置格式是否正确。
- 为每个拉取请求生成一个计划。
- 在你更新 terraform 目录中的文件时触发配置。
注意
通过转到“操作”,然后选择 Terraform 工作流和“重新运行现有作业”,也可触发 GitHub Actions 工作流。
触发工作流
接下来,在存储库中通过以下操作来触发 GitHub 操作:
在内置的 GitHub 文本编辑器或你选择的编辑器中,按照以下说明编辑 terraform/variables.tf:
a. 将
"CHANGE_ME_RESOURCE_GROUP"
更改为你所需的资源组名称。
b. 将"CHANGE_ME_APP_NAME"
更改为你所需的应用程序名称。 确保应用程序名称独一无二。variable "resource_group" { description = "The resource group" default = "CHANGE_ME_RESOURCE_GROUP" } variable "application_name" { description = "The Spring Boot application name" default = "CHANGE_ME_APP_NAME" } variable "location" { description = "The Azure location where all resources in this example should be created" default = "westeurope" }
提交更改。
验证 GitHub Actions 生成
在你的存储库中选择“操作”,然后在左窗格中选择 TERRAFORM 工作流。
在步骤列表中,验证是否已触发“Terraform 初始化”、“Terraform 计划”和“Terraform 验证”。
在步骤列表中,展开“Terraform 应用”,并验证:
Terraform 是否已创建资源并显示 Azure 实例 URL。
你的 Azure 应用实例是否公开可用。
后续步骤
在下一个练习中,你将使用 GitHub Actions 部署 Spring Boot 示例应用程序。
设置应用程序名称和 Azure 资源组
在 GitHub 存储库中,通过执行以下操作来编辑 Azure 资源名称:
在内置的 GitHub 文本编辑器或你选择的编辑器中,按照以下说明编辑 terraform/variables.tf:
a. 将
"<CHANGE_ME_RESOURCE_GROUP>"
更改为你所需的资源组名称。
b. 将"<CHANGE_ME_APP_NAME>"
更改为你所需的应用程序名称。 确保应用程序名称独一无二。variable "resource_group" { description = "The resource group" default = "<CHANGE_ME_RESOURCE_GROUP>" } variable "application_name" { description = "The Spring Boot application name" default = "CHANGE_ME_APP_NAME" } variable "location" { description = "The Azure location where all resources in this example should be created" default = "westeurope" }
提交更改
创建 Azure 管道以预配 Terraform 资源
在我们的 Azure DevOps 项目中,我们将创建两个单独的管道用于预配和生成并部署。 预配管道创建将在稍后通过“生成并部署”管道发布的 Azure 资源。
让我们创建第一个预配管道:
选择你的组织,然后选择“新建项目”。
指定下列参数。
参数 说明 项目名称 必需 说明 可选 能见度 选择“专用” 高级 版本控制 选择“GIT” 工作项进程 选择“基本” 选择“创建项目”,创建项目并打开欢迎页。
设置 Azure 管道服务连接
让我们为 Azure 管道授予对 Azure 帐户的访问权限。
在 Azure DevOps 中,从项目设置页打开“Service connections”页
依次选择“创建服务连接”、“Azure 资源管理器”和“下一步”。
依次选择“服务主体(自动)”和“下一步”。
指定下列参数。
参数 说明 范围级别 选择 Azure 订阅 订阅 选择你的现有 Azure 订阅 资源组 留空以允许用户访问订阅中定义的所有资源 连接名称 必需。 在任务属性中引用此服务连接时将使用的名称。 此名称不是 Azure 订阅的名称。 选择保存创建连接。
创建预配管道
重要
此模块的先决条件要求安装 Terraform Azure Pipelines 扩展。 如果尚未安装,则管道将无法运行。
设置项目并连接到 Azure 后,需要创建一个 Azure 管道来预配 terraform 资源。
在 Azure DevOps 中,转到你的项目,在左侧菜单中选择“管道”,然后选择“创建管道”。
- 在“连接”选项卡上,选择“GitHub”(YAML 文件)。
- 如果系统提示你授权 GitHub 访问权限,请输入 GitHub 凭据并使用请求的权限批准对 Azure Pipelines 的访问权限。
- 在“选择”选项卡上,选择包含模板的 GitHub 存储库。
- 在“清单”选项卡上,选择“配置管道”。
- 在“配置”选项卡上,选择以使用“现有的 Azure Pipelines YAML 文件”。
- 在路径中,选择“/azuredevops/provision.yml”
- 选择“继续”以转到“查看”选项卡并查看你的管道。
在“Review your pipeline YAML”屏幕上,让我们检查要用于创建管道的 YAML 文件。
name: Provision Resources
trigger: none
pool:
vmImage: 'ubuntu-latest'
steps:
# Initialize the Terraform environment and bind to your Service Connection
- task: TerraformTaskV1@0
inputs:
provider: 'azurerm'
command: 'init'
workingDirectory: $(Build.Repository.LocalPath)/terraform
backendServiceArm: $(serviceConnection)
backendAzureRmResourceGroupName: $(serviceConnection)
backendAzureRmStorageAccountName: $(serviceConnection)
backendAzureRmContainerName: 'tfstate'
backendAzureRmKey: 'tf/terraform.tfstate'
# Apply the Terraform config and deploy to Azure
- task: TerraformTaskV1@0
inputs:
provider: 'azurerm'
command: 'apply'
workingDirectory: $(Build.Repository.LocalPath)/terraform
backendAzureRmContainerName: 'tfstate'
backendAzureRmKey: 'tf/terraform.tfstate'
environmentServiceNameAzureRM: $(serviceConnection)
让我们来看看我们在配置中使用的一些字段:
- serviceConnection:你以前设置的 Azure 管道服务连接
- command:Terraform 工作流命令 - init 或 apply
- backendAzure:团队环境中存储共享状态所需的必填字段。\
在保存和运行管道之前,需要添加将绑定到服务连接的变量:
- 选择“变量”(右上角)并添加一个名为“serviceConnection”的变量,其值作为服务连接的名称。
- 选择“确定”(右下角)保存变量。
最后,选择“run”(右上角)保存并运行管道
监视管道运行
在“Jobs”下,跟踪生成过程的每个步骤。
当管道运行时,观察第一个 Terraform init 阶段和第二个 apply 阶段从蓝色(正在运行)变为绿色(已完成)。 你可以选择各个阶段来观察管道的运行情况。
提示
查看电子邮件。 你可能已收到包含运行结果的生成通知。 你可以使用这些通知来了解每个生成是通过还是失败。
后续步骤
在下一练习中,你将使用 Azure Pipelines 来生成和部署示例 Spring Boot 应用程序。