Search…
AWS RDS snapshots using TVK hooks
How to backup/restore AWS RDS using hooks

1. Backup/Restore of Application with external DB (AWS RDS)

Objective - Support backup of external databases (AWS RDS, Google Cloud SQL to begin with)
Summary - This use case is to support the backup/restore of external cloud database configured with applications running on k8s cluster.
Pre-requisite -
  1. 1.
    Applications on the k8s cluster are configured to use Cloud Database managed service
  2. 2.
    All the required details for the cloud database connectivity are available such as database instance name, credentials
Assumptions -
  1. 1.
    Applications on the k8s cluster are configured with specific Database instance
  2. 2.
    User provides all the information required for Database backup (on-demand)
  3. 3.
    All the requirements for database backup are provided such as user access for backup, zones/regions allowed for backups, allotted space, Database instance name/identifier, location etc.
  4. 4.
    There is no additional mapping required post restore of the Database i.e. application should be able to connect to the Database using same credentials, instance name etc.
Workflow -
  1. 1.
    User provides inputs for a. List of applications configured to use external database b. The Database instance name/identifier c. User credentials for backup d. Zone/region allowed for backup e. Location for backup
  2. 2.
    A “jump” pod is needed with Cloud and kubectl libraries which are required to connect to remote Cloud databases for backup/restore. This “jump” pod is created in the same namespace where the application to be backed up is running.
  3. 3.
    As per the policy created for the application backup, the application backup is triggered.
  4. 4.
    Along with application backup, an on-demand backup/snapshot will be created for the external database using API calls. This will be achieved by Backup hooks.
  5. 5.
    Snapshot identified of the Cloud Database is constructed using BackupPlan and Backup names. This will be a unique identifier and the user will always have access to these details. Also, this will help maintain a link between the TVK backup and the Database snapshot.
  6. 6.
    For restore, user provides inputs for a. BackupPlan and Backup name for restore b. The Database instance name for restore c. User credentials for restore d. Zone/region allowed for restore e. VPC Security Group
  7. 7.
    At the time of restore of the application, the backup/snapshot will be restored using the name/identifier. This will be achieved by Restore hooks.
  8. 8.
    Post restore, the application connectivity with the external database will be established based on the database instance name/identifier and the user provided credentials.
