Azure Deploy to non-global regions

Hi,

is it possible to deploy to the non-global Azure regions like Azure Germany (China, US Gov…) from within Octopus? They use different ActiveDirectory URLs as far as I know, so logging in with the normal account does not work. In PowerShell, for example, I needed to add the specific AD URL to be able to log in.

If not, any plans of adding this?

Thanks

Hi Sebastian,

Octopus does not currently have first-class support for non-global Azure Regions.

We do have plans to implement this, and in fact a member of the community has already contributed partial support for this (partial in that it is not exposed via the Octopus Portal UI).

Please understand, this is not a feature currently exercised by our internal tests.

You should be able to set the following variables in your project:

Octopus.Action.Azure.Environment
Octopus.Action.Azure.ActiveDirectoryEndPoint
Octopus.Action.Azure.ServiceManagementEndPoint
Octopus.Action.Azure.StorageEndpointSuffix //only required for Cloud Service deployments

You can get the values for these variables by executing PowerShell such as this (this example is specific to Germany).

i.e.

Octopus.Action.Azure.Environment = AzureGermanCloud
Octopus.Action.Azure.ActiveDirectoryEndPoint = https://management.core.cloudapi.de/
AdTenant
Octopus.Action.Azure.ServiceManagementEndPoint = https://management.core.cloudapi.de/
Octopus.Action.Azure.StorageEndpointSuffix = core.cloudapi.de

I hope this helps. Please consider updating this thread with your progress?

Regards,
Michael

Hi Michael,

thanks a lot for the info.

I created a new Project in Octopus, added the variables you mentioned and added my Azure Service principal account. The test of the Azure Account fails, which I guess is expected. But when I add the deploy step to my Project and select my account, I get this error so that I cannot select my web app:

System.Runtime.Serialization.SerializationException: There was an error deserializing the object of type Microsoft.IdentityModel.Clients.ActiveDirectory.TokenResponse. Encountered unexpected character ‘<’. —> System.Xml.XmlException: Encountered unexpected character ‘<’.

at System.Xml.XmlExceptionHelper.ThrowXmlException(XmlDictionaryReader reader, XmlException exception)

at System.Runtime.Serialization.Json.XmlJsonReader.Read()

at System.Xml.XmlBaseReader.IsStartElement()

at System.Xml.XmlBaseReader.IsStartElement(XmlDictionaryString localName, XmlDictionaryString namespaceUri)

at System.Runtime.Serialization.Json.DataContractJsonSerializer.InternalIsStartObject(XmlReaderDelegator reader)

at System.Runtime.Serialization.Json.DataContractJsonSerializer.InternalReadObject(XmlReaderDelegator xmlReader, Boolean verifyObjectName)

at System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator reader, Boolean verifyObjectName, DataContractResolver dataContractResolver)

— End of inner exception stack trace —

at Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext.RunAsyncTask[T](Task`1 task)

at Octopus.Worker.Azure.AzureAccountExtensions.GetAuthorizationToken(AzureServicePrincipalAccount account) in Z:\buildAgent\workDir\eec88466c176b607\source\Octopus.Worker\Azure\AzureAccountExtensions.cs:line 25

at Octopus.Server.Web.Api.Actions.AzureWebSitesListAction.GetSites(AzureServicePrincipalAccount servicePrincipalAccount) in Z:\buildAgent\workDir\eec88466c176b607\source\Octopus.Server\Web\Api\Actions\AzureWebSitesListAction.cs:line 87

at Octopus.Server.Web.Api.Actions.AzureWebSitesListAction.Execute() in Z:\buildAgent\workDir\eec88466c176b607\source\Octopus.Server\Web\Api\Actions\AzureWebSitesListAction.cs:line 50

at Octopus.Server.Web.Infrastructure.Api.Responder`1.Respond(TDescriptor options, NancyContext context) in Z:\buildAgent\workDir\eec88466c176b607\source\Octopus.Server\Web\Infrastructure\Api\Responder.cs:line 145

at System.Dynamic.UpdateDelegates.UpdateAndExecute3[T0,T1,T2,TRet](CallSite site, T0 arg0, T1 arg1, T2 arg2)

at Octopus.Server.Web.Api.OctopusRestApiModule.<>c__DisplayClass0_0.<.ctor>b__0(Object o) in Z:\buildAgent\workDir\eec88466c176b607\source\Octopus.Server\Web\Api\OctopusRestApiModule.cs:line 46

at Nancy.Routing.Route.<>c__DisplayClass4.b__3(Object parameters, CancellationToken context)

Did I understand your instruction correctly or did I do something wrong?

Thanks,
Sebastian

I apologize, I should have mentioned that you will not be able to use the drop-down to select your Web App. You will have to bind the value to a Variable. You can do this by checking the “Custom bindings” box next to the drop-down. If this is unavailable due to the error, you may have to bind the Account to a variable (similar to the process described here), which will force you to use a variable for the Web App also.

The support for alternate Azure regions was added to Calamari (our deployment agent executable), but (as you have seen) there is no support in the Octopus Portal UI as yet.

I did warn you it was not first-class :slight_smile:

Hi Michael,

No problem, thanks, I will try again.

Hi Michael,

I finally found the time to try it again.
I added the following config to my project variables and an Azure Web App deploy step:
[cid:image003.png@01D257C9.D053EDD0]

I had to change the AD URL because the one mentioned by you failed.
I tried using the OAuth2 flow with those URLs and that works fine for me (with login.microsoftonline.de as the OAuth Token Provider and management.microsoftazure.de as the service management endpoint). I also tried the service management endpoint https://management.core.cloudapi.de/ mentioned by you but the result is the same, so I guess it fails before that.

Now I get the error that it does not know the subscription. Does Octopus maybe still use the global AD? Is there a way that I can find more details about the actual request?

15:15:53 Info | Deploying to Azure WebApp ‘hq-dashboard’ in Resource Group hq-production, using subscription-id '8f855cd4-XXXXXXXXXX‘

15:15:53 Verbose | Authentication Context: https://login.microsoftonline.de/9960fe4d-XXXXXXXXXX

15:15:53 Error | Hyak.Common.CloudException: SubscriptionNotFound: The subscription ‘8f855cd4-XXXXXXXXXX’ could not be found.

15:15:53 Error | at Microsoft.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)

