Virtual Private Network (VPN)

Learn how to connect AEM as a Cloud Service with your VPN to create secure communication channels between AEM and internal services.

What is Virtual Private Network?

Virtual Private Network (VPN) allows an AEM as a Cloud Service customer to connect the AEM environments within a Cloud Manager Program to an existing, supported VPN. This allows secure, and controlled connections between AEM as a Cloud Service and services within the customer’s network.

A Cloud Manager Program can only have a single network infrastructure type. Ensure that Virtual Private Network is the most appropriate type of network infrastructure for your AEM as a Cloud Service before executing the following commands.

NOTE
Please note, connecting the build environment from Cloud Manager to a VPN is not supported. If you must access binary artifacts from a private repository, you must set up a secure and password-protected repository with a URL that is available on the public internet as described here.

Prerequisites

The following are required when setting up Virtual Private Network:

For more details watch the following walkthrough for how to setup, configure, and obtain Cloud Manger API credentials, and how to use them to make a Cloud Manager API call.

Transcript
So I’m going to show you how to create an Adobe Developer project that facilitates the integration with Cloud Manager’s APIs. This could be as simple as making curl commands to the Cloud Manager API endpoints, or as complex as scripting integrations with Cloud Manager’s APIs from an external CICD system. So the first thing we’ll do is head over to developer.adobe.com and click the console button to open a console. If you’re part of multiple orgs, make sure that you have the one selected that contains the Cloud Manager product that you’ll be interacting with.
And then also make sure that you are either in the system administrator role or have API developer access within your organization. So let’s head over to projects, and we can just create a brand new project here. I’ll create an empty project.
And I like to name my project so I can find it later if I need to. So I’m going to just call this Cloud Manager APIs. You can name this anything you want.
We can add a description as well, and we can save our project. All right, so now that we’ve saved it, we are in our project here. And the first thing we want to do is add the Cloud Manager API. So go ahead and add an API.
We’ll head over to Experience Cloud and locate Cloud Manager and select it. Now, if you don’t have this option, that typically means that you are in the wrong IMS org up here at the top, or possibly you don’t have access to this integration. Next, we’ll need to define some credentials that we’ll use to interact with this project. So we have the option to just generate a public and private key pair, or if you have your own, you can always upload your public key at this step. Note that you can do both of these things later on. So you can always generate new key pairs in Adobe Developer Console itself, or you could upload your own private key if you wanted to generate one offline later. For simplicity, let’s just generate a new key pair here.
And you’ll notice that a key pair has been generated. Here’s the public key, and the public and private key pair were both downloaded automatically to my local machine. So Adobe Developer Console doesn’t actually store a copy of the private key. That’s your responsibility to make sure it’s kept in a safe place. So it downloads automatically and then you need to put that in some sort of secret management system. All right, so we should be good to go here. So let’s go ahead and click next And next, we need to select product profiles for this integration. So essentially, product profiles define access to specific feature, and in this case, specific APIs that we can call within the Cloud Manager API set. And if we actually go over to the Cloud Manager docs.
These are all documented very well. So we can go to detailed permission list. And as you can see here, each API operation is listed as well as whatever product profiles are required to make this call. So you can go down here and make sure that you are assigning the product profiles necessary for whatever job you’re going to be doing with this integration. Typically, deployment manager and business owner are all you need. So let’s head back here, and let’s just give our integration, both of these access so we can access the full suite of APIs.
Save our changes.
There’s a few things to call out here. So if we scroll down on under the API section here, under Cloud Manager, we see our service account or JWT credentials. So here’s our client ID. We can reveal our client secret, some technical account information, organization ID. And you will need some of these when making your calls to the Cloud Manager HTTP APIs, but you can get all these values here. Also worth noting that these are the same credentials that are displayed under the credentials service account JWT screen. So these are the same ones. So don’t be confused by these two sets here. So as mentioned before during the setup of the project, we can manage all of our public keys that are associated with this project right here. So if we ever wanted to get rid of an existing one or add some more for different clients, we can take care of that all right here in this screen.
The last thing I want to show you is how we can generate a access bear token that can be used with the Cloud Manager API calls. So if we head over to the Cloud Manager API integration, you’ll see that there is a generate access token section here and we can paste our private key in. Remember, when we generated this project, I downloaded this public/private key pair in this config.zip. So let’s go ahead and open this up.
And open the private key up.
And we can select all of it and copy its contents. And make sure you include the begin private key string as well as the end private key string at the bottom. We can take that private key, paste it into the private key field to have generate token. And this will generate an access token that we can use as our bear token. We’re making our calls to Cloud Manager’s HTTP API.
Now that we have our Adobe Developer Console project set up that we can use to make calls to the Cloud Manager HTTP APIs, let’s try that out. So down below here in visual source code, I have a stubbed out curl request that calls the Cloud Manager API that lists the regions for an AEM as a Cloud Service program. And we’ll need to provide a few things like the program ID, the organization ID, client ID, and access token. So the first thing let’s tackle is getting the program ID. And this is actually something we get from Cloud Manager itself rather than from the Adobe Developer Console. So this is the program ID of the AEM as a Cloud Service program that we want to get the regions for.
So we’ll click into our program three, which is the program we’ll be using here. And there’s a couple places we can get it from, for instance, it’s available up here in the URL next to program, or we can go to the environment.
And you can see all of our URLs have the P49018 segment.
So this means the program ID is 49018. So let’s just go ahead and put that in here, 49018. Next, we need the organization ID. And if you recall, this is something that we saw in the Adobe Developer Console project. So let’s head over here. Again, let’s head down to Cloud Manager, and we could also have gone to the credentials service account, but down here at the bottom, we have some credentials.
We have an organization ID right here. So let’s just copy that and paste that in. Next is the client ID. So again, we can look up here and there’s the client ID listed. So let’s just go ahead and copy this and paste that in as well. The last item is the access token. So as you recall, we can generate an access token for this by pasting the private key in this field and generating a token for ourselves. Previously, we had downloaded the private and public key pair that was generated for the project to my local machine. I do have this saved. However, I do want to show you how you can generate a new one if you happen to have lost the original, or if someone else has generated the original. So we can pretend that I’ve lost it in this scenario. So what we can do to generate a new one or provide a new key set is head up to credentials service account, head down to the bottom. And you can see any existing public keys that are associated with this account, and we can either add a new public key if we’ve generated a new public/private key pair locally, or we can just generate a new one, just like we did during project creation. So again, for simplicity, I’ll simply generate a new one.
And again, just like before, it will automatically start to download for the public and private key pair here. So let’s go ahead and open this up. And we can head into the file, and just like before, open the private key. So we can make sure this is all selected.
And then head back to the Adobe Developer Console. And remember, we’ll have to head over to the APIs Cloud Manager for this and paste it into generate access token.
All right, and now this has successfully created our new access token that we can put into our curl command. So let’s copy that. And beware, this is rather long, but that’s fine. So we’ll go ahead and copy and paste it in. And now what we can do is simply take this curl command and run it.
And there we go. We can see down here at the bottom, we actually have a JSON object coming back. Has a total number of seven regions listed and each region has a name in the list. So as we can see here, we successfully authenticated our Cloud Manager API call using our Adobe Developer Console project. -

