From 60269306c544bcb628a2c649eaaed4535aed6bf2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B9=AF=E6=9C=AC=20=E9=96=8B?= Date: Sun, 3 Sep 2023 12:05:18 +0000 Subject: [PATCH] =?UTF-8?q?Merged=20PR=20285:=20Staging=E7=94=A8=E3=83=87?= =?UTF-8?q?=E3=83=97=E3=83=AD=E3=82=A4=E3=83=91=E3=82=A4=E3=83=97=E3=83=A9?= =?UTF-8?q?=E3=82=A4=E3=83=B3=E3=82=92=E4=BD=9C=E6=88=90=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 概要 [Task2198: Staging用デプロイパイプラインを作成する](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/2198) - Stating/Production用のデプロイパイプラインの構成ファイルを作成 ## レビュー対象外 - depoyment slotを使ったデプロイには未対応(別PBIで対応予定) ## レビューポイント - ざっくり実施される処理とその順序として問題はなさそうか - 情報共有 ## 動作確認状況 - Dockerイメージがビルド&プッシュ、静的ファイルがビルド&Pipeline用Blobストレージにアップロードされる所までは確認済 - 書式はPipeline上画面で確認済 --- azure-pipelines-production.yml | 89 +++++++++++++--- azure-pipelines-staging.yml | 187 +++++++++++++++++++++++++++++++-- 2 files changed, 257 insertions(+), 19 deletions(-) diff --git a/azure-pipelines-production.yml b/azure-pipelines-production.yml index b35783a..45eba43 100644 --- a/azure-pipelines-production.yml +++ b/azure-pipelines-production.yml @@ -1,3 +1,6 @@ +# Pipeline側でKeyVaultやDocker、AppService等に対する操作権限を持ったServiceConenctionを作成し、 +# 環境変数 AZURE_SERVICE_CONNECTION の値としてServiceConenction名を設定しておくこと +# また、環境変数 STATIC_DICTATION_DEPLOYMENT_TOKEN の値として静的WebAppsのデプロイトークンを設定しておくこと trigger: tags: include: @@ -22,36 +25,98 @@ jobs: exit 1 fi displayName: 'タグが付けられたCommitがmainブランチに存在するか確認' -- job: backend_build - dependsOn: initialize - condition: succeeded('initialize') - displayName: Dictation App Service Deploy +- job: backend_deploy + displayName: Backend Deploy pool: - vmImage: ubuntu-latest + name: odms-deploy-pipeline steps: - checkout: self clean: true fetchDepth: 1 -- job: frontend_build - dependsOn: initialize - condition: succeeded('initialize') - displayName: Dictation Static App Service Deploy + - task: AzureRmWebAppDeployment@4 + inputs: + ConnectionType: 'AzureRM' + azureSubscription: $(AZURE_SERVICE_CONNECTION) + appType: 'webAppContainer' + WebAppName: 'app-odms-dictation-prod' + ResourceGroupName: 'prod-application-rg' + DockerNamespace: 'crodmsregistrymaintenance.azurecr.io' + DockerRepository: '$(Build.Repository.Name)/staging/dictation' + DockerImageTag: '$(Build.SourceVersion)' +- job: frontend_deploy + displayName: Deploy Frontend Files + variables: + storageAccountName: saomdspipeline + containerName: staging pool: - vmImage: ubuntu-latest + name: odms-deploy-pipeline steps: - checkout: self clean: true fetchDepth: 1 + - task: AzureKeyVault@2 + displayName: 'Azure Key Vault: kv-odms-secret-prod' + inputs: + ConnectedServiceName: $(AZURE_SERVICE_CONNECTION) + KeyVaultName: kv-odms-secret-prod + SecretsFilter: '*' + - task: AzureCLI@2 + inputs: + azureSubscription: $(AZURE_SERVICE_CONNECTION) + scriptType: 'bash' + scriptLocation: 'inlineScript' + inlineScript: | + az storage blob download \ + --auth-mode login \ + --account-name $(storageAccountName) \ + --container-name $(containerName) \ + --name $(Build.SourceVersion).zip \ + --file $(Build.SourcesDirectory)/$(Build.SourceVersion).zip + - task: Bash@3 + displayName: Bash Script + inputs: + targetType: inline + script: unzip $(Build.SourcesDirectory)/$(Build.SourceVersion).zip -d $(Build.SourcesDirectory)/$(Build.SourceVersion) + - task: AzureStaticWebApp@0 + displayName: 'Static Web App: ' + inputs: + workingDirectory: '$(Build.SourcesDirectory)' + app_location: '/$(Build.SourceVersion)' + config_file_location: /dictation_client + skip_app_build: true + skip_api_build: true + is_static_export: false + verbose: false + azure_static_web_apps_api_token: $(STATIC_DICTATION_DEPLOYMENT_TOKEN) - job: migration condition: succeeded('initialize') displayName: DB migration dependsOn: - initialize - - backend_build - - frontend_build + - backend_deploy + - frontend_deploy pool: name: db-migrate-pipelines steps: - checkout: self clean: true fetchDepth: 1 + - task: AzureKeyVault@2 + displayName: 'Azure Key Vault: kv-odms-secret-prod' + inputs: + ConnectedServiceName: $(AZURE_SERVICE_CONNECTION) + KeyVaultName: kv-odms-secret-prod + - task: CmdLine@2 + displayName: migration + inputs: + script: >2 + # DB接続情報書き換え + sed -i -e "s/DB_NAME/$(db-name)/g" ./dictation_server/db/dbconfig.yml + sed -i -e "s/DB_PASS/$(db-pass)/g" ./dictation_server/db/dbconfig.yml + sed -i -e "s/DB_USERNAME/$(db-user)/g" ./dictation_server/db/dbconfig.yml + sed -i -e "s/DB_PORT/$(db-port)/g" ./dictation_server/db/dbconfig.yml + sed -i -e "s/DB_HOST/$(db-host)/g" ./dictation_server/db/dbconfig.yml + sql-migrate --version + cat ./dictation_server/db/dbconfig.yml + # migration実行 + sql-migrate up -config=./dictation_server/db/dbconfig.yml -env=ci \ No newline at end of file diff --git a/azure-pipelines-staging.yml b/azure-pipelines-staging.yml index ba3c32c..78965ab 100644 --- a/azure-pipelines-staging.yml +++ b/azure-pipelines-staging.yml @@ -1,3 +1,6 @@ +# Pipeline側でKeyVaultやDocker、AppService等に対する操作権限を持ったServiceConenctionを作成し、 +# 環境変数 AZURE_SERVICE_CONNECTION の値としてServiceConenction名を設定しておくこと +# また、環境変数 STATIC_DICTATION_DEPLOYMENT_TOKEN の値として静的WebAppsのデプロイトークンを設定しておくこと trigger: branches: include: @@ -28,33 +31,203 @@ jobs: - job: backend_build dependsOn: initialize condition: succeeded('initialize') - displayName: Dictation App Service Deploy + displayName: Build And Push Backend Image pool: - vmImage: ubuntu-latest + name: odms-deploy-pipeline steps: - checkout: self clean: true fetchDepth: 1 + - task: Npm@1 + displayName: npm ci + inputs: + command: ci + workingDir: dictation_server + verbose: false + - task: AzureKeyVault@2 + displayName: 'Azure Key Vault: kv-odms-secret-stg' + inputs: + ConnectedServiceName: $(AZURE_SERVICE_CONNECTION) + KeyVaultName: kv-odms-secret-stg + SecretsFilter: '*' + - task: Bash@3 + displayName: Bash Script (Test) + inputs: + targetType: inline + script: | + cd dictation_server + npm run test + env: + JWT_PUBLIC_KEY: $(token-public-key) + SENDGRID_API_KEY: $(sendgrid-api-key) + NOTIFICATION_HUB_NAME: $(notification-hub-name) + NOTIFICATION_HUB_CONNECT_STRING: $(notification-hub-connect-string) + STORAGE_ACCOUNT_NAME_US: $(storage-account-name-us) + STORAGE_ACCOUNT_NAME_AU: $(storage-account-name-au) + STORAGE_ACCOUNT_NAME_EU: $(storage-account-name-eu) + STORAGE_ACCOUNT_KEY_US: $(storage-account-key-us) + STORAGE_ACCOUNT_KEY_AU: $(storage-account-key-au) + STORAGE_ACCOUNT_KEY_EU: $(storage-account-key-eu) + STORAGE_ACCOUNT_ENDPOINT_US: $(storage-account-endpoint-us) + STORAGE_ACCOUNT_ENDPOINT_AU: $(storage-account-endpoint-au) + STORAGE_ACCOUNT_ENDPOINT_EU: $(storage-account-endpoint-eu) + ADB2C_TENANT_ID: $(adb2c-tenant-id) + ADB2C_CLIENT_ID: $(adb2c-client-id) + ADB2C_CLIENT_SECRET: $(adb2c-client-secret) + - task: Docker@0 + displayName: build + inputs: + azureSubscriptionEndpoint: $(AZURE_SERVICE_CONNECTION) + azureContainerRegistry: '{"loginServer":"crodmsregistrymaintenance.azurecr.io", "id" : "/subscriptions/108fb131-cdca-4729-a2be-e5bd8c0b3ba7/resourceGroups/maintenance-rg/providers/Microsoft.ContainerRegistry/registries/crOdmsRegistryMaintenance"}' + dockerFile: DockerfileServerDictation.dockerfile + imageName: $(Build.Repository.Name)/staging/dictation:$(Build.SourceVersion) + - task: Docker@0 + displayName: push + inputs: + azureSubscriptionEndpoint: $(AZURE_SERVICE_CONNECTION) + azureContainerRegistry: '{"loginServer":"crodmsregistrymaintenance.azurecr.io", "id" : "/subscriptions/108fb131-cdca-4729-a2be-e5bd8c0b3ba7/resourceGroups/maintenance-rg/providers/Microsoft.ContainerRegistry/registries/crOdmsRegistryMaintenance"}' + action: Push an image + imageName: $(Build.Repository.Name)/staging/dictation:$(Build.SourceVersion) +- job: backend_deploy + dependsOn: backend_build + condition: succeeded('backend_build') + displayName: Backend Deploy + pool: + name: odms-deploy-pipeline + steps: + - checkout: self + clean: true + fetchDepth: 1 + - task: AzureRmWebAppDeployment@4 + inputs: + ConnectionType: 'AzureRM' + azureSubscription: $(AZURE_SERVICE_CONNECTION) + appType: 'webAppContainer' + WebAppName: 'app-odms-dictation-stg' + ResourceGroupName: 'stg-application-rg' + DockerNamespace: 'crodmsregistrymaintenance.azurecr.io' + DockerRepository: '$(Build.Repository.Name)/staging/dictation' + DockerImageTag: '$(Build.SourceVersion)' - job: frontend_build dependsOn: initialize condition: succeeded('initialize') - displayName: Dictation Static App Service Deploy + displayName: Build Frontend Files + variables: + storageAccountName: saomdspipeline + containerName: staging pool: - vmImage: ubuntu-latest + name: odms-deploy-pipeline steps: - checkout: self clean: true fetchDepth: 1 + - task: Npm@1 + displayName: npm ci + inputs: + command: ci + workingDir: dictation_client + verbose: false + - task: Bash@3 + displayName: Bash Script + inputs: + targetType: inline + script: cd dictation_client && npm run build + - task: ArchiveFiles@2 + inputs: + rootFolderOrFile: dictation_client/build + includeRootFolder: false + archiveType: 'zip' + archiveFile: '$(Build.ArtifactStagingDirectory)/$(Build.SourceVersion).zip' + replaceExistingArchive: true + - task: AzureCLI@2 + inputs: + azureSubscription: $(AZURE_SERVICE_CONNECTION) + scriptType: 'bash' + scriptLocation: 'inlineScript' + inlineScript: | + az storage blob upload \ + --auth-mode login \ + --account-name $(storageAccountName) \ + --container-name $(containerName) \ + --name $(Build.SourceVersion).zip \ + --type block \ + --file $(Build.ArtifactStagingDirectory)/$(Build.SourceVersion).zip +- job: frontend_deploy + dependsOn: frontend_build + condition: succeeded('frontend_build') + displayName: Deploy Frontend Files + variables: + storageAccountName: saomdspipeline + containerName: staging + pool: + name: odms-deploy-pipeline + steps: + - checkout: self + clean: true + fetchDepth: 1 + - task: AzureKeyVault@2 + displayName: 'Azure Key Vault: kv-odms-secret-stg' + inputs: + ConnectedServiceName: $(AZURE_SERVICE_CONNECTION) + KeyVaultName: kv-odms-secret-stg + SecretsFilter: '*' + - task: AzureCLI@2 + inputs: + azureSubscription: $(AZURE_SERVICE_CONNECTION) + scriptType: 'bash' + scriptLocation: 'inlineScript' + inlineScript: | + az storage blob download \ + --auth-mode login \ + --account-name $(storageAccountName) \ + --container-name $(containerName) \ + --name $(Build.SourceVersion).zip \ + --file $(Build.SourcesDirectory)/$(Build.SourceVersion).zip + - task: Bash@3 + displayName: Bash Script + inputs: + targetType: inline + script: unzip $(Build.SourcesDirectory)/$(Build.SourceVersion).zip -d $(Build.SourcesDirectory)/$(Build.SourceVersion) + - task: AzureStaticWebApp@0 + displayName: 'Static Web App: ' + inputs: + workingDirectory: '$(Build.SourcesDirectory)' + app_location: '/$(Build.SourceVersion)' + config_file_location: /dictation_client + skip_app_build: true + skip_api_build: true + is_static_export: false + verbose: false + azure_static_web_apps_api_token: $(STATIC_DICTATION_DEPLOYMENT_TOKEN) - job: migration condition: succeeded('initialize') displayName: DB migration dependsOn: - initialize - - backend_build - - frontend_build + - backend_deploy + - frontend_deploy pool: name: db-migrate-pipelines steps: - checkout: self clean: true - fetchDepth: 1 \ No newline at end of file + fetchDepth: 1 + - task: AzureKeyVault@2 + displayName: 'Azure Key Vault: kv-odms-secret-stg' + inputs: + ConnectedServiceName: $(AZURE_SERVICE_CONNECTION) + KeyVaultName: kv-odms-secret-stg + - task: CmdLine@2 + displayName: migration + inputs: + script: >2 + # DB接続情報書き換え + sed -i -e "s/DB_NAME/$(db-name)/g" ./dictation_server/db/dbconfig.yml + sed -i -e "s/DB_PASS/$(db-pass)/g" ./dictation_server/db/dbconfig.yml + sed -i -e "s/DB_USERNAME/$(db-user)/g" ./dictation_server/db/dbconfig.yml + sed -i -e "s/DB_PORT/$(db-port)/g" ./dictation_server/db/dbconfig.yml + sed -i -e "s/DB_HOST/$(db-host)/g" ./dictation_server/db/dbconfig.yml + sql-migrate --version + cat ./dictation_server/db/dbconfig.yml + # migration実行 + sql-migrate up -config=./dictation_server/db/dbconfig.yml -env=ci \ No newline at end of file