> ## Documentation Index
> Fetch the complete documentation index at: https://developer.upsun.com/llms.txt
> Use this file to discover all available pages before exploring further.

# How to enable custom maintenance page in Fastly

> Configure GitLab CI/CD to deploy to Upsun from private air-gapped GitLab instances using push-based workflows and API automation.


export const PostMeta = ({data = {}}) => {
  const {author, date, image} = data;
  const authors = Array.isArray(author) ? author : author ? [author] : [];
  const resolveAuthor = slug => {
    const entry = AUTHOR_MAP[slug] || ({});
    const name = entry.name || slug;
    const github = entry.github || null;
    const linkedin = entry.linkedin || null;
    const url = github ? `https://github.com/${github}` : linkedin || null;
    const avatarUrl = github ? `https://github.com/${github}.png?size=64` : null;
    return {
      name,
      url,
      avatarUrl
    };
  };
  const formattedDate = date ? new Date(date).toLocaleDateString('en-US', {
    year: 'numeric',
    month: 'long',
    day: 'numeric'
  }) : null;
  if (!image && authors.length === 0 && !formattedDate) return null;
  const AUTHOR_MAP = {
    "aaron-collier": {
      "name": "Aaron Collier"
    },
    "aaron-dudenhofer": {
      "name": "Aaron Dudenhofer"
    },
    "aaron-porter": {
      "name": "Aaron Porter"
    },
    "adriaan-odendaal": {
      "name": "Adriaan Odendaal"
    },
    "ajmal": {
      "name": "Ajmal Siddiqui"
    },
    "akalipetis": {
      "name": "Antonis Kalipetis"
    },
    "alexander-varwijk": {
      "name": "Alexander Varwijk"
    },
    "alicia-bevilacqua": {
      "name": "Alicia Bevilacqua"
    },
    "amelie-deguerry": {
      "name": "Amelie Deguerry"
    },
    "anacidre": {
      "name": "Ana Cidre",
      "linkedin": "https://www.linkedin.com/in/ana-cidre"
    },
    "andoni": {
      "name": "Andoni Auzmendi"
    },
    "andrei-taranu": {
      "name": "Andrei (Alex) Taranu",
      "linkedin": "https://www.linkedin.com/in/andrei-alex-taranu/"
    },
    "andrew-baxter": {
      "name": "Andrew Baxter"
    },
    "andrew-melck": {
      "name": "Andrew Melck"
    },
    "antoine-crochet-damais": {
      "name": "Antoine Crochet Damais"
    },
    "augustin-delaporte": {
      "name": "Augustin Delaporte",
      "linkedin": "https://www.linkedin.com/in/augustindelaporte/"
    },
    "branislav-bujisic": {
      "name": "Branislav Bujisic"
    },
    "carl-smith": {
      "name": "Carl Smith"
    },
    "caroline-leroy": {
      "name": "Caroline Leroy"
    },
    "cati-mayer": {
      "name": "Cati Mayer"
    },
    "catplat": {
      "name": "C Trinkwon"
    },
    "ceelolulu": {
      "name": "Celeste van der Watt"
    },
    "chadwcarlson": {
      "name": "Chad Carlson",
      "github": "chadwcarlson",
      "linkedin": "https://www.linkedin.com/in/chadwcarlson"
    },
    "chris-ward": {
      "name": "Chris Ward"
    },
    "chris-yates": {
      "name": "Chris Yates"
    },
    "christian-sieber": {
      "name": "Christian Sieber"
    },
    "christopher-lockheardt": {
      "name": "Christopher Lockheardt"
    },
    "christopher-skene": {
      "name": "Christopher Skene"
    },
    "chuck-morgan": {
      "name": "Chuck Morgan"
    },
    "corey-dockendorf": {
      "name": "Corey Dockendorf"
    },
    "crell": {
      "name": "Crell"
    },
    "damz": {
      "name": "Damz"
    },
    "dan-morrison": {
      "name": "Dan Morrison"
    },
    "davidbonachera": {
      "name": "David Bonachera",
      "github": "davidbonachera",
      "linkedin": "https://www.linkedin.com/in/davidbonachera"
    },
    "dereliahmet1": {
      "name": "Ahmet Faruk Dereli"
    },
    "devicezero": {
      "name": "Jonas Kröger",
      "github": "devicezero",
      "linkedin": "https://www.linkedin.com/in/jonaskroeger/"
    },
    "doug-goldberg": {
      "name": "Doug Goldberg"
    },
    "duncan-naves": {
      "name": "Duncan Naves",
      "github": "duncannaves",
      "linkedin": "https://www.linkedin.com/in/duncan-naves-a94423aa"
    },
    "erika-bustamante": {
      "name": "Erika Bustamante"
    },
    "fabpot": {
      "name": "Fabien Potencier"
    },
    "flovntp": {
      "name": "Florent Huck",
      "github": "flovntp",
      "linkedin": "https://www.linkedin.com/in/florenthuck"
    },
    "fred-plais": {
      "name": "Fred Plais"
    },
    "gauthier-garnier": {
      "name": "Gauthier Garnier"
    },
    "gilzow": {
      "name": "Paul Gilzow"
    },
    "gmoigneu": {
      "name": "Guillaume Moigneu",
      "github": "gmoigneu",
      "linkedin": "https://www.linkedin.com/in/guillaumemoigneu/"
    },
    "gregqualls": {
      "name": "Greg Qualls"
    },
    "guguss": {
      "name": "Augustin Delaporte"
    },
    "haylee-millar": {
      "name": "Haylee Millar"
    },
    "ivana-kotur": {
      "name": "Ivana Kotur"
    },
    "jackrabbithanna": {
      "name": "Mark Hanna"
    },
    "jared-wright": {
      "name": "Jared Wright",
      "github": "jww-sh",
      "linkedin": "https://www.linkedin.com/in/jaredwaynewright"
    },
    "jessica-orozco": {
      "name": "Jessica Orozco"
    },
    "joey-stanford": {
      "name": "Joey Stanford"
    },
    "john-grubb": {
      "name": "John Grubb"
    },
    "jonas-kruger": {
      "name": "Jonas Kruger"
    },
    "kathryn-frazer": {
      "name": "Kathryn Frazer"
    },
    "kemiojo": {
      "name": "Kemi Elizabeth Ojogbede"
    },
    "kieronsambrook-smith": {
      "name": "Kieronsambrook Smith"
    },
    "laurent-arnoud": {
      "name": "Laurent Arnoud"
    },
    "letoya-boyne": {
      "name": "Letoya Boyne"
    },
    "lolautruche": {
      "name": "Jérôme Vieilledent"
    },
    "lyly-lepinay": {
      "name": "Lyly Lepinay"
    },
    "manauwar-alam": {
      "name": "Manauwar Alam"
    },
    "marc-antoine-porri": {
      "name": "Marc Antoine Porri"
    },
    "maria-antinkaapo": {
      "name": "Maria Antinkaapo"
    },
    "maria-de-anton": {
      "name": "Maria De Anton"
    },
    "mark-dorison": {
      "name": "Mark Dorison"
    },
    "markus-hausammann": {
      "name": "Markus Hausammann"
    },
    "mary-thomas": {
      "name": "Mary Thomas"
    },
    "mathias-bolt-lesniak": {
      "name": "Mathias Bolt Lesniak"
    },
    "mathieu-strauch": {
      "name": "Mathieu Strauch"
    },
    "matthias-van-woensel": {
      "name": "Matthias Van Woensel",
      "linkedin": "https://www.linkedin.com/in/matthias-van-woensel-267a069"
    },
    "michael-sharp": {
      "name": "Michael Sharp"
    },
    "mupsi": {
      "name": "Marine Gandy"
    },
    "natalie-harper": {
      "name": "Natalie Harper"
    },
    "ngommenginger": {
      "name": "Nicolas Gommenginger",
      "linkedin": "https://www.linkedin.com/in/nicolas-gommenginger"
    },
    "nicholas-bennison": {
      "name": "Nicholas Bennison"
    },
    "nicholas-vahalik": {
      "name": "Nicholas Vahalik"
    },
    "nick-hardiman": {
      "name": "Nick Hardiman"
    },
    "nickanderegg": {
      "name": "Nickanderegg"
    },
    "nicolas-grekas": {
      "name": "Nicolas Grekas",
      "github": "nicolas-grekas",
      "linkedin": "https://www.linkedin.com/in/nicolasgrekas/"
    },
    "niti-malwade": {
      "name": "Niti Malwade"
    },
    "opensocialteam": {
      "name": "Opensocialteam"
    },
    "ori-pekelman": {
      "name": "Ori Pekelman"
    },
    "otavio-santana": {
      "name": "Otavio Santana"
    },
    "palwandi": {
      "name": "Pawan Alwandi",
      "github": "pawpy",
      "linkedin": "https://www.linkedin.com/in/pawanalwandi"
    },
    "patrick-boest": {
      "name": "Patrick Boest"
    },
    "patrick-dawkins": {
      "name": "Patrick Dawkins",
      "github": "pjcdawkins",
      "linkedin": "https://www.linkedin.com/in/patrickdawkins"
    },
    "patrick-klima": {
      "name": "Patrick Klima"
    },
    "pjcdawkins": {
      "name": "Pjcdawkins"
    },
    "prineet-kaurbhurji": {
      "name": "Prineet Kaurbhurji"
    },
    "quentin-sinig": {
      "name": "Quentin Sinig"
    },
    "ralt": {
      "name": "Florian Margaine",
      "github": "ralt",
      "linkedin": "https://www.linkedin.com/in/florian-margaine-43971136"
    },
    "ramanathanramakrishnamurthy": {
      "name": "Ramanathanramakrishnamurthy"
    },
    "remi-lejeune": {
      "name": "Rémi Lejeune"
    },
    "ribel": {
      "name": "Taras Kruts"
    },
    "robert-douglass": {
      "name": "Robert Douglass"
    },
    "rudy-weber": {
      "name": "Rudy Weber"
    },
    "ryan-hicks": {
      "name": "Ryan Hicks"
    },
    "sabri-helal": {
      "name": "Sabri Helal"
    },
    "savannah-bergeron": {
      "name": "Savannah Bergeron"
    },
    "shannon-vettes": {
      "name": "Shannon Vettes"
    },
    "shawn-ogasawara": {
      "name": "Shawn Ogasawara",
      "linkedin": "https://www.linkedin.com/in/shawn-ogasawara-83a9a0/"
    },
    "shawna-spoor": {
      "name": "Shawna Spoor"
    },
    "shedrack-akintayo": {
      "name": "Shedrack Akintayo"
    },
    "simon-ruggier": {
      "name": "Simon Ruggier"
    },
    "sophie-van-der-kindere": {
      "name": "Sophie Van Der Kindere"
    },
    "stefanos-thampis": {
      "name": "Stefanos Thampis"
    },
    "stephen-weinberg": {
      "name": "Stephen Weinberg"
    },
    "sukhman-virk": {
      "name": "Sukhman Virk"
    },
    "sumaira-nazir": {
      "name": "Sumaira Nazir"
    },
    "sumer": {
      "name": "Sümer Cip"
    },
    "syed-raza": {
      "name": "Syed Raza"
    },
    "tamara-bacchia": {
      "name": "Tamara Bacchia"
    },
    "tara-arnold": {
      "name": "Tara Arnold"
    },
    "theosakamg": {
      "name": "Mickael Gaillard",
      "github": "theosakamg"
    },
    "thomasdiluccio": {
      "name": "Thomas di Luccio"
    },
    "tim-anderson": {
      "name": "Tim Anderson"
    },
    "tom-helmer-hansen": {
      "name": "Tom Helmer Hansen"
    },
    "tylermills": {
      "name": "Tyler Mills"
    },
    "upsun": {
      "name": "Upsun"
    },
    "veronika-tolkachova": {
      "name": "Veronika Tolkachova",
      "linkedin": "https://www.linkedin.com/in/veronika-tolkachova-169167a2"
    },
    "vince-parker": {
      "name": "Vince Parker"
    },
    "vinnie-russo": {
      "name": "Vincenzo Russo"
    },
    "vrobert78": {
      "name": "Vincent Robert",
      "github": "vrobert78",
      "linkedin": "https://www.linkedin.com/in/vincent-robert-498a883"
    },
    "yuriy-babenko": {
      "name": "Yuriy Babenko"
    },
    "yuriy-gerasimov": {
      "name": "Yuriy Gerasimov"
    }
  };
  return <div className="post-meta">
      {(authors.length > 0 || formattedDate) && <div className="post-meta-info">
          {authors.length > 0 && <div className="post-meta-authors">
              {authors.map(slug => {
    const {name, url, avatarUrl} = resolveAuthor(slug);
    const inner = <>
                    {avatarUrl && <img src={avatarUrl} alt={name} className="post-meta-avatar" />}
                    <span className="post-meta-author-name">{name}</span>
                  </>;
    return url ? <a key={slug} href={url} target="_blank" rel="noopener noreferrer" className="post-meta-author">
                    {inner}
                  </a> : <span key={slug} className="post-meta-author">{inner}</span>;
  })}
            </div>}
          {authors.length > 0 && formattedDate && <span className="post-meta-separator" aria-hidden="true">·</span>}
          {formattedDate && <span className="post-meta-date">{formattedDate}</span>}
        </div>}
      {image && <img src={image} alt="" className="post-meta-image" aria-hidden="true" />}
    </div>;
};

