{"id":79391,"date":"2018-06-20T19:22:52","date_gmt":"2018-06-20T19:22:52","guid":{"rendered":"https:\/\/www.red-gate.com\/simple-talk\/?p=79391"},"modified":"2019-08-15T13:49:34","modified_gmt":"2019-08-15T13:49:34","slug":"building-a-sql-azure-database-from-teamcity","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/blogs\/building-a-sql-azure-database-from-teamcity\/","title":{"rendered":"Building a SQL Azure Database from TeamCity"},"content":{"rendered":"<p>I\u2019m in the process of setting up a new environment using Azure SQL Databases, previously in Azure we\u2019ve just used an Azure VM with SQL Server on it.\u00a0\u00a0I\u2019m also fairly new to setting up a Continuous Integration environment and in-house we use Team City, so in this blog and probably the next few I\u2019m going to go through how to set up Team City to deploy to an Azure SQL database.\u00a0\u00a0There are definitely other ways of doing it and probably better ways but this is how I tackled it.<\/p>\n<p>In the full process, which I will cover in a series of blog posts, I will show you how to:<\/p>\n<ol>\n<li>Check for the existence of a database,<\/li>\n<li>Delete a database,<\/li>\n<li>Create a database,<\/li>\n<li>Sync the schema from source control<\/li>\n<li>Populate it with some data.<\/li>\n<\/ol>\n<p>In this post we will cover points 1 to 3.<\/p>\n<p>Assumptions:<\/p>\n<ul>\n<li>You have Team City setup and have a basic understanding of how it works, if however you need some help please refer to my blog post on the subject <a href=\"https:\/\/www.red-gate.com\/simple-talk\/blogs\/installing-and-setting-up-teamcity\/\">here<\/a><\/li>\n<li>You have a login to Azure<\/li>\n<li>You have created a Resource Group in Azure<\/li>\n<li>You have an understanding of Powershell<\/li>\n<\/ul>\n<p>I write all my commands in Powershell and I write them using Visual Studio Code.<\/p>\n<p>Before I start putting anything into TeamCity I write the code and make sure it\u2019s doing what\u2019s required and then I can quickly plumb it into TeamCity knowing that it\u2019s basically working. One thing to remember when working with TeamCity is that you can parameterise everything, which means scripts can be written and used in different environments by changing the parameters, this obviously changes how we write the Powershell.<\/p>\n<p>I also created a test database in the appropriate resource group via the Azure portal so that I had all the information I needed.<\/p>\n<p>Before you start writing the Powershell code you will need to ensure that the required modules are installed as follows:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-79394\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/06\/BuildingAzureDB_1.png\" alt=\"\" width=\"357\" height=\"55\" \/><\/p>\n<p>To create the database the parameters we will need are:<\/p>\n<p><strong>Server Name<\/strong> \u2013 the full name of the Azure Server, you can get this by clicking in the Azure Portal on the database need set up above and clicking on \u201cShow database connection strings\u201d and this will give you all the information you need\u00a0 in relation to the server.<\/p>\n<p><strong>Azure Account Name<\/strong> \u2013 this is the login you use to connect to the portal, it will be in the format <a href=\"mailto:something@something.onmicrosoft.com\">something@something.onmicrosoft.com<\/a><\/p>\n<p><strong>Password<\/strong> \u2013 in Team City you can save a password in a secure string, for testing purposes you can just put the password here, but NEVER save it here.<\/p>\n<p>So the powershell will look something like this:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-79395\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/06\/BuildingAzureDB_2.png\" alt=\"\" width=\"614\" height=\"103\" \/><\/p>\n<p>We then need to convert the password to a secure string and set the result as a parameter using the following code:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-79396\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/06\/BuildingAzureDB_3.png\" alt=\"\" width=\"689\" height=\"40\" \/><\/p>\n<p>Using these details I logged in to the azure portal using the following code:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-79397\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/06\/BuildingAzureDB_4.png\" alt=\"\" width=\"818\" height=\"73\" \/><\/p>\n<p>This uses the username passed in as the parameter, the password that we\u2019ve converted to a secure string which we have set to be a credential, and then using these credentials we\u2019ve logged in to our Azure account.<\/p>\n<p>We then need to pass in the detail of which resource group we want to use, which location and pass it a database name.\u00a0 We could parameterise these but in this case I haven\u2019t as my resource group and location wont change, but if I wanted to use this code for a different resource groups or locations I\u2019d definitely parameterise them.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-79398\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/06\/BuildingAzureDB_5.png\" alt=\"\" width=\"557\" height=\"87\" \/><\/p>\n<p>Then we need to check whether our database exists, we can use an Azure command for this called <strong>Get-AzureRMSQLDatabase<\/strong> and we need to pass it the ServerName, ResourceGroupName and DatabaseName.\u00a0 We need to pass this to a variable because really all we want to know is if it exists, if it does we want to delete it because, in my opinion, when you are building a test database from a source controlled environment you want to start with an empty database.\u00a0 In future builds I will be building a pre-production environment in which case we will be comparing and making changes and not starting from empty.<\/p>\n<p>To remove a database we use the command <strong>Remove-AzureRmSqlDatabase <\/strong>and we need to pass in the ResourceGroupName, ServerName and DatabaseName<\/p>\n<p>The script to check and remove the database is as follows:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-79399\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/06\/BuildingAzureDB_6.png\" alt=\"\" width=\"1287\" height=\"81\" \/><\/p>\n<p>Once the database no longer exists we can create a new one.\u00a0 We have to use the New-AzureRmSqlDatabase command and pass in the ResourceGroupName, ServerName and DatabaseName and the RequestedServiceObjectiveName which is basically what tier of database do we want, I\u2019m using Basic because it\u2019s a test box and I\u2019m only interested in building the cheapest I can without compromising performance.\u00a0 However remember some functionality which works on higher tiers may not work on this as I found out.\u00a0 For example Clustered ColumnStore indexes do not work on the Basic tier so consider your functionality when setting the level you want.<\/p>\n<p>The code to do this is:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-79400\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/06\/BuildingAzureDB_7.png\" alt=\"\" width=\"1435\" height=\"35\" \/><\/p>\n<p>So the entire script looks like this:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-79393\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/06\/BuidlingAzureDB_8.png\" alt=\"\" width=\"1473\" height=\"494\" \/><\/p>\n<p>Once we\u2019ve tested this script and prove it works we need to plumb it in to TeamCity.\u00a0 However remember to remove the password, we don\u2019t want to save a password in here.\u00a0\u00a0 We could encrypt the password and save it in a file, but TeamCity handles it quite well so I\u2019ll leave it there.<\/p>\n<p>In TeamCity open your Build Configuration and add a build step.\u00a0<\/p>\n<p>The window will look like this:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone  wp-image-79401\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/06\/BuildingAzureDB_8.png\" alt=\"\" width=\"888\" height=\"664\" \/><\/p>\n<p>Going through this step by step:<\/p>\n<ul>\n<li><strong>Runner type<\/strong> refers to what type of script we are using and in this case it\u2019s Powershell.<\/li>\n<li><strong>Step name<\/strong> is up to you, whatever makes sense,<\/li>\n<li><strong>Execute Step<\/strong> defaults to \u201cIf all previous steps finished successfully\u201d, but you can look at the options and choose which is most appropriate. I keep with the default because I don\u2019t want it to continue if something hasn\u2019t worked properly.<\/li>\n<li><strong>Platform<\/strong> relates to the version you are using,<\/li>\n<li><strong>Format stderr output<\/strong> as: defaults to Warning but if I want it to error if there is something that doesn\u2019t work quite right so I often change this to Error.<\/li>\n<li><strong>Script<\/strong>, select file as we are running a script from a file.<\/li>\n<li><strong>Script File<\/strong> is, you will notice that I\u2019ve used a parameter and then the \\ and the file name, we\u2019ll set the parameters shortly.<\/li>\n<li>Then you need to click on <strong>Expand<\/strong> and the script arguments will be displayed, you can see here I\u2019ve added in the 3 parameters that we set in the powershell script. We have to put parameter names in % and \u201c, I can\u2019t explain why I just know that we need to!!!<\/li>\n<\/ul>\n<p>Then we save it.<\/p>\n<p>Now we need to click on Parameters on the left menu to set our parameters.<\/p>\n<p>It will list all parameters used and there will be red text in the value box for those parameters with missing values.<\/p>\n<p>Populate the missing ones with the details you set in the powershell.<\/p>\n<p>To set the password ones, click on edit and click in here click on \u201cEdit\u201d and in display select Hidden and in Type select Password, that way you enter the password in once and then it\u2019s hidden from sight.<\/p>\n<p>Once these are all saved you can click on Run and Run the build, hopefully without error.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I\u2019m in the process of setting up a new environment using Azure SQL Databases, previously in Azure we\u2019ve just used an Azure VM with SQL Server on it.\u00a0\u00a0I\u2019m also fairly new to setting up a Continuous Integration environment and in-house we use Team City, so in this blog and probably the next few I\u2019m going&#8230;&hellip;<\/p>\n","protected":false},"author":10747,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[2],"tags":[],"coauthors":[57570],"class_list":["post-79391","post","type-post","status-publish","format-standard","hentry","category-blogs"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/79391","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/10747"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=79391"}],"version-history":[{"count":3,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/79391\/revisions"}],"predecessor-version":[{"id":79405,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/79391\/revisions\/79405"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=79391"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=79391"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=79391"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=79391"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}