We are in the process of deploying ArcGIS Enterprise 11.1 and I have create a Cloudformation stack to deploy all the infra to AWS, however I am not overly familiar with the configuration of ArcGIS Enterprise, I've read a lot of documentation but would appreciate if someone more knowledgeable could review.
Our Planned installation will have a publicly accessible load balancer running under gis.company.com and we have Portal, ArcGIS Server, Datastore, a geoprocessing server, a imagery processing server, Ideally we would use SAML or OpenID to Azure AD/Entra ID and the arcgis and processing servers would be federated to portal (is this right?). We are planning to use FSX for configuration storage and I think I have set this up right. Also planning not to use the webadaptor
I was planning on routing paths /arcgis/rest/* /arcgis/services/*, /arcgis/admin to a target group for ArcGIS Servers, paths /portal/*, /arcgis/home/* /arcgis/sharing/*, /arcgis/portaladmin/* and /arcgis/portaladmin?* to a target group for Portal and /image/* to target group for Image Processing and /geoprocessing/* to a targetgroup for geoprocessing however I am not sure if this will work.
When using AWS Application Load balancer should I be directing 443 to 6443 on ArcGIS server or to 6080? Do I need to get certificate and install it on ArcGIS Server?
{
"Description": "Application Load balancer template or ESRI Setup",
"Parameters":{
"StackName":{
"Type":"String"
},
"BucketName":{
"Type":"String"
},
"VPCId":{
"Type":"String"
},
"PublicSubnets":{
"Type":"CommaDelimitedList"
},
"PrivateSubnets":{
"Type":"CommaDelimitedList"
},
"PortalInternalPort":{
"Type": "Number",
"Default": 7443
},
"PortalExternalPort":{
"Type": "Number",
"Default": 443
},
"AGSInternalPort":{
"Type": "Number",
"Default": 6443
},
"AGSExternalPort":{
"Type": "Number",
"Default": 443
},
"AGSFederationExternalPort":{
"Type": "Number",
"Default": 6443
},
"PortalFederationExternalPort":{
"Type": "Number",
"Default": 7443
},
"CertificateArn":{
"Type": "String"
},
"ALBSGId":{
"Type": "String"
},
"HealthCheckIntervalSeconds":{
"Type": "Number"
},
"PortalHealthCheckPath":{
"Type": "String"
},
"AGSHealthCheckPath":{
"Type": "String"
},
"HealthCheckProtocol":{
"Type": "String"
},
"PortalInstanceId":{
"Type": "String"
},
"HealthCheckTimeoutSeconds":{
"Type": "Number",
"Default": 10
},
"AGSInstanceId":{
"Type": "String"
},
"ImageProcInstanceId":{
"Type": "String"
},
"GeoProcInstanceId":{
"Type": "String"
},
"AccessLogPrefix":{
"Type": "String",
"Default": "access_log"
},
"ConnectionLogPrefix":{
"Type": "String",
"Default": "connection_log"
}
},
"Resources":{
"ALBLogBucket":{
"Type":"AWS::S3::Bucket",
"Properties":{
"BucketName":{"Ref":"BucketName"}
}
},
"ALBLogBucketPolicy":{
"Type":"AWS::S3::BucketPolicy",
"Properties":{
"Bucket":{"Ref":"BucketName"},
"PolicyDocument":{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::783225319266:root"
},
"Action": "s3:PutObject",
"Resource": [
{"Fn::Sub":"arn:aws:s3:::${BucketName}/${AccessLogPrefix}/AWSLogs/${AWS::AccountId}/*"},
{"Fn::Sub":"arn:aws:s3:::${BucketName}/${ConnectionLogPrefix}/AWSLogs/${AWS::AccountId}/*"}
]
}
]
}
}
},
"ALB": {
"Type": "AWS::ElasticLoadBalancingV2::LoadBalancer",
"Properties": {
"LoadBalancerName": {"Fn::Sub": "${AWS::StackName}-ALB"},
"Subnets": [
{"Fn::Select": [0,{"Ref": "PublicSubnets"}]},
{"Fn::Select": [1,{"Ref": "PublicSubnets"}]}
],
"Type": "application",
"SecurityGroups": [{"Ref": "ALBSGId"}],
"Scheme": "internet-facing",
"LoadBalancerAttributes": [
{
"Key": "idle_timeout.timeout_seconds",
"Value": "600"
},
{
"Key": "access_logs.s3.enabled",
"Value": true
},
{
"Key": "access_logs.s3.bucket",
"Value": { "Ref": "ALBLogBucket"}
},
{
"Key":"access_logs.s3.prefix",
"Value": {"Ref":"AccessLogPrefix"}
},
{
"Key": "connection_logs.s3.enabled",
"Value": true
},
{
"Key": "connection_logs.s3.bucket",
"Value": { "Ref": "ALBLogBucket"}
},
{
"Key": "connection_logs.s3.prefix",
"Value": {"Ref":"ConnectionLogPrefix"}
},
{
"Key": "routing.http.xff_header_processing.mode",
"Value": "append"
}
],
"Tags": [
{
"Key": "Name",
"Value": {"Fn::Sub": "${AWS::StackName}-ALB"}
}
]
},
"DependsOn":[
"ALBLogBucket",
"ALBLogBucketPolicy"
]
},
"TGAGS": {
"Type": "AWS::ElasticLoadBalancingV2::TargetGroup",
"Properties": {
"Name": "TG-AGS",
"Port": {"Ref": "AGSExternalPort"},
"Protocol": {"Ref":"HealthCheckProtocol"},
"TargetType": "instance",
"VpcId": { "Ref": "VPCId" },
"HealthCheckIntervalSeconds": { "Ref": "HealthCheckIntervalSeconds"},
"HealthCheckPath": {"Ref":"AGSHealthCheckPath"},
"HealthCheckProtocol": {"Ref": "HealthCheckProtocol"},
"HealthCheckTimeoutSeconds":{"Ref":"HealthCheckTimeoutSeconds"},
"HealthCheckPort":{"Ref":"AGSInternalPort"},
"Targets":[
{
"Id": {"Ref":"AGSInstanceId"},
"Port": {"Ref":"AGSInternalPort"}
}
]
}
},
"TGPortal": {
"Type": "AWS::ElasticLoadBalancingV2::TargetGroup",
"Properties": {
"Name": "TG-Portal",
"Port": {"Ref": "PortalExternalPort"},
"Protocol": "HTTPS",
"TargetType": "instance",
"VpcId": { "Ref": "VPCId" },
"HealthCheckIntervalSeconds": { "Ref": "HealthCheckIntervalSeconds"},
"HealthCheckPath": { "Ref": "PortalHealthCheckPath"},
"HealthCheckProtocol": "HTTPS",
"HealthCheckTimeoutSeconds":{"Ref":"HealthCheckTimeoutSeconds"},
"HealthCheckPort":{"Ref":"PortalInternalPort"},
"Targets":[
{
"Id": {"Ref":"PortalInstanceId"},
"Port": {"Ref":"PortalInternalPort"}
}
]
}
},
"TGGeoProc": {
"Type": "AWS::ElasticLoadBalancingV2::TargetGroup",
"Properties": {
"Name": "TG-GeoProc",
"Port": {"Ref": "AGSExternalPort"},
"Protocol": {"Ref":"HealthCheckProtocol"},
"TargetType": "instance",
"VpcId": { "Ref": "VPCId" },
"HealthCheckIntervalSeconds": { "Ref": "HealthCheckIntervalSeconds"},
"HealthCheckPath": { "Ref": "PortalHealthCheckPath"},
"HealthCheckProtocol": {"Ref": "HealthCheckProtocol"},
"HealthCheckTimeoutSeconds":{"Ref":"HealthCheckTimeoutSeconds"},
"HealthCheckPort":{"Ref":"AGSInternalPort"},
"Targets":[
{
"Id": {"Ref":"GeoProcInstanceId"},
"Port": {"Ref":"AGSInternalPort"}
}
]
}
},
"TGImageProc": {
"Type": "AWS::ElasticLoadBalancingV2::TargetGroup",
"Properties": {
"Name": "TG-ImageProc",
"Port": {"Ref": "AGSExternalPort"},
"Protocol": {"Ref":"HealthCheckProtocol"},
"TargetType": "instance",
"VpcId": { "Ref": "VPCId" },
"HealthCheckIntervalSeconds": { "Ref": "HealthCheckIntervalSeconds"},
"HealthCheckPath": { "Ref": "AGSHealthCheckPath"},
"HealthCheckProtocol": {"Ref": "HealthCheckProtocol"},
"HealthCheckTimeoutSeconds":{"Ref":"HealthCheckTimeoutSeconds"},
"HealthCheckPort":{"Ref":"AGSInternalPort"},
"Targets":[
{
"Id": {"Ref":"ImageProcInstanceId"},
"Port": {"Ref":"AGSInternalPort"}
}
]
}
},
"ListenerHTTPS":{
"Type": "AWS::ElasticLoadBalancingV2::Listener",
"Properties":{
"LoadBalancerArn": { "Ref": "ALB"},
"Port": 443,
"Protocol": "HTTPS",
"SslPolicy": "ELBSecurityPolicy-TLS13-1-2-2021-06",
"Certificates":[
{"CertificateArn": { "Ref": "CertificateArn"}}
],
"DefaultActions": [
{
"Type": "redirect",
"RedirectConfig":{
"Protocol": "HTTPS",
"Host": "#{host}",
"Path": "/arcgis/home/",
"StatusCode": "HTTP_301"
}
}
]
}
},
"ListenerFederation6443":{
"Type": "AWS::ElasticLoadBalancingV2::Listener",
"Properties":{
"LoadBalancerArn": { "Ref": "ALB"},
"Port": {"Ref": "AGSFederationExternalPort"},
"Protocol": "HTTPS",
"SslPolicy": "ELBSecurityPolicy-TLS13-1-2-2021-06",
"Certificates":[
{"CertificateArn": { "Ref": "CertificateArn"}}
],
"DefaultActions": [
{
"Type": "forward",
"ForwardConfig":{
"TargetGroups": [
{
"TargetGroupArn": { "Ref": "TGAGS" }
}
]
}
}
]
}
},
"ListenerFederation7443":{
"Type": "AWS::ElasticLoadBalancingV2::Listener",
"Properties":{
"LoadBalancerArn": { "Ref": "ALB"},
"Port": {"Ref": "PortalFederationExternalPort"},
"Protocol": "HTTPS",
"SslPolicy": "ELBSecurityPolicy-TLS13-1-2-2021-06",
"Certificates":[
{"CertificateArn": { "Ref": "CertificateArn"}}
],
"DefaultActions": [
{
"Type": "forward",
"ForwardConfig":{
"TargetGroups": [
{
"TargetGroupArn": { "Ref": "TGPortal" }
}
]
}
}
]
}
},
"ListenerRuleAGS": {
"Type": "AWS::ElasticLoadBalancingV2::ListenerRule",
"DependsOn": "ALB",
"Properties": {
"Actions": [
{
"Type": "forward",
"TargetGroupArn": { "Ref": "TGAGS" }
}
],
"Conditions": [
{
"Field": "path-pattern",
"Values": [
"/arcgis/rest/*",
"/arcgis/admin/*",
"/arcgis/services/*"
]
}
],
"ListenerArn": { "Fn::GetAtt": ["ListenerHTTPS", "ListenerArn"] },
"Priority": 20
}
},
"ListenerRulePortal": {
"Type": "AWS::ElasticLoadBalancingV2::ListenerRule",
"DependsOn": "ALB",
"Properties": {
"Actions": [
{
"Type": "forward",
"TargetGroupArn": { "Ref": "TGPortal" }
}
],
"Conditions": [
{
"Field": "path-pattern",
"Values": [
"/portal/*",
"/arcgis/home/*",
"/arcgis/sharing/*",
"/arcgis/portaladmin/*",
"/arcgis/portaladmin?*"
]
}
],
"ListenerArn": { "Fn::GetAtt": ["ListenerHTTPS", "ListenerArn"] },
"Priority": 10
}
},
"ListenerRuleGeoProc": {
"Type": "AWS::ElasticLoadBalancingV2::ListenerRule",
"DependsOn": "ALB",
"Properties": {
"Actions": [
{
"Type": "forward",
"TargetGroupArn": { "Ref": "TGGeoProc" }
}
],
"Conditions": [
{
"Field": "path-pattern",
"Values": ["/geoprocessing/*"]
}
],
"ListenerArn": { "Fn::GetAtt": ["ListenerHTTPS", "ListenerArn"] },
"Priority": 30
}
},
"ListenerRuleImageProc": {
"Type": "AWS::ElasticLoadBalancingV2::ListenerRule",
"DependsOn": "ALB",
"Properties": {
"Actions": [
{
"Type": "forward",
"TargetGroupArn": { "Ref": "TGImageProc" }
}
],
"Conditions": [
{
"Field": "path-pattern",
"Values": ["/image/*"]
}
],
"ListenerArn": { "Fn::GetAtt": ["ListenerHTTPS", "ListenerArn"] },
"Priority": 40
}
},
"ListenerRuleRedirectArcGISManagerToVoid":{
"Type": "AWS::ElasticLoadBalancingV2::ListenerRule",
"DependsOn": "ALB",
"Properties": {
"Actions": [
{
"Type": "fixed-response",
"FixedResponseConfig": {
"StatusCode": "403"
}
}
],
"Conditions": [
{
"Field": "path-pattern",
"Values": [
"/arcgis/manager*",
"/arcgis/admin/*"
]
}
],
"ListenerArn": { "Fn::GetAtt": ["ListenerHTTPS", "ListenerArn"] },
"Priority": 70
}
}
},
"Outputs":{
}
}
Anything else I should know or any obvious mistakes/missteps here?
Solved! Go to Solution.
Hey @KarlC ,
I don't have time review your entire CFT, but a couple things from your initial description:
Hope this helps.
Hey @KarlC ,
I don't have time review your entire CFT, but a couple things from your initial description:
Hope this helps.