This tutorial uses curl to make the Cloud Manager API configurations. The provided curl commands assume a Linux/macOS syntax. If using the Windows command prompt, replace the \ line-break character with ^.

Enable Virtual Private Network per program

Start by enabling the Virtual Private Network on AEM as a Cloud Service.

  1. First, determine the region in which the Advanced Networking is needed by using the Cloud Manager API listRegions operation. The region name is required to make subsequent Cloud Manager API calls. Typically, the region the Production environment resides in is used.

    Find your AEM as a Cloud Service environment’s region in Cloud Manager under the environment’s details. The region name displayed in Cloud Manager can be mapped to the region code used in the Cloud Manager API.

    listRegions HTTP request

    code language-shell
    $ curl -X GET https://cloudmanager.adobe.io/api/program/{programId}/regions \
        -H 'x-gw-ims-org-id: <ORGANIZATION_ID>' \
        -H 'x-api-key: <CLIENT_ID>' \
        -H 'Authorization: Bearer <ACCESS_TOKEN>' \
        -H 'Content-Type: application/json'
    
  2. Enable Virtual Private Network for a Cloud Manager Program using Cloud Manager APIs createNetworkInfrastructure operation. Use the appropriate region code obtained from the Cloud Manager API listRegions operation.

    createNetworkInfrastructure HTTP request

    code language-shell
    $ curl -X POST https://cloudmanager.adobe.io/api/program/{programId}/networkInfrastructures \
        -H 'x-gw-ims-org-id: <ORGANIZATION_ID>' \
        -H 'x-api-key: <CLIENT_ID>' \
        -H 'Authorization: Bearer <ACCESS_TOKEN>' \
        -H 'Content-Type: application/json'
        -d @./vpn-create.json
    

    Define the JSON parameters in a vpn-create.json and provided to curl via ... -d @./vpn-create.json.

    Download the example vpn-create.json. This file only an example. Configure your file as required based on the optional/required fields documented at enableEnvironmentAdvancedNetworkingConfiguration.

    code language-json
    {
        "kind": "vpn",
        "region": "va7",
        "addressSpace": [
            "10.104.182.64/26"
        ],
        "dns": {
            "resolvers": [
                "10.151.201.22",
                "10.151.202.22",
                "10.154.155.22"
            ],
            "domains": [
                "wknd.site",
                "wknd.com"
            ]
        },
        "connections": [{
            "name": "connection-1",
            "gateway": {
                "address": "195.231.212.78",
                "addressSpace": [
                    "10.151.0.0/16",
                    "10.152.0.0/16",
                    "10.153.0.0/16",
                    "10.154.0.0/16",
                    "10.142.0.0/16",
                    "10.143.0.0/16",
                    "10.124.128.0/17"
                ]
            },
            "sharedKey": "<secret_shared_key>",
            "ipsecPolicy": {
                "dhGroup": "ECP256",
                "ikeEncryption": "AES256",
                "ikeIntegrity": "SHA256",
                "ipsecEncryption": "AES256",
                "ipsecIntegrity": "SHA256",
                "pfsGroup": "ECP256",
                "saDatasize": 102400000,
                "saLifetime": 3600
            }
        }]
    }
    

    Wait 45-60 minutes for the Cloud Manager Program to provision the network infrastructure.

  3. Check that the environment has finished Virtual Private Network configuration using the Cloud Manager API getNetworkInfrastructure operation, using the id returned from the createNetworkInfrastructure HTTP request in the previous step.

    getNetworkInfrastructure HTTP request

    code language-shell
    $ curl -X GET https://cloudmanager.adobe.io/api/program/{programId}/networkInfrastructure/{networkInfrastructureId} \
        -H 'x-gw-ims-org-id: <ORGANIZATION_ID>' \
        -H 'x-api-key: <CLIENT_ID>' \
        -H 'Authorization: <YOUR_BEARER_TOKEN>' \
        -H 'Content-Type: application/json'
    

    Verify that the HTTP response contains a status of ready. If not yet ready recheck the status every few minutes.