15:15:53 Error | at Microsoft.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccess(Task task)

15:15:53 Error | at Microsoft.Azure.Management.Resources.ResourceGroupOperationsExtensions.List(IResourceGroupOperations operations, ResourceGroupListParameters parameters)

15:15:53 Error | at Calamari.Azure.Integration.Websites.Publishing.ResourceManagerPublishProfileProvider.GetPublishProperties(String subscriptionId, String resourceGroupName, String siteName, String tenantId, String applicationId, String password, String serviceManagementEndPoint, String activeDirectoryEndPoint) in Z:\buildAgent\workDir\14ffc968155e4956\source\Calamari.Azure\Integration\Websites\Publishing\ResourceManagerPublishProfileProvider.cs:line 28

15:15:53 Error | at Calamari.Azure.Deployment.Conventions.AzureWebAppConvention.GetPublishProfile(VariableDictionary variables) in Z:\buildAgent\workDir\14ffc968155e4956\source\Calamari.Azure\Deployment\Conventions\AzureWebAppConvention.cs:line 96

15:15:53 Error | at Calamari.Azure.Deployment.Conventions.AzureWebAppConvention.Install(RunningDeployment deployment) in Z:\buildAgent\workDir\14ffc968155e4956\source\Calamari.Azure\Deployment\Conventions\AzureWebAppConvention.cs:line 29

15:15:53 Error | at Calamari.Deployment.ConventionProcessor.RunInstallConventions() in Z:\buildAgent\workDir\14ffc968155e4956\source\Calamari\Deployment\ConventionProcessor.cs:line 60

15:15:53 Error | at Calamari.Deployment.ConventionProcessor.RunConventions() in Z:\buildAgent\workDir\14ffc968155e4956\source\Calamari\Deployment\ConventionProcessor.cs:line 28

15:15:53 Error | Running rollback conventions…

15:15:53 Error | Hyak.Common.CloudException: SubscriptionNotFound: The subscription '8f855cd4-XXXXXXXXXXX‘ could not be found.

15:15:53 Error | at Microsoft.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)

15:15:53 Error | at Microsoft.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccess(Task task)

15:15:53 Error | at Microsoft.Azure.Management.Resources.ResourceGroupOperationsExtensions.List(IResourceGroupOperations operations, ResourceGroupListParameters parameters)

15:15:53 Error | at Calamari.Azure.Integration.Websites.Publishing.ResourceManagerPublishProfileProvider.GetPublishProperties(String subscriptionId, String resourceGroupName, String siteName, String tenantId, String applicationId, String password, String serviceManagementEndPoint, String activeDirectoryEndPoint) in Z:\buildAgent\workDir\14ffc968155e4956\source\Calamari.Azure\Integration\Websites\Publishing\ResourceManagerPublishProfileProvider.cs:line 28

