Configure ArcGIS Server to use Azure file share

4483
3
Jump to solution
07-21-2020 04:26 AM
JohnFannon
Occasional Contributor III

Hi

We are trying to deploy a high availability architecture for ArcGIS Server (not Portal) v10.7.1 on Azure and need to configure ArcGIS Server instances to use an Azure file share for configuration and directories, but are having some issues with this.

Note that we are NOT using (and cannot use) Cloud Builder due to restrictions/standards in place on the customer's Azure environment. Instead the customers Dev Ops team has scripted the build of VMs and file shares etc. We are then manually installing and configuring ArcGIS Server on the VMs.

So far we have tried creating a mapped drive under the user account that ArcGIS Server is running under on the VM and using the UNC path in the site configuration options when creating a new site. This works initially, but then fails later and the site is unusable. 

So - my question is - what is the correct way to configure ArcGIS Server to use the Azure file share for configuration and directories?

I have found the following article relating to Amazon S3 setup, which suggests using createNewSite under the ArcGIS Server administration directory and then supplying some json configuration for the storage locations. I suspect we may need to do something similar for our Azure file share, but we can find no similar documentation for Azure:

Configure a highly available ArcGIS Server with a shared configuration store on Amazon storage servi... 

If anyone can point me in the direction of the documentation for Azure or give any guidance on this it would be greatly appreciated. Or perhaps if you have configured your site in this way (with or without cloud builder), you could supply the json that was used to configure it?

Regards

John

0 Kudos
1 Solution

Accepted Solutions
ChristopherPawlyszyn
Esri Contributor

I know this was about a month ago, but wanted to include my answer from another thread that I believe would apply in this use case as well.

How to enable Azure File share using SMB on deployed ArcGIS Server  

In the past when working with a customer we added the credentials to the Windows Credential Manager using the cmdkey command, then connected to the file share using the UNC path as opposed to a mapped drive. I don't remember having any additional difficulty at that point, but make sure you're running the cmdkey command below from a command prompt running as the service account user in Windows. Hope that helps!

 

cmdkey /add:<storage-account-name>.file.core.windows.net /user:AZURE\<storage-account-name> /pass:<storage-account-key>

 

External Reference (under the 'Access issues with an application or service account' subheading):

Tips & Tricks for Azure File Shares - Microsoft Tech Community - 277943


-- Chris Pawlyszyn

View solution in original post

3 Replies
ChristopherPawlyszyn
Esri Contributor

I know this was about a month ago, but wanted to include my answer from another thread that I believe would apply in this use case as well.

How to enable Azure File share using SMB on deployed ArcGIS Server  

In the past when working with a customer we added the credentials to the Windows Credential Manager using the cmdkey command, then connected to the file share using the UNC path as opposed to a mapped drive. I don't remember having any additional difficulty at that point, but make sure you're running the cmdkey command below from a command prompt running as the service account user in Windows. Hope that helps!

 

cmdkey /add:<storage-account-name>.file.core.windows.net /user:AZURE\<storage-account-name> /pass:<storage-account-key>

 

External Reference (under the 'Access issues with an application or service account' subheading):

Tips & Tricks for Azure File Shares - Microsoft Tech Community - 277943


-- Chris Pawlyszyn
JohnFannon
Occasional Contributor III

Sorry for the delayed response. We did resolve this issue through discussion with Microsoft, who's suggestion was to use the cmdkey utility exactly as you have described. Importantly, this needs to be run as the service account user by opening a command prompt as that user.

We were then able to use the UNC path in the ArcGIS Server configuration.

XuejinRuan
New Contributor III

Hi Chris,

We used this approach for a similar scenario, and it worked for ArcGIS server deployment. However, we ran into issues with ArcGIS Portal deployment. 

What we were trying to do is to configure an HA portal deployment. We wanted to put the portal Content folder in a shared network drive. Our shared network folder is in a different domain from the Portal for ArcGIS service domain account. There's  no trust relationship between file share domain and Portal for ArcGIS service account domain. We created an entry for Portal ArcGIS service account  in credentials manager to access the file share for its environment (we did exactly the same thing as you proposed). We were able to install the portal and we also saw items being created in the shared network drive content folder. However,  when portal get restarted. We see the following errors: 

dojo.js:142 GET https://domain:7443/arcgis/sharing/rest/portals/helpmap?culture=en-us&f=json 404
dojo.js:142 GET https://domain:7443/arcgis/sharing/rest/portals/self?culture=en-us&f=json 404
dojo.js:142 GET https://domain:7443/arcgis/sharing/rest/portals/self/settings?f=json 404

The workaround we came up with was to grant the Portal Service Account local admin privilege to the VM where ArcGIS Portal was installed. That would make things work. 

If we took away the local admin privilege, we could not access portal generateToken page. We did some further digging, and and it seemed only the following web app failed to start. Can you see what is going on behind the scene? What else should we do to make it work without granting Portal Service Account local admin privilege to the VM? 

12-Feb-2021 18:26:24.373 INFO [main] org.apache.catalina.core.ApplicationContext.log Initializing Spring root WebApplicationContext