Configure Virtual Private Network proxies per environment

  1. Enable and configure the Virtual Private Network configuration on each AEM as a Cloud Service environment using the Cloud Manager API enableEnvironmentAdvancedNetworkingConfiguration operation.

    enableEnvironmentAdvancedNetworkingConfiguration HTTP request

    code language-shell
    $ curl -X PUT https://cloudmanager.adobe.io/api/program/{programId}/environment/{environmentId}/advancedNetworking \
        -H 'x-gw-ims-org-id: <ORGANIZATION_ID>' \
        -H 'x-api-key: <CLIENT_ID>' \
        -H 'Authorization: Bearer <ACCESS_TOKEN>' \
        -H 'Content-Type: application/json' \
        -d @./vpn-configure.json
    

    Define the JSON parameters in a vpn-configure.json and provided to curl via ... -d @./vpn-configure.json.

    Download the example vpn-configure.json

    code language-json
    {
        "nonProxyHosts": [
            "example.net",
            "*.example.org"
        ],
        "portForwards": [
            {
                "name": "mysql.example.com",
                "portDest": 3306,
                "portOrig": 30001
            },
            {
                "name": "smtp.sendgrid.com",
                "portDest": 465,
                "portOrig": 30002
            }
        ]
    }
    

    nonProxyHosts declares a set of hosts for which port 80 or 443 should be routed through the default shared IP address ranges rather than the dedicated egress IP. nonProxyHosts may be useful as traffic egressing through shared IPs may be further optimized automatically by Adobe.

    For each portForwards mapping, the advanced networking defines the following forwarding rule:

    table 0-row-5 1-row-5
    Proxy host Proxy port External host External port
    AEM_PROXY_HOST portForwards.portOrig portForwards.name portForwards.portDest

    If your AEM deployment only requires HTTP/HTTPS connections to external service, leave the portForwards array empty, as these rules are only required for non-HTTP/HTTPS requests.

  2. For each environment, validate the vpn routing rules are in effect using the Cloud Manager API’s getEnvironmentAdvancedNetworkingConfiguration operation.

    getEnvironmentAdvancedNetworkingConfiguration HTTP request

    code language-shell
    $ curl -X GET https://cloudmanager.adobe.io/api/program/{programId}/environment/{environmentId}/advancedNetworking \
        -H 'x-gw-ims-org-id: <ORGANIZATION_ID>' \
        -H 'x-api-key: <CLIENT_ID>' \
        -H 'Authorization: Bearer <ACCESS_TOKEN>' \
        -H 'Content-Type: application/json'
    
  3. Virtual private network proxy configurations can be updated using the Cloud Manager API’s enableEnvironmentAdvancedNetworkingConfiguration operation. Remember enableEnvironmentAdvancedNetworkingConfiguration is a PUT operation, so all rules must be provided with every invocation of this operation.

  4. Now you can use the Virtual Private Network egress configuration in your custom AEM code and configuration.

