# Akamai Edge-side personalization

> Classify visitors and execute personalization instructions on the edge with Akamai.

Source: https://docs.uniform.app/docs/integrations/cdn/akamai/akamai-edge-personalization

You can use Akamai to classify visitors and execute personalization
instructions on the edge. This approach gives you the user
experience benefits of server-side rendering with the performance
and scalability benefits of a CDN.

> **Tip:**
>
> For more information about the benefits of executing personalization
> using Akamai EdgeWorkers, see the overview
> of [edge-side personalization](https://docs.uniform.app/docs/guides/personalization/edge-side-personalization).

> **Before you start:**
>
> You must have the following available to complete
> the instructions in this section:
>
> 1. Entitlement for EdgeWorkers in your Akamai contract. [Akamai documentation](https://techdocs.akamai.com/edgeworkers/docs/add-edgeworkers-to-contract)
>    has more details.
> 2. Administrator access to [Akamai Control Center](https://control.akamai.com/).
> 3. Ability to [clone](https://docs.github.com/en/repositories/creating-and-managing-repositories/cloning-a-repository) a GitHub repository.
> 4. [Node.js](https://nodejs.dev/) v16+ installed locally.
> 5. An application with [edge-side personalization activated](https://docs.uniform.app/docs/guides/personalization/activate-personalization#edge-side).
> 6. Npm access token from Uniform. Edge-side personalization requires private packages. If you don't have an access token, [contact us](mailto:support@uniform.dev?subject=Access+token+for+edge+personalization).

## Configure CLI

The Akamai CLI enables you to send commands to Akamai without
having to log into the Akamai Control Center. Entering commands
on the CLI is faster than having to navigate through a lot of
different screens in the Control Center.

> **Tip:**
>
> All the required configuration can be accomplished using
> the Akamai Control Center, which gives you a GUI to work in.
> Using the CLI allows you to write scripts to automate the
> configuration, backup and recovery processes.
>
> Akamai also offers an API that you can use as an alternative
> to the CLI.

### Create API client

An API client provides the credentials the CLI will use in
order to send commands to Akamai. You can create an API
client in the Akamai Control Center.

1. Identify the home directory on your local machine.

   `zsh (MacOS/Linux)`

   ```bash
   cd ~
   ```

   `PowerShell (Windows)`

   ```powershell
   cd $HOME
   ```

   > **Note:**
   >
   > The CLI runs on your local machine. It uses settings
   > from a file located in your home directory.
2. Create a file in your home directory `.edgerc`
3. Add the following to the file:

   ```
   [papi]

   [default]
   ```
4. Log into the Akamai Control Center.
5. Navigate to **ACCOUNT ADMIN > Identity & access**.
6. Click **Create API client**.
7. For the API client type select **Myself**.
8. Click **Quick**.
9. Find the section **Credentials**.
10. Click **Copy credential**.
11. Paste the contents of your clipboard into the file `.edgerc`
    under the sections **papi** and **default**. The file should
    look like the following:

    ```
    [papi]
    client_secret = ????????????????????????????????????????????
    host = ??????????????????????????????????????????????????????????
    access_token = ????-????????????????-????????????????
    client_token = ????-????????????????-????????????????

    [default]
    client_secret = ????????????????????????????????????????????
    host = ??????????????????????????????????????????????????????????
    access_token = ????-????????????????-????????????????
    client_token = ????-????????????????-????????????????
    ```
12. Save the file.

### Install CLI

The Akamai CLI is a small program that must be installed on your local machine.

1. Install the [Akamai CLI](https://github.com/akamai/cli).
2. Open a CLI & enter the following commands:

   ```
   akamai install edgeworkers
   akamai install property-manager
   ```

   > **Note:**
   >
   > The CLI is a generic tool. You have to install the
   > functionality you want to use. This adds the commands
   > to interact with EdgeWorkers and the Property Manager.

## Retrieve settings

Before you can create a new property in Akamai, there are
a few settings you must retrieve using the CLI:

| Setting | Retrieval instructions | More information |
| --- | --- | --- |
| Contract ID | [Get contract ID](#contract-id) | [Akamai docs](https://techdocs.akamai.com/property-mgr/reference/get-contracts) |
| Product ID | [Get product ID](#product-id) | [Akamai docs](https://techdocs.akamai.com/property-mgr/reference/get-products) |
| Group ID | [Get group ID](#group-id) | [Akamai docs](https://techdocs.akamai.com/property-mgr/reference/get-groups) |
| Resource tier | [Get resource tier](#resource-tier) | [Akamai docs](https://techdocs.akamai.com/edgeworkers/reference/get-resource-tiers) |

### Contract ID

```
akamai property-manager list-contracts --format json
```

You will get a response like the following:

```json
[
    {
        "contractId": "ctr_P-1234567",
        "contractTypeName": "DIRECT_CUSTOMER"
    }
]
```

> **Attention:**
>
> Using the example above, the contract is `P-1234567`.
> You must remove the `ctr_` from the value.

### Product ID

```
akamai property-manager list-products \
    --contractId <YOUR CONTRACT ID> \
    --format json
```

You will get a response like the following:

```json
[
    {
        "productName": "Fresca",
        "productId": "prd_Fresca"
    }
]
```

Using the example above, the product ID is `Fresca`.
You must remove the `prd_` from the value.

### Group ID

```
akamai property-manager list-groups --format json
```

You will get a response like the following:

```json
[
    {
        "groupName": "engineering",
        "groupId": "grp_2222222",
        "parentGroupId": "grp_1111111",
        "contractIds": [
            "ctr_P-1234567"
        ]
    },
    {
        "groupName": "My-Company-P-1234567",
        "groupId": "grp_1111111",
        "contractIds": [
            "ctr_P-1234567"
        ]
    }
]
```

Using the example above, the available group IDs are `1111111`
and `2222222`. You must remove the `grp_` from the value.

> **Tip:**
>
> If you are unsure which group ID to use, select the one with a
> group name that matches your contract ID. that's the top-level
> group.

### Resource tier

```
akamai edgeworkers list-restiers --contractId <YOUR CONTRACT ID>
```

The response is more complex than the responses for the other CLI
commands. There is a numbered list of resource tiers, and under
each tier is a detailed description of the features of that tier.

In the example below, the resource id is **200**:

```
----------------------------------------------------------------------------
--- The following Resource Tiers available for the contract id P-1234567 ---
----------------------------------------------------------------------------
1. ResourceTier 200 - Dynamic Compute
Maximum CPU time during initialization: 60 ms
Maximum wall time during initialization: 200 ms
Maximum memory usage per event handler: 1.5 MB
Maximum CPU time per event handler: 10 ms
Maximum wall time per event handler: 4 s
...
```

## Create EdgeWorker ID

An [EdgeWorker ID](https://techdocs.akamai.com/edgeworkers/docs/create-an-edgeworker-id)
uniquely identifies your EdgeWorker. Even though you haven't
created the EdgeWorker yet, you can still create the ID and
associate the EdgeWorker with the ID later.

1. Determine a name for your EdgeWorker.

   > **Note:**
   >
   > You might want to use your domain name to make
   > it easy for other Akamai administrators to understand
   > the purpose of the EdgeWorker.
2. In the CLI, enter the following command:

   ```
   akamai edgeworkers create-id \
       <GROUP ID> <EDGE WORKER NAME> \
       --resourceTierId <RESOURCE TIER ID>
   ```

   > **Note:**
   >
   > Unlike in other places when you specify the group ID, in this
   > command you don't use the `--groupId` switch.
3. The output from the command will include a value **edgeWorkerId**.
   Note this value. You will need it when you create your Akamai
   property.

## Clone repository

Clone the following repository:

```
https://github.com/uniformdev/examples
```

> **Note:**
>
> This repository includes files that you will use to configure
> an EdgeWorker and property in Akamai. The files are located in
> the folder `examples/context-edge-akamai`.

## Write EdgeWorker code

Uniform provides the source code for a fully functional EdgeWorker
that executes Uniform personalization instructions.

> **Tip:**
>
> Review the [Akamai EdgeWorkers User Guide](https://techdocs.akamai.com/edgeworkers/docs/write-your-javascript-code) for a detailed tutorial on how to create an EdgeWorker.

1. Open a terminal window in the following folder in the root of the repository you cloned:

   ```
   examples/context-edge-akamai/worker
   ```
2. Enter the following command:

   ```
   npm install
   ```
3. Create a file `.env` with the following environment variables:

   | Variable name | Value |
   | --- | --- |
   | `AKAMAI_WORKER_ID` | The EdgeWorker ID you created in the previous section. |
   | `AKAMAI_WORKER_NETWORK` | The Akamai network you want to activate the EdgeWorker on. This must be one of the following:<br>- STAGING<br>- PRODUCTION |
   | `AKAMAI_WORKER_VERSION_INCREMENT` | The script automatically increments the EdgeWorker version number. This variable determines how the new version number is determined. This must be one of the following:<br>- `major` changes 1.0.0 to 2.0.0<br>- `minor` changes 1.0.0 to 1.1.0<br>- `patch` changes 1.0.0 to 1.0.1 |
   | `UNIFORM_PROJECT_ID` | The Uniform project whose manifest is retrieved. |
   | `UNIFORM_API_KEY` | The Uniform API key used to retrieve the manifest. |

## Deploy EdgeWorker

The repository you cloned contains a number of scripts that
automate the process of deploying an EdgeWorker.

> **Tip:**
>
> You don't have to use these scripts. You can deploy the
> EdgeWorker using whatever tools and approach you prefer.

1. Enter the following command:

   ```
   npm run worker:version:prepare
   ```

   > **Note:**
   >
   > This npm script:
   >
   > - Downloads the Uniform manifest.
   > - Increments the version number for the EdgeWorker.
   > - Builds the EdgeWorker.
2. Enter the following command:

   ```
   npm run worker:version:deploy
   ```

   > **Note:**
   >
   > This npm script:
   >
   > - Creates the TAR archive file.
   > - Uploads the file to Akamai using the Akamai CLI.
   > - Builds the EdgeWorker.
3. Enter the following command:

   ```
   npm run activate:version
   ```

   > **Note:**
   >
   > This npm script activates the new version of the EdgeWorker on the
   > specified Akamai network using the Akamai CLI.
4. The EdgeWorker can take 15 minutes or longer to activate.
   You can check the status of the activation process using
   the following command:

   ```
   npm run worker:status
   ```

   > **Note:**
   >
   > When the status for your version is `COMPLETE`, and it
   > is the version at the top of the list (or has the greatest
   > value for `activationId`), that means your version is active.

## Identify your origin

Akamai runs personalization by making a request to the
origin (like your web application) and executing the
personalization instructions associated with that page
(such as what you have configured using Uniform Context).

You have several options for where to deploy your web application.

> **Tip:**
>
> As long as Akamai can access your web application using HTTPS,
> you can host your app anywhere you like. The options described
> below are popular options.

### Akamai NetStorage

NetStorage is Akamai's globally distributed cloud storage solution.
You can use NetStorage as the origin and use Akamai as both a host
and a CDN.

### AWS S3 Buckets/Cloudfront

These instructions assume the following:

- Your web application is already deployed to an S3 bucket.
- Cloudfront is configured to provide public access to the
  contents of the S3 bucket using HTTPS.
- You have administrator access to the S3 bucket and Cloudfront.

1. In Cloudfront, open your distribution.
2. Copy the **Distribution domain name**.

   > **Note:**
   >
   > This is the URL you can use to access your site through
   > Cloudfront. To Akamai, this URL is the origin. The
   > hostname from the URL is the value you will need when
   > configuring Akamai.

### Azure Static Web Apps

Akamai has a partnership with Microsoft that enables high-speed
access to Azure resources from Akamai's network. As a result,
Akamai can use an Azure Static Web App as the origin without
the kind of network latency you might expect when multiple
clouds are involved.

## Configure certificate

To serve files to your visitors, Akamai needs a
certificate that matches your domain name. Akamai supports
multiples types of certificates.

### SAN certificates

A SAN certificate is a single certificate that can support multiple
domains. By adding your hostname as a subject alternative name (SAN)
on the certificate, Akamai can use this certificate with your domain.

1. Log into Akamai Control Center.
2. Navigate to **CDN > Certificates**.
3. In the row for your certificate, click **Actions > View and Edit Certificate**.
4. In the section **Enter Certificate Information**, click **Edit**.
5. In the field **SAN (optional)**, enter the hostname for your site.

   > **Note:**
   >
   > This should be the hostname visitors use to access your site.
6. Click **Update**.
7. Click **Submit**.
8. Click **Go**.
9. Click **Validate Domain Control**.

   > **Note:**
   >
   > Akamai gives you several options for how you can prove that
   > you have control of the domain. Follow the instructions you
   > prefer.
10. Click **Check status now**.

    > **Note:**
    >
    > You should see **Valid** next to the hostname in the list of domains.
11. Akamai submits a request for a certificate to be generated and
    deployed. This can take 15 minutes or longer. But eventually
    you will see your certificate has been deployed to production.

## Configure property

In Akamai, a property represents all the configuration that
Akamai uses to determine how to handle requests for your web
application. This includes things like when to use caching
and when to use the EdgeWorker.

### Determine CP code

When you create your Akamai property, you must specify a
[CP code](https://techdocs.akamai.com/cp-codes/docs/about-cp-codes).
This value allows you to classify the traffic Akamai handles,
which is useful for billing, reporting, logging and other purposes.

You can create a new CP code or use an existing one.

**Create new**

You can create a new CP code using the CLI.

1. Enter the following command:

   ```
   akamai property-manager create-cpcode \
       --contractId <YOUR CONTRACT ID> \
       --groupId <GROUP ID> \
       --productId <PRODUCT ID> \
       --cpcodeName <CP CODE NAME>
   ```

   > **Note:**
   >
   > This command creates the new CP code, but it displays no
   > output. You must run another command to get the CP code ID.
2. Enter the following command:

   ```
   akamai property-manager list-cpcodes \
       --contractId <YOUR CONTRACT ID> \
       --groupId <GROUP ID> 
   ```

   > **Note:**
   >
   > This is the same command from the previous section. You will
   > see your new CP code in the list. The CP code ID is follows
   > `cpc_`. You must remove the `cpc_` from the value.

**Use existing**

You can find the ID for an existing CP code using the CLI.

```
akamai property-manager list-cpcodes \
    --contractId <YOUR CONTRACT ID> \
    --groupId <GROUP ID> 
```

You will get a response like the following:

```
╒══════════════╤════════════════╤══════════════╤═══════════════════════╕
│"ID"          │"Name"          │"Product IDs" │"Creation Date"        │
╞══════════════╪════════════════╪══════════════╪═══════════════════════╡
│"cpc_1111111" │"my-domain-1"   │"prd_Fresca"  │"2021-08-25T15:37:40Z" │
├──────────────┼────────────────┼──────────────┼───────────────────────┤
│"cpc_2222222" │"my-domain-2"   │"prd_Fresca"  │"2021-08-26T03:12:55Z" │
├──────────────┼────────────────┼──────────────┼───────────────────────┤
│"cpc_3333333" │"my-domain-3"   │"prd_Fresca"  │"2021-09-03T02:42:40Z" │
└──────────────┴────────────────┴──────────────┴───────────────────────┘
```

Using the example above, there are 3 CP codes available in the
group. The CP code ID is follows `cpc_`. You must remove the
`cpc_` from the value.

> **Note:**
>
> If there are no CP codes available, or you can't find one that
> you want to use, you can [create a new CP code](#create-cp-code).
>
> If you are going to use one of the CP codes list above, note the
> ID and skip to [Configure property](#configure-property).

### Create property

This section covers how to create a new property in Akamai.

> **Info:**
>
> If you already have a property that you want to use, skip to [Import Property](#import-property).

Enter the following command:

```
akamai property-manager new-property \
    --contractId <YOUR CONTRACT ID> \
    --groupId <GROUP ID> \
    --productId <PRODUCT ID> \
    --property <PROPERTY NAME>
```

> **Note:**
>
> This will create a new property in Akamai and create a folder on
> your machine with property name. In this folder you will find a
> number of files that contain the various default settings that
> Akamai uses for new properties.

### Import property

> **Info:**
>
> If you created a new property in the previous section, skip to [Update Property](#update-property).

> **Warning:**
>
> You can use an existing Akamai property if you like, but you
> will be replacing most of the settings on the property. If
> the property is used for other purposes, you should review
> the changes described in this documentation carefully.

Enter the following command:

```
akamai property-manager import --property <PROPERTY NAME>
```

> **Note:**
>
> This creates a folder on your machine with property name. In this
> folder you will find a number of files that contain the various
> settings that are current configured on the property.

### Update property

Regardless of whether you created a new property or are using an
existing property, the property already has some configuration
settings. These settings need to be updated in order for the
EdgeWorker (which you still haven't created yet) to be used.

1. Enter the following command:

   ```
   akamai property-manager set-default --property <PROPERTY NAME>
   ```

   > **Note:**
   >
   > From now on, when you enter commands on the CLI, if you
   > don't specify a property explicitly, this property name
   > will be used.
2. Delete the files in the folder `config-snippets`.

   > **Note:**
   >
   > These files represent the current property settings.
   > You will replace these settings.
3. In the repository you cloned, copy the files from `examples/context-edge-akamai/cli/property/config-snippets`
   to the folder you deleted the files from in the earlier step.
4. Open the file `config-snippets/main.json`.
5. Replace the following placeholders with the settings you retrieved earlier:

   ```
   <ORIGIN HOSTNAME>
   ```

   ```
   <CP CODE NAME>
   ```

   ```
   <PRODUCT ID>
   ```

   ```
   <CP CODE NAME>
   ```
6. Open the file `config-snippets/EW_HTML_Pages.json`.
7. Replace the following placeholders with the settings you retrieved earlier:

   ```
   <EDGEWORKER ID>
   ```
8. Enter the following command:

   ```
   akamai property-manager save
   ```

   > **Note:**
   >
   > This will update the property in Akamai using the settings from your local files.

### Configure property hostname

> **Info:**
>
> In most cases this section only applies if you created a new
> property. An existing property will probably already have a
> hostname configured. If your property has a properly configured
> hostname, you can skip this section.

1. Log into Akamai Control Center.
2. Navigate to **CDN > Properties**.
3. Click your property.
4. Click on the latest version.
5. In the section **Property Hostnames**, tick the checkbox next to your hostname.

   ![](https://docs.uniform.app/images/integrations/cdn/akamai/personalization/setup/property-hostnames-before.png)
6. Click **Edit Selected**.
7. Click **Next**.

   ![](https://docs.uniform.app/images/integrations/cdn/akamai/personalization/setup/edit-hostnames.png)
8. Select your certificate.

   ![](https://docs.uniform.app/images/integrations/cdn/akamai/personalization/setup/select-certificate.png)
9. Click **Next**.

   ![](https://docs.uniform.app/images/integrations/cdn/akamai/personalization/setup/hostname-not-set-on-property.png)
10. Click the pencil icon next to **No Edge Hostname Selected**.
11. Enter a value for the field **Edge Hostname**:

    ![](https://docs.uniform.app/images/integrations/cdn/akamai/personalization/setup/associate-edge-hostname-to-property-hostname.png)

    > **Note:**
    >
    > This is the hostname that Akamai uses across its own network.
    > You will update DNS for your domain to map this internal hostname
    > to the public hostname that visitors use to access your site.
12. Click **Update**.

    ![](https://docs.uniform.app/images/integrations/cdn/akamai/personalization/setup/hostname-set-on-property.png)

    > **Note:**
    >
    > In your DNS, add a CNAME record for your property hostname
    > to associate the Akamai edge hostname.
13. Click **Submit**.

    ![](https://docs.uniform.app/images/integrations/cdn/akamai/personalization/setup/property-hostname-modified-success.png)
14. Click **Close**.
15. Click **Save**.

### Activate property

Before your changes are available on Akamai, you must activate
your property. You can activate on either the staging or
production environment by entering the appropriate command:

`Staging`

```bash
akamai property-manager activate -n staging
```

`Production`

```bash
akamai property-manager activate -n production
```

> **Note:**
>
> It can take 15 minutes or longer for the property to be activated.
> You can check the activation status using the following command:
>
> ```
> akamai property-manager cs
> ```