<PostMeta data={{ author: ["andoni"], date: "2025-08-25T02:00:00+00:00", image: "/images/posts/hands-on/fastly-maintenance/manualjob.webp" }} />

This step-by-step guide outlines how to create and maintain a custom maintenance page
in [Fastly](https://www.fastly.com/), and how to enable and disable it either manually
or during [Upsun](https://www.upsun.com) deployments.

We need to add a dictionary in Fastly which we will use as an on / off switch to enable and disable the maintenance page
as well as the content of maintenance page.

We are going to use official Fastly CLI tool which you can download
from [Fastly CLI](https://www.fastly.com/documentation/reference/tools/cli/). You will need a Fastly API token with
permissions to perform changes.

We are going to use these two environment variables:

* `FASTLY_SERVICE_ID`: Contains our Fastly service ID.
* `FASTLY_API_TOKEN`: Contains our Fastly API token.

## Create Fastly configuration

<Note>
  Please define these two local environment variables before starting, using the following command lines:

  ```bash {filename="Terminal"} theme={null}
  export FASTLY_SERVICE_ID=<YOUR-FASTLY-SERVICE-ID>
  export FASTLY_API_TOKEN=<YOUR-FASTLY-API-TOKEN>
  ```
</Note>

Let’s start with cloning the active configuration version:

```bash {filename="Terminal"} theme={null}
fastly service-version clone -t $FASTLY_API_TOKEN -s $FASTLY_SERVICE_ID --version active

SUCCESS: Cloned service $FASTLY_SERVICE_ID version X to version Y
```

From now on, we will work on our cloned version by referring to it with `--version latest`.

Let’s create a dictionary which will be used as on & off switch to enable and disable the maintenance page:

```bash {filename="Terminal"} theme={null}
fastly dictionary create -t $FASTLY_API_TOKEN -s $FASTLY_SERVICE_ID --version latest --name maintenance

SUCCESS: Created dictionary maintenance (id zHpEamIhKjDt7B28bSyRw4, service $FASTLY_SERVICE_ID, version Y)
```

Make a note of the given dictionary ID and let’s store it on a variable:

```bash {filename="Terminal"} theme={null}
export FASTLY_MAINTENANCE_DICT=zHpEamIhKjDt7B28bSyRw4
```

Let’s add an entry in the new dictionary which will be the actual on/off switch:

```bash {filename="Terminal"} theme={null}
fastly dictionary-entry create -t $FASTLY_API_TOKEN -s $FASTLY_SERVICE_ID --dictionary-id $FASTLY_MAINTENANCE_DICT --key maintenance --value=false

SUCCESS: Created dictionary item maintenance (service $FASTLY_SERVICE_ID, dictionary $FASTLY_MAINTENANCE_DICT)
```

We need a VCL to check for the key in the dictionary to know whether to return the maintenance page or not.
Save the following VCL snippet in `maintenance_recv.vcl`:

```vcl {filename="maintenance_recv.vcl"} theme={null}
if (table.lookup(maintenance, "maintenance", "false") == "true") {
   error 653 "maintenance";
}
```

Let’s upload this `maintenance_recv.vcl` VCL to Fastly:

```bash {filename="Terminal"} theme={null}
fastly vcl snippet create -t $FASTLY_API_TOKEN -s $FASTLY_SERVICE_ID --version latest --name maintenance_recv --type recv --priority 50 --content maintenance_recv.vcl

SUCCESS: Created VCL snippet 'maintenance_recv' (service: $FASTLY_SERVICE_ID, version: Y, dynamic: false, snippet id: KdpZbSaxdj4bqP3kwKHt41, type: recv, priority: 50)
```

Save the maintenance page inside a VCL called `maintenance_error.vcl` like below. Note maintenance page goes within HTML
tags:

```vcl {filename="maintenance_error.vcl"} theme={null}
if (obj.status == 653) {
  set obj.status = 200;
  set obj.response = "OK";
  synthetic {"
    <html>
      <head>
      </head>
      <body>
        <h1>This site is under maintenance</h1>
      </body>
    </html>
  "};
  return(deliver);
}
```

Let’s create the `maintenance_error.vcl` VCL with the maintenance page in Fastly:

```bash {filename="Terminal"} theme={null}
fastly vcl snippet create -t $FASTLY_API_TOKEN -s $FASTLY_SERVICE_ID --version latest --name maintenance_error --type error --content maintenance_error.vcl

SUCCESS: Created VCL snippet 'maintenance_error' (service: $FASTLY_SERVICE_ID, version: Y, dynamic: false, snippet id: 3BcskRs1Z2Fo9GqidDwDf0, type: error, priority: 100)
```

We can now activate our changes:

```bash {filename="Terminal"} theme={null}
fastly service-version activate -t $FASTLY_API_TOKEN -s $FASTLY_SERVICE_ID --version latest

SUCCESS: Activated service $FASTLY_SERVICE_ID version Y
```

## Testing

From now on, we can enable and disable our maintenance page in Fastly on demand by altering the key in the dictionary.
We can enable it by setting the key value to true:

```bash {filename="Terminal"} theme={null}
fastly dictionary-entry update -t $FASTLY_API_TOKEN -s $FASTLY_SERVICE_ID --dictionary-id $FASTLY_MAINTENANCE_DICT --key maintenance --value=true

SUCCESS: Updated dictionary item (service $FASTLY_SERVICE_ID)

Dictionary ID: $FASTLY_MAINTENANCE_DICT
Item Key: maintenance
Item Value: true
```

Bear in mind it will take several seconds for Fastly to propagate the key value among their edge servers. You can browse
to our website and check how the maintenance page is being served by Fastly.

We can disable the maintenance page by altering the key to false in the dictionary:

```bash {filename="Terminal"} theme={null}
fastly dictionary-entry update -t $FASTLY_API_TOKEN -s $FASTLY_SERVICE_ID --dictionary-id $FASTLY_MAINTENANCE_DICT --key maintenance --value=false

SUCCESS: Updated dictionary item (service $FASTLY_SERVICE_ID)

Dictionary ID: $FASTLY_MAINTENANCE_DICT
Item Key: maintenance
Item Value: false
Maintenance page will disappear and the website will be live again.
```

## Enable maintenance during deployment

If we want to display the maintenance page during deployment, we can do so by adding the variables and enable followed
disable the page in the deployment hooks.

We can add the variables to our project like below:

```bash {filename="Terminal"} theme={null}
upsun variable:create -p <PROJECT_ID> -e <PROD_ENVIRONMENT> --level environment --inheritable false --visible-build true --prefix env --no-wait --name FASTLY_SERVICE_ID --value $FASTLY_SERVICE_ID
upsun variable:create -p <PROJECT_ID> -e <PROD_ENVIRONMENT> --level environment --inheritable false --visible-build true --prefix env --no-wait --sensitive true --name FASTLY_API_TOKEN --value $ FASTLY_API_TOKEN
upsun variable:create -p <PROJECT_ID> -e <PROD_ENVIRONMENT> --level environment --inheritable false --visible-build true --prefix env --no-wait --name FASTLY_MAINTENANCE_DICT --value $FASTLY_MAINTENANCE_DICT
```

<Note>
  **Note:** Replace `<PROJECT_ID>` and `<PROD_ENVIRONMENT>` with your Upsun project info.

  Example:

  * `<PROJECT_ID>` = `azertyuiop1234`
  * `<PROD_ENVIRONMENT>` = `main`
</Note>

We add enable and disable maintenance commands at the end of [build and deploy hooks](https://docs.upsun.com/create-apps/app-reference/single-runtime-image.html#hooks) respectively:

```yaml {filename=".upsun/config.yaml",hl_lines=["7-8", "13"],linenostart=1} theme={null}
applications:
  app:
    hooks:
      build: |
        set -e
        #...
        brew install fastly/tap/fastly
        fastly dictionary-entry update -t $FASTLY_API_TOKEN -s $FASTLY_SERVICE_ID --dictionary-id $FASTLY_MAINTENANCE_DICT --key maintenance --value=true
    
      deploy: |
        set -e
        #...
        fastly dictionary-entry update -t $FASTLY_API_TOKEN -s $FASTLY_SERVICE_ID --dictionary-id $FASTLY_MAINTENANCE_DICT --key maintenance --value=false
```

<Note>
  **Please note**:

  The above commands can also be applied to [Platform.sh](https://platform.sh) projects by replacing `upsun` CLI by `platform` CLI in the call.
</Note>

## Updating maintenance page

What if we want to update the maintenance page in the future?

For doing so, we update `maintenance_error.vcl` with our updated maintenance page within HTML tags. We create a new
version, upload it and activate in Fastly:

```bash {filename="Terminal"} theme={null}
fastly service-version clone -t $FASTLY_API_TOKEN -s $FASTLY_SERVICE_ID --version active
fastly vcl snippet update -t $FASTLY_API_TOKEN -s $FASTLY_SERVICE_ID --version latest --name maintenance_error --type error --content maintenance_error.vcl
fastly service-version activate -t $FASTLY_API_TOKEN -s $FASTLY_SERVICE_ID --version latest
```

## Adding allowed IPs while maintenance enabled

Let's say that we want to allow some IP ranges to allow to reach the website when the maintenance page is enabled. This is useful when we need to perform tests and other tasks during mainteance window. In order to accomplish this, we will need to create an ACL with the excluded IP ranges and exclude this list when maintenance is enabled.

Create a new version to make changes:

```bash {filename="Terminal"} theme={null}
fastly service-version clone -t $FASTLY_API_TOKEN -s $FASTLY_SERVICE_ID --version active
```

Create the ACL:

```bash {filename="Terminal"} theme={null}
$ fastly acl create -t $FASTLY_API_TOKEN -s $FASTLY_SERVICE_ID --version latest --name maintenance_ips
SUCCESS: Created ACL 'maintenance_ips' (id: yQImb1Ab1cIWaqBV42VWC2, service: $FASTLY_SERVICE_ID, version: 41)
```

Make a note of the given ACL ID and let’s store it on a variable:

```bash {filename="Terminal"} theme={null}
export FASTLY_MAINTENANCE_ACL=yQImb1Ab1cIWaqBV42VWC2
```

Let's add an IP address and a network to it (these IP addresses are examples and add IP ranges you own instead):

```bash {filename="Terminal"} theme={null}
fastly acl-entry create -t $FASTLY_API_TOKEN -s $FASTLY_SERVICE_ID --acl-id $FASTLY_MAINTENANCE_ACL --ip 101.101.101.101 --comment VPN_IP
fastly acl-entry create -t $FASTLY_API_TOKEN -s $FASTLY_SERVICE_ID --acl-id $FASTLY_MAINTENANCE_ACL --ip 101.201.201.0 --subnet 24 --comment Office
```

Edit `maintenance_recv.vcl` VCL snippet like below:

```vcl {filename="maintenance_recv.vcl"} theme={null}
if (table.lookup(maintenance, "maintenance", "false") == "true") {
   if (!req.http.Fastly-Client-IP ~ maintenance_ips) {
      error 653 "maintenance";
   }
}
```

And upload it to Fastly:

```bash {filename="Terminal"} theme={null}
fastly vcl snippet update -t $FASTLY_API_TOKEN -s $FASTLY_SERVICE_ID --version latest --name maintenance_recv --type recv --content maintenance_recv.vcl
```

Active the new version to activate the changes:

```bash {filename="Terminal"} theme={null}
fastly service-version activate -t $FASTLY_API_TOKEN -s $FASTLY_SERVICE_ID --version latest
```

We will be able to browse to the website from IPs listed in the `maintenance_ips` ACL even after enabling the maintenance page.

### Updating maintenance ACL IPs

We can add additional IPs to the maintenance ACL in the future without cloning the version. Just add them like this:

```bash {filename="Terminal"} theme={null}
fastly acl-entry create -t $FASTLY_API_TOKEN -s $FASTLY_SERVICE_ID --acl-id $FASTLY_MAINTENANCE_ACL --ip 55.55.55.55 --comment another_location
```

## Summary

With your Fastly maintenance page configured, you can now automatically enable maintenance page in Fastly during
deployments to Upsun. This setup provides:

* [Create Fastly configuration to enable custom maintenance page](#create-fastly-configuration)
* [Automatically enable maintenance page during deployments](#enable-maintenance-during-deployment)
* [Maintain custom maintenance page](#updating-maintenance-page)

For more advanced configurations, explore [Upsun's API documentation](https://docs.upsun.com/api/) to customize
environment settings, manage resources, and integrate with your existing DevOps tools.

***

[Create your Upsun account](https://upsun.com) today.