Connecting to external services over the Virtual Private Network

With the Virtual Private Network enabled, AEM code and configuration can use them to make calls to external services via the VPN. There are two flavors of external calls that AEM treats differently:

  1. HTTP/HTTPS calls to external services
    • Includes HTTP/HTTPS calls made to services running on ports other than the standard 80 or 443 ports.
  2. non-HTTP/HTTPS calls to external services
    • Includes any non-HTTP calls, such as connections with Mail servers, SQL databases, or services that run on other non-HTTP/HTTPS protocols.

HTTP/HTTPS requests from AEM on standard ports (80/443) are allowed by default but they will not use the VPN connection if not configured appropriately as described below.

HTTP/HTTPS

When creating HTTP/HTTPS connections from AEM, when using VPN, HTTP/HTTPS connections are automatically proxied out of AEM. No additional code or configuration is required to support HTTP/HTTPS connections.

TIP
See AEM as a Cloud Service’s Virtual Private Network documentation for the full set of routing rules.

Code examples

HTTP/HTTPS

HTTP/HTTPS

Java™ code example making HTTP/HTTPS connection from AEM as a Cloud Service to an external service using HTTP/HTTPS protocol.

Non-HTTP/HTTPS connections code examples

When creating non-HTTP/HTTPS connections (ex. SQL, SMTP, and so on) from AEM, the connection must be made through a special host name provided by AEM.

Variable name
Use
Java™ code
OSGi configuration
AEM_PROXY_HOST
Proxy host for non-HTTP/HTTPS connections
System.getenv("AEM_PROXY_HOST")
$[env:AEM_PROXY_HOST]

Connections to external services are then called through the AEM_PROXY_HOST and the mapped port (portForwards.portOrig), which AEM then routes to the mapped external hostname (portForwards.name) and port (portForwards.portDest).

Proxy host
Proxy port
External host
External port
AEM_PROXY_HOST
portForwards.portOrig
portForwards.name
portForwards.portDest

Code examples

SQL connection using JDBC DataSourcePool

SQL connection using JDBC DataSourcePool

Java™ code example connecting to external SQL databases by configuring AEM's JDBC datasource pool.

SQL connection using Java APIs

SQL connection using Java™ APIs

Java™ code example connecting to external SQL databases using Java™'s SQL APIs.

Virtual Private Network (VPN)

E-mail service

OSGi configuration example using AEM's to connect to external e-mail services.

Limit access to AEM as a Cloud Service via VPN

The Virtual Private Network configuration limits access to AEM as a Cloud Service environments to a VPN.

Configuration examples

Applying an IP allow list

Applying an IP allowlist

Configure an IP allowlist such that only VPN traffic can access AEM.

Path-based VPN access restrictions to AEM Publish

Path-based VPN access restrictions to AEM Publish

Require VPN access for specific paths on AEM Publish.

recommendation-more-help
4859a77c-7971-4ac9-8f5c-4260823c6f69