Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Serviços de DevOps do Azure | Azure DevOps Server | Azure DevOps Server 2022 | Azure DevOps Server 2020
Importante
- Os nomes de trabalho e de estágio não devem entrar em conflito com palavras-chave reservadas (como
deployment
para o tipo de trabalho) - Cada trabalho numa fase deve ter um nome exclusivo.
Nos pipelines do YAML, recomendamos que coloque os passos de implementação num tipo especial de trabalho chamado trabalho de implementação. Um trabalho de implementação é uma coleção de passos executados sequencialmente no ambiente. Um trabalho de implantação e um trabalho tradicional podem existir no mesmo estágio. O Azure DevOps dá suporte às estratégias runOnce, rolling e canary.
Os trabalhos de implementação apresentam os seguintes benefícios:
- Histórico de implementações: obtém o histórico de implementações em todos os pipelines, até um recurso específico e o status das implementações para auditoria.
- Aplicar estratégia de implementação: define como a aplicação é desenvolvida.
Um trabalho de implementação não clona automaticamente o repositório de origem. Você pode verificar o repositório de origem dentro do seu trabalho com checkout: self
.
Nota
Este artigo se concentra na implantação com trabalhos de implantação. Para saber como implantar no Azure com pipelines, consulte Visão geral de Implantar no Azure.
Esquema
Vá para o esquema YAML para ver as definições jobs.deployment e jobs.deployment.environment.
Para máquinas virtuais, não é necessário definir um pool. Todas as etapas definidas em um trabalho de implantação com um recurso de máquina virtual são executadas nessa máquina virtual e não no agente no pool. Para outros tipos de recursos, como o Kubernetes, você precisa definir um pool para que as tarefas possam ser executadas nessa máquina.
Estratégias de implementação
Ao implantar atualizações de aplicativos, é importante que a técnica usada para entregar a atualização seja:
- Habilite a inicialização.
- Implante a atualização.
- Encaminhe o tráfego para a versão atualizada.
- Teste a versão atualizada após rotear o tráfego.
- Em caso de falha, execute as etapas para restaurar para a última versão válida.
Conseguimos isso usando ganchos do ciclo de vida que permitem executar etapas durante a implementação. Cada um dos ganchos do ciclo de vida é resolvido em um trabalho de agente ou um trabalho de servidor (ou um contêiner ou trabalho de validação no futuro), dependendo do pool
atributo. Por padrão, os ganchos do ciclo de vida herdam o pool
especificado pelo trabalho deployment
.
Os trabalhos de implantação usam a $(Pipeline.Workspace)
variável de sistema.
Descrições de ganchos de ciclo de vida
preDeploy
: Usado para executar etapas que inicializam recursos antes do início da implantação do aplicativo.
deploy
: Usado para executar etapas que implantam seu aplicativo. A tarefa de download de artefato é injetada automaticamente somente no hook de deploy
para trabalhos de implantação. Para interromper o download de artefatos, use - download: none
ou escolha artefatos específicos para download especificando a tarefa Baixar Artefato de Pipeline.
routeTraffic
: Usado para executar passos que direcionam o tráfego para a versão atualizada.
postRouteTraffic
: Usado para executar as etapas depois que o tráfego é roteado. Normalmente, essas tarefas monitoram a integridade da versão atualizada para um intervalo definido.
on: failure
ou on: success
: Usado para executar etapas para ações de reversão ou limpeza.
Estratégia de implantação do RunOnce
runOnce é a estratégia de implantação mais simples em que todos os ganchos do ciclo de vida, ou seja, preDeploy
deploy
, routeTraffic
e postRouteTraffic
, são executados uma vez. Em seguida, ou on:
success
ou on:
failure
é executado.
strategy:
runOnce:
preDeploy:
pool: [ server | pool ] # See pool schema.
steps:
- script: [ script | bash | pwsh | powershell | checkout | task | templateReference ]
deploy:
pool: [ server | pool ] # See pool schema.
steps:
...
routeTraffic:
pool: [ server | pool ]
steps:
...
postRouteTraffic:
pool: [ server | pool ]
steps:
...
on:
failure:
pool: [ server | pool ]
steps:
...
success:
pool: [ server | pool ]
steps:
...
Se estiveres a usar agentes autoalojados, podes utilizar as opções de limpeza do espaço de trabalho para limpar o espaço de implantação.
jobs:
- deployment: MyDeploy
pool:
vmImage: 'ubuntu-latest'
workspace:
clean: all
environment: staging
Estratégia de implementação contínua
Um de implantação progressiva substitui instâncias da versão anterior de uma aplicação por instâncias da nova versão da aplicação em um conjunto fixo de máquinas virtuais (conjunto em rotação) em cada iteração.
Atualmente, oferecemos suporte apenas à estratégia contínua para recursos de VM.
Por exemplo, uma implantação sem interrupção normalmente aguarda a conclusão das implantações em cada conjunto de máquinas virtuais antes de prosseguir para o próximo conjunto de implantações. Você pode fazer uma verificação de integridade após cada iteração e, se ocorrer um problema significativo, a implantação contínua pode ser interrompida.
As implantações contínuas podem ser configuradas especificando a palavra-chave rolling:
dentro do nó strategy:
.
A strategy.name
variável está disponível neste bloco de estratégia, que leva o nome da estratégia. Neste caso, rolando.
strategy:
rolling:
maxParallel: [ number or percentage as x% ]
preDeploy:
steps:
- script: [ script | bash | pwsh | powershell | checkout | task | templateReference ]
deploy:
steps:
...
routeTraffic:
steps:
...
postRouteTraffic:
steps:
...
on:
failure:
steps:
...
success:
steps:
...
Todos os ganchos de ciclo de vida são suportados, e as tarefas de gancho de ciclo de vida são criadas para serem executadas em todas as VMs.
preDeploy
, deploy
, routeTraffic
e postRouteTraffic
são executados uma vez por tamanho de lote definido por maxParallel
.
Em seguida, ou on: success
ou on: failure
é executado.
Com o maxParallel: <# or % of VMs>
, pode controlar o número/percentagem de alvos de máquinas virtuais para implementar em simultâneo. Isso garante que o aplicativo esteja sendo executado nessas máquinas e seja capaz de lidar com solicitações enquanto a implantação está ocorrendo no restante das máquinas, o que reduz o tempo de inatividade geral.
Nota
Existem algumas lacunas conhecidas neste recurso. Por exemplo, quando repete um estágio, ele executa novamente a implantação em todas as VMs, não apenas nos alvos falhados.
Estratégia de implementação canário
O de estratégia de implantação do Canary é uma estratégia de implantação avançada que ajuda a reduzir o risco envolvido na implantação de novas versões de aplicativos. Usando essa estratégia, você pode distribuir as alterações para um pequeno subconjunto de servidores primeiro. À medida que você ganha mais confiança na nova versão, pode liberá-la para mais servidores em sua infraestrutura e rotear mais tráfego para ela.
strategy:
canary:
increments: [ number ]
preDeploy:
pool: [ server | pool ] # See pool schema.
steps:
- script: [ script | bash | pwsh | powershell | checkout | task | templateReference ]
deploy:
pool: [ server | pool ] # See pool schema.
steps:
...
routeTraffic:
pool: [ server | pool ]
steps:
...
postRouteTraffic:
pool: [ server | pool ]
steps:
...
on:
failure:
pool: [ server | pool ]
steps:
...
success:
pool: [ server | pool ]
steps:
...
A estratégia de implantação Canary suporta o gancho de ciclo de vida preDeploy
(executado uma vez) e itera com os ganchos de ciclo de vida deploy
, routeTraffic
e postRouteTraffic
. Em seguida, ele sai com o gancho success
ou failure
.
As seguintes variáveis estão disponíveis nesta estratégia:
strategy.name
: Nome da estratégia. Por exemplo, canário.
strategy.action
: A ação a ser executada no cluster Kubernetes. Por exemplo, implantar, promover ou rejeitar.
strategy.increment
: O valor de incremento usado na interação atual. Esta variável está disponível apenas em deploy
, routeTraffic
, e postRouteTraffic
ganchos de ciclo de vida.
Exemplos
Estratégia de implantação do RunOnce
O trecho YAML de exemplo a seguir mostra um uso simples de uma tarefa de distribuição usando a runOnce
estratégia de implantação. O exemplo inclui uma etapa de finalização de compra.
jobs:
# Track deployments on the environment.
- deployment: DeployWeb
displayName: deploy Web App
pool:
vmImage: 'ubuntu-latest'
# Creates an environment if it doesn't exist.
environment: 'smarthotel-dev'
strategy:
# Default deployment strategy, more coming...
runOnce:
deploy:
steps:
- checkout: self
- script: echo my first deployment
A cada execução deste trabalho, o histórico de implantação é registrado no ambiente smarthotel-dev
.
Nota
- Também é possível criar um ambiente com recursos vazios e usá-lo como um shell abstrato para registrar o histórico de implantação, como mostrado no exemplo anterior.
O próximo exemplo demonstra como um pipeline pode designar um ambiente e um recurso como alvo para uma tarefa de implantação.
jobs:
- deployment: DeployWeb
displayName: deploy Web App
pool:
vmImage: 'ubuntu-latest'
# Records deployment against bookings resource - Kubernetes namespace.
environment: 'smarthotel-dev.bookings'
strategy:
runOnce:
deploy:
steps:
# No need to explicitly pass the connection details.
- task: KubernetesManifest@1
displayName: Deploy to Kubernetes cluster
inputs:
action: deploy
namespace: $(k8sNamespace)
manifests: |
$(System.ArtifactsDirectory)/manifests/*
imagePullSecrets: |
$(imagePullSecret)
containers: |
$(containerRegistry)/$(imageRepository):$(tag)
Esta abordagem tem os seguintes benefícios:
- Registra o histórico de implantação em um recurso específico dentro do ambiente, em vez de registrar o histórico em todos os recursos dentro do ambiente.
- As etapas no trabalho de implantação herdam automaticamente os detalhes de conexão do recurso (neste caso, um namespace Kubernetes,
smarthotel-dev.bookings
), porque o trabalho de implantação está vinculado ao ambiente. Isso é útil nos casos em que o mesmo detalhe de conexão é definido para várias etapas do trabalho.
Nota
Se estiver a utilizar um cluster AKS privado, certifique-se de que está ligado à rede virtual do cluster, uma vez que o ponto de extremidade do servidor API não está exposto através de um endereço IP público.
O Azure Pipelines recomenda configurar um agente auto-hospedado em uma VNET que tenha acesso à rede virtual do cluster. Consulte Opções para conexão com o cluster privado para obter detalhes.
Estratégia de implementação contínua
A estratégia de atualização contínua para VMs atualiza até cinco alvos em cada iteração.
maxParallel
determina o número de alvos que podem ser implantados simultaneamente. A seleção leva em conta o número absoluto ou a porcentagem de metas que devem permanecer disponíveis a qualquer momento, excluindo as metas para as quais estão sendo implantadas. Ele também é usado para determinar as condições de sucesso e falha durante a implantação.
jobs:
- deployment: VMDeploy
displayName: web
environment:
name: smarthotel-dev
resourceType: VirtualMachine
strategy:
rolling:
maxParallel: 5 # for percentages, mention as x%
preDeploy:
steps:
- download: current
artifact: drop
- script: echo initialize, cleanup, backup, install certs
deploy:
steps:
- task: IISWebAppDeploymentOnMachineGroup@0
displayName: 'Deploy application to Website'
inputs:
WebSiteName: 'Default Web Site'
Package: '$(Pipeline.Workspace)/drop/**/*.zip'
routeTraffic:
steps:
- script: echo routing traffic
postRouteTraffic:
steps:
- script: echo health check post-route traffic
on:
failure:
steps:
- script: echo Restore from backup! This is on failure
success:
steps:
- script: echo Notify! This is on success
Estratégia de implementação canário
No próximo exemplo, a estratégia canário para AKS implantará primeiramente as mudanças com 10% dos pods, seguidas por 20%, enquanto monitoriza a saúde do sistema durante postRouteTraffic
. Se tudo correr bem, vai subir a 100 por cento.
jobs:
- deployment:
environment: smarthotel-dev.bookings
pool:
name: smarthotel-devPool
strategy:
canary:
increments: [10, 20]
preDeploy:
steps:
- script: initialize, cleanup....
deploy:
steps:
- script: echo deploy updates...
- task: KubernetesManifest@1
inputs:
action: $(strategy.action)
namespace: 'default'
strategy: $(strategy.name)
percentage: $(strategy.increment)
manifests: 'manifest.yml'
postRouteTraffic:
pool: server
steps:
- script: echo monitor application health...
on:
failure:
steps:
- script: echo clean-up, rollback...
success:
steps:
- script: echo checks passed, notify...
Use decoradores de tubulação para injetar etapas automaticamente
decoradores de pipeline podem ser usados em trabalhos de implantação para injetar automaticamente qualquer etapa personalizada (por exemplo, scanner de vulnerabilidade) para cada gancho de ciclo de vida execução de cada trabalho de implantação. Como os decoradores de pipeline podem ser aplicados a todos os pipelines em uma organização, isso pode ser aplicado como uma parte da implementação de práticas de implantação seguras.
Além disso, os trabalhos de implantação podem ser executados como um trabalho de contêiner junto com o side-car de serviços, se definido.
Suporte para variáveis de saída
Defina variáveis de saída nos lifecycle hooks de um job de deployment e consuma-as em outros steps e jobs downstream dentro do mesmo estágio.
Para compartilhar variáveis entre estágios, produza um artefato em um estágio e consuma-o em um estágio subsequente ou use a stageDependencies
sintaxe descrita em variáveis.
Ao executar estratégias de implantação, você pode acessar variáveis de saída entre trabalhos usando a sintaxe a seguir.
- Para a estratégia runOnce:
$[dependencies.<job-name>.outputs['<job-name>.<step-name>.<variable-name>']]
(por exemplo,$[dependencies.JobA.outputs['JobA.StepA.VariableA']]
) - Para a estratégia runOnce mais um tipo de recurso:
$[dependencies.<job-name>.outputs['Deploy_<resource-name>.<step-name>.<variable-name>']]
. (por exemplo,$[dependencies.JobA.outputs['Deploy_VM1.StepA.VariableA']]
) - Para a estratégia canária :
$[dependencies.<job-name>.outputs['<lifecycle-hookname>_<increment-value>.<step-name>.<variable-name>']]
- Para a estratégia de rotação:
$[dependencies.<job-name>.outputs['<lifecycle-hookname>_<resource-name>.<step-name>.<variable-name>']]
# Set an output variable in a lifecycle hook of a deployment job executing canary strategy.
- deployment: A
pool:
vmImage: 'ubuntu-latest'
environment: staging
strategy:
canary:
increments: [10,20] # Creates multiple jobs, one for each increment. Output variable can be referenced with this.
deploy:
steps:
- bash: echo "##vso[task.setvariable variable=myOutputVar;isOutput=true]this is the deployment variable value"
name: setvarStep
- bash: echo $(setvarStep.myOutputVar)
name: echovar
# Map the variable from the job.
- job: B
dependsOn: A
pool:
vmImage: 'ubuntu-latest'
variables:
myVarFromDeploymentJob: $[ dependencies.A.outputs['deploy_10.setvarStep.myOutputVar'] ]
steps:
- script: "echo $(myVarFromDeploymentJob)"
name: echovar
Para um runOnce
trabalho, especifique o nome do trabalho em vez do gancho do ciclo de vida:
# Set an output variable in a lifecycle hook of a deployment job executing runOnce strategy.
- deployment: A
pool:
vmImage: 'ubuntu-latest'
environment: staging
strategy:
runOnce:
deploy:
steps:
- bash: echo "##vso[task.setvariable variable=myOutputVar;isOutput=true]this is the deployment variable value"
name: setvarStep
- bash: echo $(setvarStep.myOutputVar)
name: echovar
# Map the variable from the job.
- job: B
dependsOn: A
pool:
vmImage: 'ubuntu-latest'
variables:
myVarFromDeploymentJob: $[ dependencies.A.outputs['A.setvarStep.myOutputVar'] ]
steps:
- script: "echo $(myVarFromDeploymentJob)"
name: echovar
Quando você define um ambiente em um trabalho de implantação, a sintaxe da variável de saída varia dependendo de como o ambiente é definido. Neste exemplo, env1
usa notação abreviada e env2
inclui a sintaxe completa com um tipo de recurso definido.
stages:
- stage: StageA
jobs:
- deployment: A1
pool:
vmImage: 'ubuntu-latest'
environment: env1
strategy:
runOnce:
deploy:
steps:
- bash: echo "##vso[task.setvariable variable=myOutputVar;isOutput=true]this is the deployment variable value"
name: setvarStep
- bash: echo $(System.JobName)
- deployment: A2
pool:
vmImage: 'ubuntu-latest'
environment:
name: env2
resourceName: vmsfortesting
resourceType: virtualmachine
strategy:
runOnce:
deploy:
steps:
- script: echo "##vso[task.setvariable variable=myOutputVarTwo;isOutput=true]this is the second deployment variable value"
name: setvarStepTwo
- job: B1
dependsOn: A1
pool:
vmImage: 'ubuntu-latest'
variables:
myVarFromDeploymentJob: $[ dependencies.A1.outputs['A1.setvarStep.myOutputVar'] ]
steps:
- script: "echo $(myVarFromDeploymentJob)"
name: echovar
- job: B2
dependsOn: A2
pool:
vmImage: 'ubuntu-latest'
variables:
myVarFromDeploymentJob: $[ dependencies.A2.outputs['A2.setvarStepTwo.myOutputVarTwo'] ]
myOutputVarTwo: $[ dependencies.A2.outputs['Deploy_vmsfortesting.setvarStepTwo.myOutputVarTwo'] ]
steps:
- script: "echo $(myOutputVarTwo)"
name: echovartwo
Quando você produz uma variável de um trabalho no estágio um, fazer referência a ela a partir de um trabalho de implantação no próximo estágio usa sintaxe diferente, dependendo se você deseja definir uma variável ou usá-la como condição para o estágio.
stages:
- stage: StageA
jobs:
- job: A1
steps:
- pwsh: echo "##vso[task.setvariable variable=RunStageB;isOutput=true]true"
name: setvarStep
- bash: echo $(System.JobName)
- stage: StageB
dependsOn:
- StageA
# when referring to another stage, stage name is included in variable path
condition: eq(dependencies.StageA.outputs['A1.setvarStep.RunStageB'], 'true')
# Variables reference syntax differs slightly from inter-stage condition syntax
variables:
myOutputVar: $[stageDependencies.StageA.A1.outputs['setvarStep.RunStageB']]
jobs:
- deployment: B1
pool:
vmImage: 'ubuntu-latest'
environment: envB
strategy:
runOnce:
deploy:
steps:
- bash: echo $(myOutputVar)
Quando se exporta uma variável de um trabalho de implementação, use a sintaxe stageDependencies para a referenciar a partir do estágio seguinte (por exemplo, $[stageDependencies.<stage-name>.<job-name>.outputs[Deploy_<resource-name>.<step-name>.<variable-name>]]
).
stages:
- stage: StageA
jobs:
- deployment: A1
environment:
name: env1
resourceName: DevEnvironmentV
resourceType: virtualMachine
strategy:
runOnce:
deploy:
steps:
- script: echo "##vso[task.setvariable variable=myVar;isOutput=true]true"
name: setvarStep
- script: |
echo "Value of myVar in the same Job : $(setVarStep.myVar)"
displayName: 'Verify variable in StageA'
- stage: StageB
dependsOn: StageA
# Full Variables syntax for inter-stage jobs
variables:
myOutputVar: $[stageDependencies.StageA.A1.outputs['Deploy_DevEnvironmentV.setvarStep.myVar']]
jobs:
- deployment: B1
pool:
vmImage: 'ubuntu-latest'
environment: envB
strategy:
runOnce:
deploy:
steps:
- bash: echo $(myOutputVar)
Saiba mais sobre como definir uma variável de saída multitarefa
FAQ
O meu pipeline está preso com a mensagem "Tarefa pendente...". Como posso corrigir isso?
Isso pode acontecer quando há um conflito de nome entre dois trabalhos. Certifique-se de que todos os trabalhos de implementação no mesmo estágio tenham um nome exclusivo e de que os nomes dos trabalhos e dos estágios não contenham palavras-chave. Se a renomeação não corrigir o problema, reveja as execuções do pipeline de resolução de problemas.
Os decoradores são apoiados em grupos de implantação?
N.º Não é possível usar decoradores em grupos de implantação.