Example with steps Followed -
In AWS RDS, create a database instance using MySQL Engine. A free tier instance can be selected. Create a new VPC Security Group. Update inbound and outbound rules to allow access.
Once the instance is created, note down the Username, Password and Endpoint which are needed to connect to the DB instance. Also, create a database for wordpress application in the Database instance.
Deploy wordpress application with AWS RDS database configured (replace host url, admin password, DB name)
1
$ helm install wordpress bitnami/wordpress -n triliowp \
2
> --set mariadb.enabled=false \
3
> --set externalDatabase.host=<ext-db-host-url>.rds.amazonaws.com \
4
> --set externalDatabase.user=admin \
5
> --set externalDatabase.password=<admin_password> \
6
> --set externalDatabase.database=<db name> \
7
> --set externalDatabase.port=3306
Copied!
Check the AWS RDS Database is the wordpress tables are populated.
1
$ mysql -h <ext-db-host-url>.rds.amazonaws.com -P 3306 -u admin -p<admin_password>
2
mysql: [Warning] Using a password on the command line interface can be insecure.
3
Welcome to the MySQL monitor. Commands end with ; or \g.
4
Your MySQL connection id is 55
5
Server version: 8.0.23 Source distribution
6
7
Copyright (c) 2000, 2021, Oracle and/or its affiliates.
8
9
Oracle is a registered trademark of Oracle Corporation and/or its
10
affiliates. Other names may be trademarks of their respective
11
owners.
12
13
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
14
15
mysql> show databases;
16
+--------------------+
17
| Database |
18
+--------------------+
19
| information_schema |
20
| mysql |
21
| performance_schema |
22
| sys |
23
| trilio |
24
+--------------------+
25
5 rows in set (0.00 sec)
26
27
mysql> use trilio;
28
Reading table information for completion of table and column names
29
You can turn off this feature to get a quicker startup with -A
30
31
Database changed
32
mysql>
33
mysql> show tables;
34
+-----------------------+
35
| Tables_in_triliowp |
36
+-----------------------+
37
| wp_commentmeta |
38
| wp_comments |
39
| wp_links |
40
| wp_options |
41
| wp_postmeta |
42
| wp_posts |
43
| wp_term_relationships |
44
| wp_term_taxonomy |
45
| wp_termmeta |
46
| wp_terms |
47
| wp_usermeta |
48
| wp_users |
49
+-----------------------+
50
12 rows in set (0.00 sec)
51
52
mysql>
53
mysql> quit;
54
Bye
55
$
Copied!
Backup hooks are used to create a snapshot of the AWS RDS database snapshot. To create the RDS database snapshot, a pod with aws cli needed in the namespace. Using AWS cli, we can connect to RDS to create a snapshot.
Create the “jump” pod in the same namespace where wordpress is installed. Use the script below. It uses an image which has kubectl, aws cli installed. We need to pass on aws credentials and kubeconfig to this image. Aws credentials and region are configured using “aws configure”.
1
$ cat create_awsrds_jumphost.sh
2
#!/bin/bash
3
4
## AWS RDS Credentials and kubeconfig files are needed
5
## Configure AWS using "aws cofigure" cmd as below
6
## $ aws configure
7
## AWS Access Key ID [****************Y4TA]:
8
## AWS Secret Access Key [****************KmKp]:
9
## Default region name [None]: us-east-2
10
## Default output format [None]:
11
##
12
## Copy current kubeconfig to /root/.kube/config
13
14
# Create configmap for kubeconfig
15
if [ -e /root/.kube/config ]
16
then
17
echo "Using /root/.kube/config as valid kubeconfig"
18
else
19
echo "File /root/.kube/config doesn't exit, please copy valid kubeconfig to /root/.kube/config"
20
exit 1
21
fi
22
23
# Cleanup existing configmap, if any
24
kubectl delete configmap kubeconf -n triliowp
25
kubectl delete configmap awsconf -n triliowp
26
27
kubectl create configmap kubeconf --from-file=/root/.kube/config -n triliowp
28
if (kubectl get configmap kubeconf -n triliowp 2>/dev/null)
29
then
30
echo "Configmap for kubeconfig created successfully"
31
else
32
echo "Configmap for kubeconfig is not created, exiting..."
33
exit 1
34
fi
35
36
# Create configmap for aws rds credentials
37
if [[ -e /root/.aws/credentials && -e /root/.aws/config ]]
38
then
39
echo "Using /root/.aws/credentials and /root/.aws/config"
40
else
41
echo "Files /root/.aws/credentials and /root/.aws/config don't exit"
42
echo "Please configure AWS credentials and Region using aws configure"
43
exit 1
44
fi
45
46
kubectl create configmap awsconf --from-file=/root/.aws/ -n triliowp
47
if (kubectl get configmap awsconf -n triliowp 2>/dev/null)
48
then
49
echo "Configmap for AWS config created successfully"
50
else
51
echo "Configmap for AWS config is not created, exiting..."
52
exit 1
53
fi
54
55
# Create a jump pod for running aws rds and kubectl cmds
56
cat <<EOF | kubectl apply -f - -n triliowp
57
apiVersion: v1
58
kind: Pod
59
metadata:
60
name: jumphost-awscli
61
spec:
62
containers:
63
- name: jumphost-awscli
64
image: bearengineer/awscli-kubectl
65
imagePullPolicy: Always
66
command: [ "sh", "-c", "tail -f /dev/null" ]
67
volumeMounts:
68
- mountPath: "/root/.kube"
69
name: kubeconf
70
- mountPath: "/root/.aws"
71
name: awsconf
72
volumes:
73
- name: kubeconf
74
configMap:
75
name: kubeconf
76
- name: awsconf
77
configMap:
78
name: awsconf
79
EOF
80
81
# Wait for the pod to be up/running
82
until (kubectl get pod jumphost-awscli -n triliowp 2>/dev/null | grep Running); do sleep 5; done
83
sleep 10
84
85
# All set, start the backup with hook to run rds snapshot
86
$
87
88
$ ./create_awsrds_jumphost.sh
89
Using /root/.kube/config as valid kubeconfig
90
configmap/kubeconf created
91
NAME DATA AGE
92
kubeconf 1 1s
93
Configmap for kubeconfig created successfully
94
Using /root/.aws/credentials and /root/.aws/config
95
configmap/awsconf created
96
NAME DATA AGE
97
awsconf 2 1s
98
Configmap for AWS config created successfully
99
apiVersion: v1
100
kind: Pod
101
metadata:
102
name: jumphost-awscli
103
spec:
104
containers:
105
- name: jumphost-awscli
106
image: bearengineer/awscli-kubectl
107
imagePullPolicy: Always
108
command: [ "sh", "-c", "tail -f /dev/null" ]
109
volumeMounts:
110
- mountPath: "/root/.kube"
111
name: kubeconf
112
- mountPath: "/root/.aws"
113
name: awsconf
114
volumes:
115
- name: kubeconf
116
configMap:
117
name: kubeconf
118
- name: awsconf
119
configMap:
120
name: awsconf
121
pod/jumphost-awscli created
122
jumphost-awscli 1/1 Running 0 6s
123
$
124
$ kubectl get pod jumphost-awscli
125
NAME READY STATUS RESTARTS AGE
126
jumphost-awscli 1/1 Running 0 10s
127
$
Copied!
Create a backup hook as per yaml below using UI or CLI. In the “post” command of the hook, a script is provided which identifies a running backup and corresponding backupPlan, then creates the snapshot of the DB instance (--db-instance-identifier to be provided by the user) with snapshot identifier as “tvk-backupName-backupPlanName”. Please replace <DB Instance Identifier> with actual value below.
1
apiVersion: triliovault.trilio.io/v1
2
kind: Hook
3
metadata:
4
name: wp-hook
5
namespace: triliowp
6
spec:
7
pre:
8
execAction:
9
command:
10
- sh
11
- -c
12
- export DB_INSTANCE_ID=<DB Instance Identifier>; export SNAPSHOT_ID=$(kubectl get backup -n triliowp | grep -i InProgress | awk '{print "tvk"-$1"-"$2}'); aws rds create-db-snapshot --db-instance-identifier $DB_INSTANCE_ID --db-snapshot-identifier $SNAPSHOT_ID; aws rds wait db-snapshot-completed --db-snapshot-identifier $SNAPSHOT_ID
13
timeoutSeconds: 30
14
post:
15
execAction:
16
command:
17
- sh
18
- -c
19
- echo 'post hook action completed'
20
ignoreFailure: true
21
timeoutSeconds: 30
Copied!
Create a backupPlan using UI or CLI. Please specify the jump pod created as step 6 in pod selector for hook execution.
1
apiVersion: triliovault.trilio.io/v1
2
kind: BackupPlan
3
metadata:
4
name: wp-hook-bkpplan
5
namespace: triliowp
6
spec:
7
backupConfig:
8
schedulePolicy:
9
fullBackupCron:
10
schedule: ""
11
incrementalCron:
12
schedule: ""
13
target:
14
apiVersion: triliovault.trilio.io/v1
15
kind: Target
16
name: demo-s3-target
17
namespace: triliowp
18
backupPlanComponents: {}
19
hookConfig:
20
hooks:
21
- containerRegex: jumphost-awscli*
22
hook:
23
apiVersion: triliovault.trilio.io/v1
24
kind: Hook
25
name: wp-hook
26
namespace: triliowp
27
podSelector:
28
regex: jumphost-awscli*
29
mode: Sequential
30
podReadyWaitSeconds: 120
Copied!
Create a namespace backup where the wordpress application is installed using CLI or UI. This will also create a snapshot of the RDS database instance.
1
$ kubectl get backup demo-backup -n triliowp
2
NAME BACKUPPLAN BACKUP TYPE STATUS DATA SIZE START TIME END TIME PERCENTAGE COMPLETED BACKUP SCOPE DURATION
3
demo-backup wp-hook-bkpplan Full Available 182910976 2021-10-13T11:12:15Z 2021-10-13T11:19:03Z 100 Namespace 6m48.695350343s
4
$
Copied!
As part of the backup, a snapshot of the RDS database is taken. Same can be checked using below command with a query.
1
$ aws rds describe-db-snapshots --db-instance-identifier <DB Instance Identifier> --snapshot-type manual --query="reverse(sort_by(DBSnapshots, &SnapshotCreateTime))[*]"
2
[
3
{
4
"DBSnapshotIdentifier": "tvk-demo-backup-wp-hook-bkpplan",
5
"DBInstanceIdentifier": "<DB-Instance-Identifier>",
6
"SnapshotCreateTime": "2021-10-13T11:07:41.519000+00:00",
7
"Engine": "mysql",
8
"AllocatedStorage": 20,
9
"Status": "available",
10
"Port": 3306,
11
"AvailabilityZone": "us-east-2b",
12
"VpcId": "<vpc-aaaaa>",
13
"InstanceCreateTime": "2021-10-07T11:52:03.032000+00:00",
14
"MasterUsername": "admin",
15
"EngineVersion": "8.0.23",
16
"LicenseModel": "general-public-license",
17
"SnapshotType": "manual",
18
"OptionGroupName": "default:mysql-8-0",
19
"PercentProgress": 100,
20
"StorageType": "gp2",
21
"Encrypted": false,
22
"DBSnapshotArn": "arn:aws:rds:us-east-2:753922706039:snapshot:demo-backup-wp-hook-bkpplan",
23
"IAMDatabaseAuthenticationEnabled": false,
24
"ProcessorFeatures": [],
25
"DbiResourceId": "db-3BW2VXN5YZ4LORLSKOJU3IKUIQ",
26
"TagList": [],
27
"OriginalSnapshotCreateTime": "2021-10-13T11:07:41.519000+00:00"
28
}
29
]
30
$
Copied!
For Restore, create a restore hook as per the yaml file given below. We need user inputs for
  1. 1.
    Database Instance name for restore (DB_INSTANCE_ID=<DB Instance Identifier>)
  2. 2.
    VPC Security group to be used (VPC_SEC_GROUP=<VPC-SEC-GROUP>)
  3. 3.
    Name of the backup (BACKUP_NAME="demo-backup")
  4. 4.
    Name of the Backup Plan (BACKUPPLAN_NAME="wp-hook-bkpplan")
  5. 5.
    Based on the backup and backup plan name, SNAPSHOT ID is formed by concatenating these 2 strings.
  6. 6.
    Also note that additional maxRetryCount and timeoutSeconds are added for the “post” action as it may take more time.
