Reputation: 6452
I am completely new to deploy azure static webapp to azure. I have a very simple angular app and azure devops account.
I want to setup the azure devops pipeline to build and upload the angular app files to blob container. Note: i dont have azure subscription and only having storage account connection string details.
my yml file so far is. not sure how to proceed further.
trigger:
- main
pool:
vmImage: ubuntu-latest
steps:
- task: NodeTool@0
inputs:
versionSpec: '12.x'
displayName: 'Install Node.js'
- script: |
npm install -g @angular/cli
npm install
ng build --prod
displayName: 'npm install and build'
Can anyone please help me how to do this.
i see some script available to upload but not sure how to add to the pipeline
az storage blob upload --account-name mystorageaccount --account-key 0000-0000 --container-name mycontainer --file /path/to/file --name myblob
Upvotes: 2
Views: 2519
Reputation: 7067
This is the YAML I utilize for deploying an Angular App to Blob Storage. Under "capabilities" of the Storage Account, you will need to enable "Static Website" which will create the $web container, beyond that, update the variables in the following YAML and it should work as-is.
Here is the entire YAML, and then I will explain it section by section to give more context:
variables:
- name: storageContainer
value: myStorageaccount
- name: subscription
value: Subscription (8217a062-4d59-45f6-bc03-b6f559a1e58a)
trigger:
branches:
include:
- master
stages:
- stage: __default
jobs:
- job: Job
pool:
vmImage: windows-latest
steps:
- task: NodeTool@0
inputs:
versionSpec: '14.17.4'
force32bit: true
- task: CmdLine@2
displayName: npm install
inputs:
script: |
npm install
- task: CmdLine@2
displayName: ng build
inputs:
script: |
set PATH=%PATH%;%CD%\node_modules\.bin;C:\npm\prefix
ng build --subresource-integrity --output-hashing none
- task: AzureFileCopy@2
displayName: Deploy Files
inputs:
SourcePath: '$(System.DefaultWorkingDirectory)\dist\$(Build.Repository.Name)'
azureSubscription: $(subscription)
Destination: 'AzureBlob'
storage: $(storageContainer)
ContainerName: '$web'
BlobPrefix: ''
- task: AzureCLI@2
displayName: Delete Old Files
inputs:
azureSubscription: $(subscription)
scriptType: 'pscore'
scriptLocation: 'inlineScript'
inlineScript: 'az storage blob delete-batch -s `$web --account-name $(storageContainer) --if-unmodified-since $(Get-Date ((Get-Date).addMinutes(-5)) -UFORMAT +%Y-%m-%dT%H:%MZ)'
Okay, here it is section by section:
The following sets the values for the variables storageContainer and subscription to be used in the rest of the commands. Variables are replaced when you use $(storageContainer) type syntax.
variables:
- name: storageContainer
value: myStorageaccount
- name: subscription
value: Subscription (8217a062-4d59-45f6-bc03-b6f559a1e58a)
The following sets continuous build / delivery when code is returned to the master branch, and tells everything to deploy to a vm with the latest build of Windows. Windows is needed for some of the azure cli commands later on:
trigger:
branches:
include:
- master
stages:
- stage: __default
jobs:
- job: Job
pool:
vmImage: windows-latest
The following task installs node version 14.17.4 onto the system in order to utilize it. I had it utilize the 32-bit version of node, but that really shouldn't matter.
steps:
- task: NodeTool@0
inputs:
versionSpec: '14.17.4'
force32bit: true
The following executes the npm install and installs everything from packages.json. I added the angular/cli to my dev dependencies, and therefore its installed with this. If you don't want to do that, you'll need a command that installs the angular cli. Please keep in mind, Azure DevOps doesn't seem to like it when there is more than one node install within a CmdLine block, so you'll need another block.
- task: CmdLine@2
displayName: npm install
inputs:
script: |
npm install
The following does the Angular build (ng build). The first thing I do is set the path appropriately so that it can find the Angular cli in the dev dependencies. I also have it add c:\npm\prefix to the path, which is apparently where the global npm installs are put. That was hard to find / figure out; so I left it in the path when I found it. In my Angular build I have two flags. The --subresource-integrity flag makes it so that the script tags have an integrity attribute that has the hash of the JavaScript file. This is considered a security best practice. I also have the --output-hashing none set. This makes it so that files are just main.js rather than the longer names with the hash in the JS file. This is just a preference of mine.
- task: CmdLine@2
displayName: ng build
inputs:
script: |
set PATH=%PATH%;%CD%\node_modules\.bin;C:\npm\prefix
ng build --subresource-integrity --output-hashing none
The following Azure Cli command copies all of the files to the $web container of the storage account. The Angular build command by default putss these files from whatever is listed in "outputPath" in your angular.json. By default this is a folder under the dist directory. That folder happens to be the same exact name as my Git Repository, which I think is normal. This is why I have the source to grab files from be '$(System.DefaultWorkingDirectory)\dist$(Build.Repository.Name)' . I think this should work for you out-of-the-box the way I have it, but if not, replace "dist$(Build.Repository.Name)" with whatever is set in outputPath of your angular.json .
- task: AzureFileCopy@2
displayName: Deploy Files
inputs:
SourcePath: '$(System.DefaultWorkingDirectory)\dist\$(Build.Repository.Name)'
azureSubscription: $(subscription)
Destination: 'AzureBlob'
storage: $(storageContainer)
ContainerName: '$web'
BlobPrefix: ''
When copying files to an Azure Storage Account, by default it will overwrite files with the same name. However, it won't do anything with files that are no longer used and aren't overwritten. For that reason, this last section will delete any files that haven't been modified in the last 5 minutes. This build process on average takes about 4 minutes, so I figured anything that was older than 5 minutes was from a prior build.
- task: AzureCLI@2
displayName: Delete Old Files
inputs:
azureSubscription: $(subscription)
scriptType: 'pscore'
scriptLocation: 'inlineScript'
inlineScript: 'az storage blob delete-batch -s `$web --account-name $(storageContainer) --if-unmodified-since $(Get-Date ((Get-Date).addMinutes(-5)) -UFORMAT +%Y-%m-%dT%H:%MZ)'
Hopefully this helps save someone some time. This took MUCH more time than I was expecting to get properly put together.
Upvotes: 1
Reputation: 1833
Try with following steps.
1) Enable the static website hosting in storage account. Storage Account's side-menu (Settings ⇒ Static website)
2) Configure the release pipeline for storage account. Creating a release pipeline that will use the artifacts published as part of the build pipeline for more details refer this document document
inside an Azure DevOps project, create a new Release Pipeline by selecting Pipeline ⇒ Releases ⇒ New ⇒ New Release Pipeline
3) choose to start with an empty job instead of selecting a preconfigured template. As Azure DevOps supports multiple stages, provide the name for the stage that's created by default, or you can keep Stage 1 as its name.
4) Add the build artifacts.
Click Add an Artifact, select the Build source type (as the artifacts are stored within the build pipeline), and select the appropriate build pipeline from the source dropdown. You can keep the default values for both the version to deploy, as we always want to deploy the latest version, and the source alias. The source alias is the folder that will be used to download the artifacts.
5) Add the deployment tasks.
started with an empty job(step 3), there are no tasks defined yet. add the task to deploy the artifact's files to an Azure Storage Account.click the '+' on the Agent job, search for Azure file copy, and click the add.
When adding an Azure file copy task, need to provide the required information in order for Azure DevOps to know what files have to be deployed to which destination. This includes both the Azure Subscription, and the Storage Account information.
6) select your Azure Subscription, select Azure Blob as the Destination Type, choose the appropriate Storage Account , and provide $web for the container name (this is the default container name used by Azure Devops when enabling static websites inside an Azure Storage Account)
7) Use of Environment specific configuration
to avoid rebuilding the application in order for it to use environment-specific configuration, Use the JSON file that's served as part of the assets directory, and is retrieved in our Angular application using an Http Request. You can find a detailed overview on how to configure in this document
Create a File transform task to modify the contents of the config.json
file as part of release pipeline's stage (in case of multiple stages, every stage can have its own step, and can replace the contents with different values before deploying). Add the task, and configure it to target the assets/config.json
file inside web-app artifact.
8) Execute the task before deploying the files to Azure Storage.
9) create release pipeline variables. The file transform task will use all the variables, and update values based on its name
10) Enable the Continuous deployment trigger to continuously deploy artifacts.
Click on the lightning strike symbol that's showing up on your artifact in the pipeline section, enable the Continuous deployment trigger
11) Once the deployment is finished, navigating to one of the Azure Storage endpoint URL's should show the Angular application.
For more details refer this document
Upvotes: 1