Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#IPV-22] Enable deploy on multiple app services #128

Merged
merged 3 commits into from
Jun 7, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 10 additions & 19 deletions .devops/code-review-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@
# - DANGER_GITHUB_API_TOKEN
#

variables:
NODE_VERSION: '10.14.1'
YARN_CACHE_FOLDER: $(Pipeline.Workspace)/.yarn

# Automatically triggered on PR
# https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=azure-devops&tabs=schema%2Cparameter-schema#pr-trigger
trigger: none

# Execute agents (jobs) on latest Ubuntu version.
# To change OS for a specific, ovverride "pool" attribute inside the job definition
pool:
vmImage: 'ubuntu-latest'

resources:
repositories:
- repository: pagopaCommons
Expand All @@ -22,20 +23,10 @@ resources:
ref: refs/tags/v14
endpoint: 'io-azure-devops-github-ro'

# This pipeline has been implemented to be run on hosted agent pools based both
# on 'windows' and 'ubuntu' virtual machine images and using the scripts defined
# in the package.json file. Since we are deploying on Azure functions on Windows
# runtime, the pipeline is currently configured to use a Windows hosted image for
# the build and deploy.
pool:
vmImage: 'ubuntu-latest'

stages:
# A) Build and code validation
- stage: Build
dependsOn: []
jobs:
# A1) Checkout, install module and build code
- job: make_build
pool:
# As we deploy on Wondows machines, we use Windows to build
Expand All @@ -45,15 +36,13 @@ stages:
- script: |
yarn build
displayName: 'Build'

- stage: Static_analysis
dependsOn: []
jobs:

- job: lint
steps:
- template: templates/node-job-setup/template.yaml@pagopaCommons

- script: |
yarn lint
displayName: 'Lint'
Expand Down Expand Up @@ -91,16 +80,18 @@ stages:
DANGER_GITHUB_API_TOKEN: '$(DANGER_GITHUB_API_TOKEN)'
displayName: 'Danger CI'


# B) Run unit tests if there is a push or pull request on any branch.
- stage: Test
dependsOn: []
jobs:
- job: unit_tests
steps:
- template: templates/node-job-setup/template.yaml@pagopaCommons

- script: |
yarn generate
displayName: 'Generate defintions'
displayName: 'Generate definitions'

- script: |
yarn test:coverage
Expand Down
145 changes: 93 additions & 52 deletions .devops/deploy-pipelines.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
# Azure DevOps pipeline to release a new version and deploy to production.

variables:
NODE_VERSION: '10.14.1'
YARN_CACHE_FOLDER: $(Pipeline.Workspace)/.yarn
# Configuration to run the healthcheck container
HEALTHCHECK_CONTAINER_RG: 'io-p-rg-common'
HEALTHCHECK_CONTAINER_VNET: 'io-p-vnet-common'
HEALTHCHECK_CONTAINER_SUBNET: 'azure-devops'
HEALTHCHECK_PATH: 'api/v1/info'

parameters:
- name: 'RELEASE_SEMVER'
Expand All @@ -13,6 +16,20 @@ parameters:
- minor
- patch
default: minor
# Map of production apps to deploy to, in the form
# {logicName}:
# appname: {name of the resource}
# rg: {name of the resource group}
# Although it's a parameter, it's not intended to be edited at runtime.
# It's here because variables only handle scalar values
- name: 'PRODUCTION_APPS'
displayName: ''
type: object
default:
services:
appname: io-p-fn3-services
rg: io-p-rg-functions_services


# Only manual activations are intended
trigger: none
Expand All @@ -31,7 +48,7 @@ resources:
- repository: pagopaCommons
type: github
name: pagopa/azure-pipeline-templates
ref: refs/tags/v14
ref: refs/tags/v10
balanza marked this conversation as resolved.
Show resolved Hide resolved
endpoint: 'io-azure-devops-github-ro'

stages:
Expand Down Expand Up @@ -73,12 +90,13 @@ stages:
echo "We assume this reference to be a valid release: $(Build.SourceBranch). Therefore, there is no need to bundle a new release."
displayName: 'Skip release bundle'


# Prepare Artifact
- stage: Deploy_staging
- stage: Prepare_artifact
dependsOn:
- Release
jobs:
- job: 'prepare_artifact_and_deploy'
- job: 'prepare_artifact'
steps:
# Build application
- template: templates/node-job-setup/template.yaml@pagopaCommons
Expand All @@ -102,72 +120,95 @@ stages:
- task: CopyFiles@2
inputs:
SourceFolder: '$(System.DefaultWorkingDirectory)'
TargetFolder: '$(Build.ArtifactStagingDirectory)'
TargetFolder: '$(System.DefaultWorkingDirectory)/bundle'
Contents: |
**/*
!.git/**/*
!**/*.js.map
!**/*.ts
!.vscode/**/*
!azure-templates/**/*
!azure-pipelines.yml
!.devops/**/*
!.prettierrc
!.gitignore
!README.md
!jest.config.js
!local.settings.json
!test
!tsconfig.json
!tslint.json
!yarn.lock
!Dangerfile.js
!CODEOWNERS
!__*/**/*
displayName: 'Copy deploy files'