Replace actual values below for "DB Instance Identifier" and "VPC Sec Group"
1
apiVersion: triliovault.trilio.io/v1
2
kind: Hook
3
metadata:
4
name: restorehook
5
namespace: restorens
6
spec:
7
pre:
8
execAction:
9
command:
10
- sh
11
- -c
12
- 'echo ''Pre-hook'' '
13
ignoreFailure: true
14
timeoutSeconds: 30
15
post:
16
execAction:
17
command:
18
- sh
19
- -c
20
- DB_INSTANCE_ID="<DB Instance Identifier>"; VPC_SEC_GROUP="<VPC Sec Group>"; BACKUP_NAME="demo-backup"; BACKUPPLAN_NAME="wp-hook-bkpplan"; SNAPSHOT_ID=tvk-${BACKUP_NAME}-${BACKUPPLAN_NAME}; aws rds restore-db-instance-from-db-snapshot --db-instance-identifier ${DB_INSTANCE_ID} --db-snapshot-identifier ${SNAPSHOT_ID} --vpc-security-group-ids $(VPC_SEC_GROUP); aws rds wait db-instance-available --db-instance-identifier ${DB_INSTANCE_ID}; echo $SNAPSHOT_ID > /tmp/restorehook
21
maxRetryCount: 5
22
timeoutSeconds: 300
Copied!
If we are restoring the RDS database with the same name, no changes are needed in the restored application using the RDS database as there are no changes in the RDS Database endpoint and credentials. However, if a different RDS database name is used for restore, the restore application using the RDS database needs to be updated accordingly.
Create a restore using CLI or UI.
1
$ kubectl get restore -n restorens
2
NAME BACKUP BACKUP NAMESPACE STATUS DATA SIZE START TIME END TIME PERCENTAGE COMPLETED RESTORE SCOPE DURATION
3
demo-restore demo-backup triliowp Completed 126657137 2021-10-13T11:31:11Z 2021-10-13T11:34:51Z 100 Namespace 3m40.70240849s
4
$
Copied!
As part of the restore, the RDS Database instance is created from the snapshot. The wordpress application is up/running in the restore namespace.
This completes the backup and restore of a stateful application which uses external database like AWS RDS using Triliovault for Kubernetes.

