OAC backup and recovery

This blog covers another aspect of Oracle Cloud, the REST API, as opposed to the command line options I’ve covered in previous posts.

Oracle Analytics Cloud provides a great way to visualise your data, but Oracle have not provided an automated method for backup and restore for this service. They take backups for their own purposes, but they’re not available for a customer in case something goes wrong, and the product puts the onus on a developer to remember to manually take a snapshot before deploying code, so that they can snap that back if they make a mistake.

However, as with most things OCI, there are API’s to help you do this (https://docs.oracle.com/en/cloud/paas/analytics-cloud/acapi/quick-start.html). The process for cloning an OAC environment is pretty much the same as restoring a backup, and is:

  • Create a snapshot of the instance, saving this to an OCI bucket
  • Register the snapshot with the OAC instance you want to restore it to (you don’t need to do this if you’re restoring from the same instance you backed up from)
  • Restore the snapshot

The great thing about this process is that you can run a nightly snapshot, and then if someone does something which messes up your system (like a developer deploys some problematic code), you can snap back to last night’s position. However, unlike the in-app snapshots this is an all or nothing restore, so you restore both the OAC code AND all the data. Therefore, if it’s just some code you need and you can’t lose data which has been loaded since the snapshot was taken, you could restore to a new instance and just extract what you need using the developer tools.

Authentication

OAC API’s are slight different from the standard OCI ones, in as much as you need to generate an authentication token first. You then include that token in the API invocation as part of the GET/PUT command.

Firstly, you need to associate the OAC instance with an IDCS/IAM application to allow you to authenticate against it. If one doesn’t exist, first create a confidential application in IDCS/IAM as per the documentation. Then in the “Resources” section add your OAC instance (it should find them automatically and provide a dropdown). It will generate a new “Scope” URL, which is different from the OAC URL you use to access the application. Copy this entire URL, as you will need it later. Remember to commit any changes to this application, and you need to activate it before you can use it.

The syntax to authenticate is as simple, but it generates a huge output which you need to capture in it’s entirety. It makes sense wrapping this in a function so that you can just invoke that whenever you need to authenticate:

function Authenticate()
{
echo `curl -s –request POST \
–url https://idcs-2015…1d8e57c09.identity.oraclecloud.com/oauth2/v1/token \
–header ‘authorization: Basic <base64 encoded clientID:ClientSecret>’ \
–header ‘content-type: application/x-www-form-urlencoded;charset=UTF-8’ \
-d “grant_type=password&username=<UN>&password=<PWD>&scope= https://${vURL}.analytics.ocp.oraclecloud.comurn:opc:resource:consumer::all” | awk -F\” ‘{print $4}’`
}
echo Getting token
TOKEN=$(Authenticate)

Note that the ClientID:ClientSecret is taken from the IDCS/IAM application which you authorised above and encoded as a base64 string, and ${URL} is the first bit of the URL in the Scope section in that app.

If you’ve done this right, it generates an output that looks like this (truncated for readability):

{“access_token”:”eyJ4NXQjUzI1NiI6Im9CZUJQSEtLcmozcExjTGNESTNCMnhEWXAwS25WUWZiNWFyR1FnNXR1dVkiLCJ4NXQiOiJyZVpJTmp0U1Q5NTE0SHZmcG95eFdVVzZhQm8iLCJraWQiOiJTSUdO… cKsxaplNvkOEZI_UlBlH2DQG4I9jpDhU9VXO510K6TcyfN5cxVKiRvm4nmeUSppP6RXUvsUuSg_6-LxMdOKkTxRqP3lu0Y2NtxWlh5jwQyenPRB10IIqsR4GJkvD6IrpQ64T64vGz2g”,”token_type”:”Bearer”,”expires_in”:100}

As you can see, it expires in 100 (seconds), and you need everything in here from “ey…2g” (in this case, i.e. the whole of the token string). I normally save this as a variable e.g. $TOKEN, so that I can use it later as demonstrated above.

Backup

Now you have the token you can invoke the API to take the snapshot. The API uses a JSON file to contain all the details, so you’ll need to build that first, and it will look like this:

{
    “type”: “CREATE”,
    “name”: “Snapshot-24-01-02_00-01”,
    “storage”: {
        “type”: “OCI_NATIVE”,
        “bucket”: “OAC_Backup”,
        “auth”: {
            “type”: “OSS_AUTH_OCI_USER_ID”,
            “ociRegion”: “uk-london-1”,
            “ociTenancyId”: “ocid1.tenancy.oc1..aaaaaaaabk4…n3rdkkiuavq”,
            “ociUserId”: “ocid1.user.oc1..aaaaaaaa5bfda4c…hbsxenqeoa”,
            “ociKeyFingerprint”: “63:8e:99:01:e8:7a:f5:6f:f0:b9:50:1c:e2:25:4f:86”,
            “ociPrivateKeyWrapped”: “LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQzlJNmU3Z1RUK0xTdDQKYTdUWENxTnlDZm9LRGRWRGNnZjZP…
2TnlTUlAwcjE1ZVRkeUdLbjVBbmlaVUlnRC9nRWsyWUJ1cDVOWGVhCjJCWEM4TGJwZkFJYWxEVjQ0dTk5eVFMeEYrK3NlTk9RMmRpcm9ZRjJLOUdqS056eUlKc0dMQjZ1R3Z1RW9rZkIKeDRuZ0lheEtVc1JaTVp3K1l3d2VtK2c9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K”
        }
    },
    “bar”: {
        “uri”: “file:///PRODAnalytics/Snapshot-24-01-02_00-01.bar”,
        “password”: “Password123”
    }
}

You will need to have created the bucket in advance, and it needs to be in the region specified in the auth section. All this auth section information is the same that you would use when invoking the OCI API, and it authorises the OAC application to access the bucket to write the snapshot (see previous blog about setting up your OCI environment

Once you have your JSON file ready, invoke the snapshot API:

curl -s -i –header “Authorization: Bearer $TOKEN” –header “Content-Type: application/json” –request POST https://$vURL.analytics.ocp.oraclecloud.com/api/20210901/snapshots -d @create_snapshot.json

This will return a work request ID, and start the process in the background. Depending on the size of your instance it can take an hour or more to complete, and there is no visible evidence it’s working until the snapshot file is written into the bucket right at the end. However, you can check the progress of the work request using:

curl -s -i –header “Authorization: Bearer $TOKEN” –request GET https://$vURL.analytics.ocp.oraclecloud.com/api/20210901/workRequests/<WorkRequestID&gt;

This uses the work request id returned by the snapshot API and shows whether it’s in progress, completed or failed. If it fails you can use the debug flag to get more information (although it’s not always helpful information).

If this is a scheduled job, it’s also work performing some housekeeping on your bucket, by deleting older snapshot and only keeping a manageable number (bearing in mind that storage is cheap). The other thing you might want to think about is that if you have a DR in a second region, you might want to enable cross region replication of the snapshots, so that you can build your DR OAC instance should it be needed.

Registering Snapshot

Before restoring a snapshot, the OAC instance needs to know where it is. If you created the snapshot in this instance (i.e. doing a restore to source), then you don’t need this step, but if you’re cloning (e.g. PROD > UAT), then you will.

Registering the snapshot is easy, you just need a JSON file which holds the location of the snapshot:

{
    “type”: “REGISTER”,
    “name”: “Snapshot-23-12-09_14-07”,
    “storage”: {
        “type”: “OCI_NATIVE”,
        “bucket”: “OAC_Backup”,
        “auth”: {
            “type”: “OSS_AUTH_OCI_USER_ID”,
            “ociRegion”: “uk-london-1”,
            “ociTenancyId”: “ocid1.tenancy.oc1..aaaaaaaabk4…n3rdkkiuavq”,
            “ociUserId”: “ocid1.user.oc1..aaaaaaaa5bfda4c…hbsxenqeoa”,
            “ociKeyFingerprint”: “63:8e:99:01:e8:7a:f5:6f:f0:b9:50:1c:e2:25:4f:86”,
            “ociPrivateKeyWrapped”: “LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQzlJNmU3Z1RUK0xTdDQKYTdUWENxTnlDZm9LRGRWRGNnZjZP…
2TnlTUlAwcjE1ZVRkeUdLbjVBbmlaVUlnRC9nRWsyWUJ1cDVOWGVhCjJCWEM4TGJwZkFJYWxEVjQ0dTk5eVFMeEYrK3NlTk9RMmRpcm9ZRjJLOUdqS056eUlKc0dMQjZ1R3Z1RW9rZkIKeDRuZ0lheEtVc1JaTVp3K1l3d2VtK2c9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K”
        }
    },
    “bar”: {
        “uri”: “file:///PRODAnalytics/Snapshot-23-12-09_14-07.bar”,
        “password”: “Password123”
    }
}

This is almost identical to the create snapshot one, apart from the “type” at the top of the file, and then you invoke the API:

curl -s -i –header “Authorization: Bearer $TOKEN” –header “Content-Type: application/json” –request POST https://$vDESTURL.analytics.ocp.oraclecloud.com/api/20210901/snapshots -d @register_snapshot.json

Again, this will return a work request ID, but it’s pretty quick and only takes a few seconds to complete.

Once a snapshot is registered with OAC, then you can use it for a restore noting that the restore will overwrite EVERYTHING in the OAC instance with what is in the snapshot.

Restoring a Snapshot

To restore a snapshot, you need to use the snapshotID from OAC. All registered snapshots have a unique ID in each OAC instance. An API returns all the snapshots and their ID’s, you just need to get the one which corresponds to the snapshot you want to restore:

curl -s -i –header “Authorization: Bearer $TOKEN” –request GET https://$vDESTURL.analytics.ocp.oraclecloud.com/api/20210901/snapshots

And then use create a simple JSON file using this id:

{
   “snapshot”: {
      “id” : “f82bc74b-…-202a3f54e7b6”,
      “password” : “Password123”
   }
}

And then you invoke the API:

curl -s -i –header “Authorization: Bearer $TOKEN” –header “Content-Type: application/json” –request POST https://$vDESTURL.analytics.ocp.oraclecloud.com/api/20210901/system/actions/restoreSnapshot -d @restore_snapshot.json

Again this returns a work request id, but that only covers the loading of the snapshot. A restore is 2 phase, the first loads the snapshot into OAC (at which point the work request completes), and the second stage is to populate that data in OAC. This second phase can take an hour or more, and there is no visual indication of it’s progress or when it completes.

Summary

In summary, while OAC doesn’t have an automated backup capability, it’s easy to script the process using the available API’s and build a parameter based set of scripts to allow you to backup, restore or clone OAC instance to support your estate.

This isn’t the end of the story, but it’s a great demonstration on how the API’s and command line features in OCI can help automate your daily tasks

Leave a comment