- publish: $(System.DefaultWorkingDirectory)/bundle
artifact: Bundle

# Deploy on staging slot
- ${{ each app in parameters.PRODUCTION_APPS }}:
- stage: Deploy_${{ app.Key }}_to_staging
dependsOn:
- Prepare_artifact
jobs:
- job: 'do_deploy_${{ app.Key }}'
steps:
- checkout: none
- download: current
artifact: Bundle

- task: AzureFunctionApp@1
inputs:
azureSubscription: '$(PRODUCTION_AZURE_SUBSCRIPTION)'
resourceGroupName: '$(PRODUCTION_RESOURCE_GROUP_NAME)'
appType: 'functionApp'
appName: '$(PRODUCTION_APP_NAME)'
package: '$(Build.ArtifactStagingDirectory)/'
deploymentMethod: 'auto'
deployToSlotOrASE: true
slotName: 'staging'
displayName: Deploy to staging slot
- task: AzureFunctionApp@1
inputs:
azureSubscription: '$(PRODUCTION_AZURE_SUBSCRIPTION)'
resourceGroupName: '${{ app.Value.rg }}'
appType: 'functionApp'
appName: '${{ app.Value.appname }}'
package: '$(Pipeline.Workspace)/Bundle'
deploymentMethod: 'auto'
deployToSlotOrASE: true
slotName: 'staging'
displayName: Deploy to staging slot

# Check that the staging instance is healthy
- stage: Healthcheck
dependsOn:
- Deploy_staging
jobs:
- job: 'do_healthcheck'
steps:
- checkout: none
- template: templates/rest-healthcheck/template.yaml@pagopaCommons
parameters:
azureSubscription: '$(PRODUCTION_AZURE_SUBSCRIPTION)'
appName: '$(PRODUCTION_APP_NAME)'
endpoint: 'https://$(PRODUCTION_APP_NAME)-staging.azurewebsites.net/api/info'
endpointType: 'private'
containerInstanceResourceGroup: 'io-p-rg-common'
containerInstanceVNet: 'io-p-vnet-common'
containerInstanceSubnet: 'azure-devops'
- ${{ each app in parameters.PRODUCTION_APPS }}:
- stage: Healthcheck_${{ app.Key }}
dependsOn:
- Deploy_${{ app.Key }}_to_staging
jobs:
- job: 'do_healthcheck_${{ app.Key }}'
steps:
- checkout: none
- template: templates/rest-healthcheck/template.yaml@pagopaCommons
parameters:
azureSubscription: '$(PRODUCTION_AZURE_SUBSCRIPTION)'
appName: '${{ app.Value.appname }}'
endpoint: 'https://${{ app.Value.appname }}-staging.azurewebsites.net/$(HEALTHCHECK_PATH)'
endpointType: 'private'
containerInstanceResourceGroup: '$(HEALTHCHECK_CONTAINER_RG)'
containerInstanceVNet: '$(HEALTHCHECK_CONTAINER_VNET)'
containerInstanceSubnet: '$(HEALTHCHECK_CONTAINER_SUBNET)'

# Promote the staging instance to production
- stage: Deploy_production
dependsOn:
- Healthcheck
- Deploy_staging
jobs:
- job: 'do_deploy'
steps:
- checkout: none
- task: AzureAppServiceManage@0
inputs:
azureSubscription: '$(PRODUCTION_AZURE_SUBSCRIPTION)'
resourceGroupName: '$(PRODUCTION_RESOURCE_GROUP_NAME)'
webAppName: '$(PRODUCTION_APP_NAME)'
sourceSlot: staging
swapWithProduction: true
displayName: Swap with production slot

- ${{ each app in parameters.PRODUCTION_APPS }}:
- stage: Swap_${{ app.Key }}_to_production
dependsOn:
- Deploy_${{ app.Key }}_to_staging
# Wait for every healthcheck to succeed
# This implied that no app is swapped to prod if at least one healthcheck fails
- ${{ each appInner in parameters.PRODUCTION_APPS }}:
- Healthcheck_${{ appInner.Key }}
jobs:
- job: 'do_deploy_${{ app.Key }}'
steps:
- checkout: none
- task: AzureAppServiceManage@0
inputs:
azureSubscription: '$(PRODUCTION_AZURE_SUBSCRIPTION)'
resourceGroupName: '${{ app.Value.rg }}'
webAppName: '${{ app.Value.appname }}'
sourceSlot: staging
swapWithProduction: true
displayName: Swap with production slot

# Publish client SDK to NPM
- stage: PublishClientSDKtoNPM
Expand Down