我应该使用terraform termplate或devops管道在公共云中上传多个区域的docker图像吗



这听起来可能很天真,我必须上传公共云中所有订阅区域的docker图像。我计划在地形模板中完成这项工作,并将创建一个具有多个local-exec提供者的null_resource,以登录docker repo、docker标签和docker推送。

在未来,我们可以订阅更多的云区域,这样区域的数量在未来可能会发生变化。

我不确定地形是一个更好的选择,或者我应该考虑一些devops管道。我对地形有基本的了解,不知道devops管道是如何工作的?

有什么建议吗?

两者都可以,所以我有Terraform来制作我的所有资源,然后我使用Azure开发人员操作管道来实现这一神奇。

这是我的管道代码,我用来旋转地形:

parameters:
- name: terraformWorkingDirectory
type: string
default: $(System.DefaultWorkingDirectory)/Terraform
- name: serviceConnection
type: string
default: VALUE
- name: azureSubscription
type: string
default: VALUE
- name: appconnectionname
type: string
default: VALUE
- name: backendresourcegroupname   
type: string
default: Terraform
- name: backendstorageaccountname
type: string
default: terraform
- name: backendcontainername
type: string
default: terraformstatefile
- name: RG
type: string
default: rg_example
- name: azureLocation
type: string
default: UK South
- name: terraformVersion
type: string
default: 1.0.4
- name: artifactName
type: string
default: Website
jobs:
- job: Run_Terraform
displayName: Installing and Running Terraform
steps:
- checkout: Terraform
- task: TerraformInstaller@0
displayName: install
inputs:
terraformVersion: '${{ parameters.terraformVersion }}'
- task: CmdLine@2
inputs:
script: |
echo  '$(System.DefaultWorkingDirectory)' 
dir
- task: TerraformTaskV2@2
displayName: init
inputs:
provider: azurerm
command: init
backendServiceArm: '${{ parameters.serviceConnection }}'
backendAzureRmResourceGroupName: '${{ parameters.backendresourcegroupname }}'
backendAzureRmStorageAccountName: '${{ parameters.backendstorageaccountname }}'
backendAzureRmContainerName: '${{ parameters.backendcontainername }}'
backendAzureRmKey: terraform.tfstate
workingDirectory: '${{ parameters.terraformWorkingDirectory }}'
- task: TerraformTaskV1@0
displayName: plan
inputs:
provider: azurerm
command: plan
commandOptions: '-input=false'
environmentServiceNameAzureRM: '${{ parameters.serviceConnection }}'
workingDirectory: '${{ parameters.terraformWorkingDirectory }}'
- task: TerraformTaskV1@0
displayName: apply
inputs:
provider: azurerm
command: apply
commandOptions: '-input=false -auto-approve'
environmentServiceNameAzureRM: '${{ parameters.serviceConnection }}'
workingDirectory: '${{ parameters.terraformWorkingDirectory }}'
- job: Put_artifacts_into_place
displayName: Putting_artifacts_into_place
dependsOn: Run_Terraform
steps:
- checkout: Website
- checkout: AuthenticationServer
- task: DownloadPipelineArtifact@2
displayName: Download Build Artifacts
inputs:
artifact: '${{ parameters.artifactName }}'
patterns: /**/*.zip
path: '$(Pipeline.Workspace)'
- task: AzureWebApp@1
displayName: 'Azure Web App Deploy: VALUE'
inputs:
package: $(Pipeline.Workspace)**/*.zip
azureSubscription: '${{ parameters.azureSubscription }}'
ConnectedServiceName: '${{ parameters.appconnectionname}}'
appName: VALUE
ResourceGroupName: '${{ parameters.RG}}'
- task: DownloadPipelineArtifact@2
displayName: Download Build Artifacts
inputs:
artifact: '${{ parameters.artifactName}}'
patterns: /authsrv/**/*.zip
path: $(Pipeline.Workspace)/authsrv/

- task: AzureWebApp@1
displayName: 'Azure Web App Deploy: VALUE'
inputs:
package: $(Pipeline.Workspace)/authsrv/**/*.zip
azureSubscription: '${{ parameters.azureSubscription }}'
ConnectedServiceName: '${{ parameters.appconnectionname}}'
appName: VALUE
ResourceGroupName: '${{ parameters.RG}}'

你要做的是在Git或Azure中进行回购。在Azure中这会更容易,因为你不必与Git建立服务连接,所以出错的次数更少。。。

一旦你有了一个repo,你就必须设置一个远程后端,我使用以下azure命令完成了这项工作:

New-AzureRmResourceGroup -Name "myTerraformbackend" -Location "UK South"
New-AzureRmStorageAccount -ResourceGroupName "myTerraformbackend" -AccountName "myterraformstate" -Location UK South -SkuName Standard_LRS
New-AzureRmStorageContainer -ResourceGroupName "myTerraformbackend" -AccountName "nsdevopsterraform" -ContainerName "terraformstatefile"

我还关注了Julie Ng的这篇很棒的博客文章,她在微软工作,她谈到了远程状态文件的最佳实践:https://julie.io/writing/terraform-on-azure-pipelines-best-practices/她还在youtube频道获得了巨大的帮助。

在我的地形代码中,我还使用了一堆本地变量,它们很方便,但要确保你创建了一些原始的东西,你可以引用我的资源组id。这是第一个设置的东西,然后我的所有资源都引用该id。

这里看:

locals {
# Ids for Resource Group, merged together with unique string
resource_group_id_full_value = format("${azurerm_resource_group.terraform.id}")
resource_group_id            = substr(("${azurerm_resource_group.terraform.id}"), 15, 36)
resource_group_id_for_login = substr(("${azurerm_resource_group.terraform.id}"), 15, 8)
sql_admin_login             = format("${random_string.sql_name_random.id}-${local.resource_group_id_for_login}")
sql_server_name = format("sqlserver-${local.resource_group_id}")
sql_server_database_name = format("managerserver-${local.resource_group_id}")
}

随着时间的推移,你会更加真正地理解这一点。

我不使用null_resource。我在这里看到很多人对它们有问题,我很少使用它们。

如果你打算使用Terraform作为码头,请考虑Terraform的新功能,Terraform航路点:https://www.hashicorp.com/blog/announcing-waypoint

您现在也有Terraform工作区来处理远程状态,但我还没有时间对此进行研究。

我希望这些信息是有用的,是一个很好的开始参考。

最新更新