15:15:53 Error | at Calamari.Azure.Deployment.Conventions.AzureWebAppConvention.GetPublishProfile(VariableDictionary variables) in Z:\buildAgent\workDir\14ffc968155e4956\source\Calamari.Azure\Deployment\Conventions\AzureWebAppConvention.cs:line 96

15:15:53 Error | at Calamari.Azure.Deployment.Conventions.AzureWebAppConvention.Install(RunningDeployment deployment) in Z:\buildAgent\workDir\14ffc968155e4956\source\Calamari.Azure\Deployment\Conventions\AzureWebAppConvention.cs:line 29

15:15:53 Error | at Calamari.Deployment.ConventionProcessor.RunInstallConventions() in Z:\buildAgent\workDir\14ffc968155e4956\source\Calamari\Deployment\ConventionProcessor.cs:line 60

15:15:53 Error | at Calamari.Deployment.ConventionProcessor.RunConventions() in Z:\buildAgent\workDir\14ffc968155e4956\source\Calamari\Deployment\ConventionProcessor.cs:line 50

15:15:53 Error | at Calamari.Azure.Commands.DeployAzureWebCommand.Execute(String[] commandLineArguments) in Z:\buildAgent\workDir\14ffc968155e4956\source\Calamari.Azure\Commands\DeployAzureWebCommand.cs:line 86

15:15:53 Error | at Calamari.Program.Execute(String[] args) in Z:\buildAgent\workDir\14ffc968155e4956\source\Calamari\Program.cs:line 45

15:15:54 Fatal | The remote script failed with exit code 100

15:15:54 Verbose | at Octopus.Worker.Scripting.ScriptResult.EnsureSuccessful() in Z:\buildAgent\workDir\eec88466c176b607\source\Octopus.Worker\Scripting\ScriptResult.cs:line 69

                |       at Octopus.Server.Orchestration.Deploy.DeploymentTaskController.<>c__DisplayClass24_0.<ExecuteActionAndInitLoggingContext>b__0() in Z:\buildAgent\workDir\eec88466c176b607\source\Octopus.Server\Orchestration\Deploy\DeploymentTaskController.cs:line 280

                |       at Octopus.Server.Orchestration.Deploy.DeploymentTaskController.ExecuteWithTransientErrorDetection(Action action, Machine machine) in Z:\buildAgent\workDir\eec88466c176b607\source\Octopus.Server\Orchestration\Deploy\DeploymentTaskController.cs:line 384

                |       at Octopus.Server.Orchestration.Deploy.DeploymentTaskController.ExecuteActionAndInitLoggingContext(PlannedStep step, Machine machine, PlannedAction action) in Z:\buildAgent\workDir\eec88466c176b607\source\Octopus.Server\Orchestration\Deploy\DeploymentTaskController.cs:line 278

Thanks a lot!
Sebastian

From: Sebastian Röschmailto:Sebastian@hellohq.io
Sent: Freitag, 9. Dezember 2016 04:12
To: Michael Richardsonmailto:tender2+d772bd1ce6@tenderapp.com
Subject: Re: Azure Deploy to non-global regions [Questions #10032]

Hi Michael,

No problem, thanks, I will try again.

Sebastian,

Looking at the bottom of this class from the Azure PowerShell repository, it would seem your value of https://login.microsoftonline.de is correct for the Authentication Endpoint.
Perhaps try https://management.microsoftazure.de/ for the Octopus.Action.Azure.ServiceManagementEndPoint value?

If that doesn’t help, Calamari (our executable that performs deployments) is open-source. The class that is throwing the exception can be seen here, and also of interest is where the authorization token is built here.
You could try extracting this code out so you can play and debug it.

You are quite possibly the first person attempting this, as I believe the contributor of that functionality was using Azure China.

Regards,
Michael

Hi Michael,

Thank you for the help. I managed to identify the issue and fix it. I created a pull request and would love to hear your feedback.

Thank you,
Sebastian

Hi Michael,

I wrote a short post about how Azure Web App deploy works for me in Azure Germany with Octopus. Maybe interesting for you?

https://www.hellohq.io/octopus-deploy-with-azure-germany/

Best regards,

Sebastian

Hi Sebastian,

That looks awesome! I’m planning on finishing that PR merge today. We don’t have access to any non-public Azure regions, which hampers us a bit.

Regards,

Robert W

Hi Sebastian,

I’ve added the latest version of Calamari into the main Octopus release, and it will be included in 3.7.14.

I had to modify your change to add a separate variable, as each region has two different management API endpoints. See this Octopus issue for details.

Thanks again for your contribution.

Robert W

Hi Robert,

Any time, thanks a lot for the help. Looking forward to the release.