12-Feb-2021 18:26:53.341 SEVERE [main] org.apache.catalina.core.StandardContext.listenerStart Exception sending context initialized event to listener instance of class [org.springframework.web.context.ContextLoaderListener]

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'accountsRequestHandler' defined in class path resource [spring/gw-dispatcher.xml]: Cannot resolve reference to bean 'gwAccounts' while setting bean property 'accounts'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'gwAccounts' defined in class path resource [spring/gw-config.xml]: Cannot resolve reference to bean 'gwCommunity' while setting bean property 'community'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'gwCommunity' defined in class path resource [spring/gw-config.xml]: Cannot resolve reference to bean 'securityPermissions' while setting bean property 'securityPermissions'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'securityPermissions' defined in class path resource [spring/gw-config.xml]: Cannot resolve reference to bean 'gwContent' while setting bean property 'content'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'gwContent' defined in class path resource [spring/gw-config.xml]: Invocation of init method failed; nested exception is com.esri.gw.GWException: ObjectStore must be set in GWContent

at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:378)

at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:110)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1602)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1354)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:572)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:495)

at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317)

at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)

at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315)

at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)

at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:759)

at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:869)

at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550)

at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:409)

at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:291)

at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:103)

at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4685)

at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5146)

at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)

at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:717)

at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:690)

at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:705)

at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:631)

at org.apache.catalina.startup.HostConfig$DeployDescriptor.run(HostConfig.java:1831)

at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)

at java.base/java.util.concurrent.FutureTask.run(Unknown Source)

at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)

at java.base/java.util.concurrent.AbstractExecutorService.submit(Unknown Source)

at org.apache.catalina.startup.HostConfig.deployDescriptors(HostConfig.java:526)

at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:425)

at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1576)

at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:309)

at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:123)

at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:423)

at org.apache.catalina.util.LifecycleBase.setState(LifecycleBase.java:366)

at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:936)

at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:841)

at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)

at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1384)

at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1374)

at java.base/java.util.concurrent.FutureTask.run(Unknown Source)

at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)

at java.base/java.util.concurrent.AbstractExecutorService.submit(Unknown Source)

at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:909)

at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:262)

at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)

at org.apache.catalina.core.StandardService.startInternal(StandardService.java:421)

at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)

at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:930)

at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)

at org.apache.catalina.startup.Catalina.start(Catalina.java:633)

at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)

at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

at java.base/java.lang.reflect.Method.invoke(Unknown Source)

at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:343)

at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:474)

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'gwAccounts' defined in class path resource [spring/gw-config.xml]: Cannot resolve reference to bean 'gwCommunity' while setting bean property 'community'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'gwCommunity' defined in class path resource [spring/gw-config.xml]: Cannot resolve reference to bean 'securityPermissions' while setting bean property 'securityPermissions'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'securityPermissions' defined in class path resource [spring/gw-config.xml]: Cannot resolve reference to bean 'gwContent' while setting bean property 'content'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'gwContent' defined in class path resource [spring/gw-config.xml]: Invocation of init method failed; nested exception is com.esri.gw.GWException: ObjectStore must be set in GWContent

at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:378)

at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:110)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1602)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1354)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:572)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:495)

at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317)

at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)

at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315)

at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)

at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:367)

... 56 more

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'gwCommunity' defined in class path resource [spring/gw-config.xml]: Cannot resolve reference to bean 'securityPermissions' while setting bean property 'securityPermissions'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'securityPermissions' defined in class path resource [spring/gw-config.xml]: Cannot resolve reference to bean 'gwContent' while setting bean property 'content'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'gwContent' defined in class path resource [spring/gw-config.xml]: Invocation of init method failed; nested exception is com.esri.gw.GWException: ObjectStore must be set in GWContent

at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:378)

at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:110)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1602)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1354)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:572)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:495)

at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317)

at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)

at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315)

at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)

at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:367)

... 66 more

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'securityPermissions' defined in class path resource [spring/gw-config.xml]: Cannot resolve reference to bean 'gwContent' while setting bean property 'content'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'gwContent' defined in class path resource [spring/gw-config.xml]: Invocation of init method failed; nested exception is com.esri.gw.GWException: ObjectStore must be set in GWContent

at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:378)

at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:110)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1602)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1354)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:572)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:495)

at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317)

at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)

at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315)

at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)

at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:367)

... 76 more

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'gwContent' defined in class path resource [spring/gw-config.xml]: Invocation of init method failed; nested exception is com.esri.gw.GWException: ObjectStore must be set in GWContent

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1699)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:573)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:495)

at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317)

at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)

at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315)

at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)

at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:367)

... 86 more

Caused by: com.esri.gw.GWException: ObjectStore must be set in GWContent

at com.esri.gw.content.GWContent.init(GWContent.java:8636)

at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)

at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

at java.base/java.lang.reflect.Method.invoke(Unknown Source)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeCustomInitMethod(AbstractAutowireCapableBeanFactory.java:1824)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1767)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1695)

... 93 more

 

 

With this set up, we have to grant Portal for ArcGIS service account local admin access to the machine where portal is installed in order to make things work if we put the content folder to the shared network drive.

 

 

 

0 Kudos