Steps:
- Intro
- VSO
- Docker
- xUnit
- Build
- Back end
- Selenium
- Docker
- Release Management
- Testing
In this post we are going to build our pipeline in Release
Management. Before we do this, we are going to polish our build and make sure
we publish all the artifacts we are going to need in our release pipeline. This will include the PowerShell scripts for managing
our Docker Hosts, the dacpac for our SQL database,
the UI tests, and the zip file to deploy our web service.
You are going to need to get the names of the SQL Servers,
SQL Databases, and Web Apps we created in Step
6 to complete this post.
In Step 7 we changed the Id column to be an Identity column
directly in the Database. However, I forgot to sync that change to our Database
project. We need to correct that.
Otherwise, when you deploy this project you will not be able to add new people.
1.
Update Database project
a.
Open PeopleTrackerWebService
solution
b.
Open People.sql
c.
Right-click the Id column and select Properties
d.
Set (Is Identity) to True
e.
Save your changes
We need to make a change to our PowerShell scripts. We need them to behave one way during build
and a different way during our release. During build, we only want the image
created and pushed to DockerHub. During our release, we do not need to build
the image again. We simply need to run it and pass in values to be stored as
environment variables in the container. These values will override the values set in
our ASP.NET 5 applications.
2.
Edit the publish.ps1 files
a.
Open PeopleTracker
solution
b.
Open devdockerhost-publish.ps1
c.
Cut the code below between lines 148 to 158 and
paste it into the else block of if(!$buildOnly)
'Building Docker image: {0}' -f $imageName | Write-Verbose
$command
= 'docker{0} -H {1} build -t
{2} -f "{3}" "{4}"' -f $authOptions, $dockerServerUrl, $imageName, $dockerfilePath, $packOutput
$command
| Print-CommandString
$command
| Execute-CommandString | Write-Verbose
'The Docker image "{0}" was created successfully.' -f $imageName | Write-Output
Write-Verbose 'Time to push to Docker
Hub'
$command
= 'docker{0} -H {1} push {2}' -f $authOptions, $dockerServerUrl, $imageName
$command
| Print-CommandString
$command
| Execute-CommandString | Write-Verbose
'The Docker image "{0}" was
pushed successfully.' -f $imageName | Write-Output
d.
Add the following line below $appType = $publishProperties[“DockerAppType”]
$addEnvVars = $publishProperties["DockerEnvVars"]
e.
Replace if ($appType -eq "Web") { $envVars = ' -e "server.urls=http://*:{0}"'
-f $containerPort } with the line below
if
($appType -eq "Web") {
$envVars = ' -e "server.urls=http://*:{0}" {1}' -f $containerPort, $addEnvVars }
f.
Repeat steps c-e for the QA and Prod files as
well
Before we commit our changes, we are going to disable the LaunchSiteAfterPublish property in the pubxml
files. We could override it by passing
in false from Build and Release, but that makes the arguments longer and more
difficult to manage. When this value is
true, the PowerShell script will launch the default browser and navigate to the
web site which we do not need in an automated pipeline.
3.
Disable LaunchSiteAfterPublish
in pubxml files
a.
Open each pubxml file
b.
Set LaunchSiteAfterPublish
element to False
4.
Commit and push your changes
a.
From the View menu select Team Explorer
b.
Click Changes button
c.
Enter a comment
d.
Select Commit and Push
We are going to package our ASP.NET 4.5 Web API as a zip
file to deploy to an Azure Web App. Then
we will edit the Copy and Publish Build Artifacts task of our build to be more
specific. Currently, we grab all the
files that are in bin folders. This, however, leaves our PowerShell scripts
behind.
5.
Edit your build
a.
Select the Visual Studio Build task
b.
Change MSBuild
Arguments to
/p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:PackageLocation="$(BuildConfiguration)" /p:DeployOnBuild=true
c.
Select the Copy and Publish Build Artifacts task
d.
Change the Contents to
**\*.zip
**\*.dacpac
**\PublishProfiles
**\*test*\bin
e.
Save and Queue your build
f.
Confirm it builds as expected and everything we
need is in the artifacts
With our build ready, we can move to the Release hub and
create our Release Pipeline. The
pipeline will include everything except the tests, which we will configure in
the final post of this series.
We created three Docker hosts: one for Dev, QA and
Production. Our pipeline will enable us to deploy to each one of them.
6.
Create new Release Management pipeline
a.
Visit the Release hub of your VSTS project
b.
Click the Create release definition link
c.
Select the Empty template
d.
Click OK
e.
Enter a name
f.
Click the Link to a build definition link
g.
Select our build definition and click Link
h.
Change the name of the first environment from
Default Environment to Dev
i.
Click the ellipses of the default environment
and select Agent options…
j.
Change the Default queue to Default
k.
Click OK
l.
Click Configuration
m.
Enter ImageName for
Name
n.
Enter your Docker image name for the value in {DockerHubUsername}/{Repo} format
o.
Save your definition
With our definition created, we can start to build our first
environment.
7.
Add tasks to Dev environment
a.
Click Add tasks
b.
Add the Azure SQL Database Deployment task
c.
Add the Azure Web App Deployment task
d.
Add the PowerShell task
e.
Click Close
8.
Configure Azure SQL Database Deployment task
a.
Select the Azure SQL Database Deployment task
b.
Click the Manage link next to Azure Subscription
c.
Click New Service Endpoint and select Azure
d.
Enter a name
e.
Download your certificate using this link: https://manage.windowsazure.com/publishsettings
f.
Open the file and locate the subscription Id as
well as the Name and Management Certificates and copy into the dialog
g.
Return to the Release and click the Refresh
button for the Azure Subscription
h.
Select the Azure subscription you just added
As of this writing, the Azure SQL Database Deployment task
does not support mini search patterns or browsing for the dacpac
file. Therefore, we are going to take a
shortcut by using the browse functionality on the PowerShell task.
i.
Click on the PowerShell task
j.
Use the browse for Script filename to find the dacpac file
k.
Copy that value
l.
Click on the Azure SQL Database Deployment
m.
Paste the path for DACPAC File
n.
Click the ellipse of the Dev environment and
select Configure variables
o.
Enter SQLServer for
name and the FQDN name of the SQL Server created in Step
6 for value
p.
Click Add variable
q.
Enter Database for name and the name of the SQL
Database created in Step
6 for value
r.
Click Add variable
s.
Enter SQLUser for name
and the admin account you created in Step 6 for the value
t.
Click Add variable
u.
Enter Password for the Name and the actual SQL
Server Admin password for the value
v.
Click the lock icon to encrypt the data
w.
Click OK
x.
Enter $(SQLServer) for
the Azure SQL Server Name
y.
Enter $(Database) for the Database Name
z.
Enter $(Password) for the Password
If you used the same password for all your SQL Servers, you
can define this variable under the Configuration tab of the Release instead of
at the environment level.
aa.
Expand the Firewall section
bb.
Select AutoDetect for Specify Firewall Rules
Using
9.
Configure Azure Web App Deployment task
a.
Click the ellipse of the Dev environment and
select Configure variables
b.
Click Add variable
c.
Enter WebSiteName for
name and the Web App name of the Web App created in Step
6 for value
d.
Click OK
e.
Select Azure Web App Deployment task
a.
Click the Refresh button for the Azure
Subscription
b.
Select the Azure Subscription you just added
c.
Enter $(WebSiteName)
for the Web App Name
d.
Select the correct Web App Location for the Web
App entered above
e.
Use the browse button to locate the zip file for
the Web Service package
10.
Configure the PowerShell task
a.
Click the ellipse of the Dev environment and
select Configure variables
b.
Click Add variable
c.
Enter WebAPI for the
Name and the full URL to your web service including http:// for the value
d.
Click OK
e.
Select the PowerShell task
f.
Browse to the devdockerhost-publish.ps1 file
g.
Copy and paste the value below for Arguments
-publishProperties @{"DockerImageName" = "$(ImageName):$(Build.BuildId)"; "DockerEnvVars"
= "-e ""WebApiBaseUrl=$(WebAPI)"" -e ""BuildNumber=$(Build.BuildId)"" "} -packOutput
".\" -pubxmlfile ".\devdockerhost.pubxml"
h.
Expand the Advanced section
i.
Browse to the PublishProfiles
folder
11.
Create QA
a.
Click the ellipse of the Dev environment and
select Clone environment
b.
Enter QA for the name
c.
Click the ellipse of the QA environment and
select Configure variables
d.
Update all values to match those for your QA
resources
e.
Click OK
f.
Click the ellipse of the QA environment and
select Assign approvers…
g.
Uncheck the Automated check box for
Pre-deployment approver
h.
Add yourself as the approver
i.
Click OK
j.
Select the PowerShell task
k.
Browse to the QA version of the publish.ps1 file
12.
Create Prod
a.
Click the ellipse of the QA environment and
select Clone environment
b.
Enter Prod for the name
c.
Click the ellipse of the Prod environment and
select Configure variables
d.
Update all values to match those for your Prod
resources
e.
Click the ellipse of the Prod environment and
select Assign approvers…
f.
Uncheck the Automated check box for
Pre-deployment approver
g.
Add yourself as the approver
h.
Click OK
i.
Select the PowerShell task
j.
Browse to the Prod version of the publish.ps1
file
13.
Enable Continuous Deployment
a.
Click on Triggers
b.
Check the Continuous deployment check box
c.
Select the build
d.
Save your release
e.
Start a new release
f.
Confirm it deploys as expected
In the next and final post, we will add our Selenium and
Cloud based load test to our release definition.