2. AWS RDS snapshot cleanup upon backup deletion

Objective - Provide tool for deletion of snapshots of external databases (AWS RDS, Google Cloud SQL to begin with)
Summary - This use case is to provide a tool to delete snapshot of external cloud database upon deletion of TVK backup linked to the cluster.
Pre-requisite -
  1. 1.
    Applications on the k8s cluster are configured to use Cloud Database managed service
  2. 2.
    All the required details for the cloud database connectivity are available such as database instance name, credentials
  3. 3.
    k8s cluster with TVK installed and target configured. Based on the backups on the target, the snapshots will be retained/deleted.
Assumptions -
  1. 1.
    Applications on the k8s cluster are configured with specific Database instance
  2. 2.
    User provides all the information required for Database snapshot deletion (on-demand)
  3. 3.
    All the requirements for database snapshot deletion are provided such as user access for backup, zones/regions allowed for backups, allotted space, Database instance name/identifier, location etc.
  4. 4.
    The TVK backup target configured on the k8s cluster is referred for comparing the available backups against the snapshots of the Cloud database instances.
Workflow -
  1. 1.
    User provides inputs for a. List of applications configured to use external database b. The Database instance name/identifier c. User credentials for backup, snapshot deletion d. Zone/region allowed for backup, snapshot deletion e. Location for backup
  2. 2.
    The user inputs/credentials are stored in a configmap or secret
  3. 3.
    The TVK is installed and backup target is configured.
  4. 4.
    A cronjob is created using an image which has access to AWS RDS and k8s cluster. It has kubectl, awscli tools and libraries installed.
  5. 5.
    The cronjob will periodically check the backups available on the backup target and compare it with the snapshots of the external cloud database. If the backup is deleted from the backup target, the cronjob will delete the corresponding snapshot from the external cloud database.
  6. 6.
    The cronjob is launched "on-demand" by the user.
Example with steps Followed -
Create a configmap with a script to check backups in a user specified namespace. Refer the yaml below. Please replace <DB Instance Identifier> with actual value.
1
kind: ConfigMap
2
apiVersion: v1
3
metadata:
4
name: snap-delete-script
5
data:
6
snapdelscript.sh: |
7
#!/bin/sh
8
echo "Cronjb to cleanup RDS snapshots if TVK backups are not found"
9
echo
10
snaplist=$(aws rds describe-db-snapshots --db-instance-identifier <DB Instance Identifier> --snapshot-type manual --query="reverse(sort_by(DBSnapshots, &SnapshotCreateTime))[*].DBSnapshotIdentifier" | grep -i tvk | tr -d '",')
11
kubectl get backup --no-headers -n triliowp | awk '{print "tvk-"$1"-"$2}' > backuplist
12
for snap in ${snaplist}
13
do
14
if ! grep "$snap" backuplist
15
then
16
echo "Backup for snapshot $snap not found"
17
echo "Deleting the snapshot $snap"
18
aws rds delete-db-snapshot --db-snapshot-identifier $snap
19
echo
20
else
21
echo "Backup for $snap Found"
22
echo
23
fi
24
done
25
echo "===Done==="
Copied!
Create a cronjob to run the script with schedule for the execution. It uses an image which has kubectl, aws cli installed. We need to pass on aws credentials and kubeconfig to this image. Aws credentials and region are configured using “aws configure”. The schedule can be changed as per the frequency needed to cleanup the snapshots. Refer the yaml below
1
kind: CronJob
2
apiVersion: batch/v1beta1
3
metadata:
4
name: snap-delete-cronjob
5
spec:
6
schedule: "*/1 * * * *"
7
jobTemplate:
8
spec:
9
template:
10
spec:
11
containers:
12
- name: mycron-container
13
image: bearengineer/awscli-kubectl
14
imagePullPolicy: IfNotPresent
15
16
command: [ "/bin/sh" ]
17
args: [ "/tmp/snapdelscript.sh" ]
18
volumeMounts:
19
- name: script
20
mountPath: "/tmp/"
21
- name: kubeconf
22
mountPath: "/root/.kube"
23
- name: awsconf
24
mountPath: "/root/.aws"
25
26
volumes:
27
- name: script
28
configMap:
29
name: snap-delete-script
30
- name: kubeconf
31
configMap:
32
name: kubeconf
33
- name: awsconf
34
configMap:
35
name: awsconf
36
restartPolicy: OnFailure
37
terminationGracePeriodSeconds: 0
38
39
concurrencyPolicy: Replace
Copied!
Steps and output of the commands
1
$ kubectl create -f snapdelete_configmap.yaml -n snapdelete
2
configmap/snap-delete-script created
3
$
4
$ kubectl get configmap -n snapdelete
5
NAME DATA AGE
6
awsconf 2 4d21h
7
kube-root-ca.crt 1 4d23h
8
kubeconf 1 4d21h
9
snap-delete-script 1 9s
10
$
11
$ kubectl create -f snap-delete-cronjob.yaml -n snapdelete
12
cronjob.batch/snap-delete-cronjob created
13
$ kubectl get all -n snapdelete NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
14
cronjob.batch/snap-delete-cronjob */1 * * * * False 0 <none> 8s
15
$
16
$ aws rds describe-db-snapshots --db-instance-identifier <DB Instance Indetifier> --snapshot-type manual --query="reverse(sort_by(DBSnapshots, &SnapshotCreateTime))[*].DBSnapshotIdentifier"
17
[
18
"tvk-demo3-wp-hook-bkpplan",
19
"tvk-demo-backup-wp-hook-bkpplan",
20
"tvk-demo2-wp-hook-bkpplan",
21
"tvk-demo1-wp-hook-bkpplan",
22
"demo-backup-wp-hook-bkpplan"
23
]
24
$
25
$ kubectl get all -n snapdelete
26
NAME READY STATUS RESTARTS AGE
27
pod/snap-delete-cronjob-1636549440-f7bl2 0/1 Completed 0 10s
28
29
NAME COMPLETIONS DURATION AGE
30
job.batch/snap-delete-cronjob-1636549440 1/1 4s 11s
31
32
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
33
cronjob.batch/snap-delete-cronjob */1 * * * * False 0 18s 55s
34
$
35
$ kubectl logs pod/snap-delete-cronjob-1636549440-f7bl2 -n snapdelete
36
Cronjb to cleanup RDS snapshots if TVK backups are not found
37
38
Backup for snapshot tvk-demo3-wp-hook-bkpplan not found
39
Deleting the snapshot tvk-demo3-wp-hook-bkpplan
40
{
41
"DBSnapshot": {
42
"MasterUsername": "admin",
43
"LicenseModel": "general-public-license",
44
"InstanceCreateTime": "2021-10-13T11:46:33.596Z",
45
"Engine": "mysql",
46
"VpcId": "<vpc-aaaaa>",
47
"DBSnapshotIdentifier": "tvk-demo3-wp-hook-bkpplan",
48
"AllocatedStorage": 20,
49
"Status": "deleted",
50
"PercentProgress": 100,
51
"DBSnapshotArn": "arn:aws:rds:us-east-2:753922706039:snapshot:tvk-demo3-wp-hook-bkpplan",
52
"EngineVersion": "8.0.23",
53
"ProcessorFeatures": [],
54
"OptionGroupName": "default:mysql-8-0",
55
"SnapshotCreateTime": "2021-11-10T12:51:27.805Z",
56
"AvailabilityZone": "us-east-2a",
57
"StorageType": "gp2",
58
"Encrypted": false,
59
"IAMDatabaseAuthenticationEnabled": false,
60
"DbiResourceId": "db-Q5FFFZMYAU3JNOKRDFYR72YIJE",
61
"SnapshotType": "manual",
62
"Port": 3306,
63
"DBInstanceIdentifier": "<DB-Instance-Identifier>"
64
}
65
}
66
67
tvk-demo-backup-wp-hook-bkpplan
68
Backup for tvk-demo-backup-wp-hook-bkpplan Found
69
70
tvk-demo2-wp-hook-bkpplan
71
Backup for tvk-demo2-wp-hook-bkpplan Found
72
73
tvk-demo1-wp-hook-bkpplan
74
Backup for tvk-demo1-wp-hook-bkpplan Found
75
76
===Done===
77
$
78
$ aws rds describe-db-snapshots --db-instance-identifier <DB Instance Identifier> --snapshot-type manual --query="reverse(sort_by(DBSnapshots, &SnapshotCreateTime))[*].DBSnapshotIdentifier"
79
[
80
"tvk-demo-backup-wp-hook-bkpplan",
81
"tvk-demo2-wp-hook-bkpplan",
82
"tvk-demo1-wp-hook-bkpplan",
83
"demo-backup-wp-hook-bkpplan"
84
]
85
$
Copied!
Last modified 3d ago