2022-09-19 16:19:51 -07:00
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
"""
Purpose
Shows how to use the AWS SDK for Python (Boto3) to create and manage Amazon Aurora
2022-09-26 15:04:55 -07:00
DB clusters.
2022-09-19 16:19:51 -07:00
"""
import logging
import boto3
from botocore . exceptions import ClientError
logger = logging . getLogger ( __name__ )
2023-10-18 10:35:05 -07:00
2022-09-19 16:19:51 -07:00
# snippet-start:[python.example_code.aurora.helper.AuroraWrapper_full]
# snippet-start:[python.example_code.aurora.helper.AuroraWrapper_decl]
class AuroraWrapper :
2022-09-26 15:04:55 -07:00
""" Encapsulates Aurora DB cluster actions. """
2023-10-18 10:35:05 -07:00
2022-09-19 16:19:51 -07:00
def __init__ ( self , rds_client ) :
"""
:param rds_client: A Boto3 Amazon Relational Database Service (Amazon RDS) client.
"""
self . rds_client = rds_client
@classmethod
def from_client ( cls ) :
"""
Instantiates this class from a Boto3 client.
"""
2023-10-18 10:35:05 -07:00
rds_client = boto3 . client ( " rds " )
2022-09-19 16:19:51 -07:00
return cls ( rds_client )
2023-10-18 10:35:05 -07:00
# snippet-end:[python.example_code.aurora.helper.AuroraWrapper_decl]
2022-09-19 16:19:51 -07:00
# snippet-start:[python.example_code.aurora.DescribeDBClusterParameterGroups]
def get_parameter_group ( self , parameter_group_name ) :
"""
2022-09-26 15:04:55 -07:00
Gets a DB cluster parameter group.
2022-09-19 16:19:51 -07:00
:param parameter_group_name: The name of the parameter group to retrieve.
:return: The requested parameter group.
"""
try :
response = self . rds_client . describe_db_cluster_parameter_groups (
2023-10-18 10:35:05 -07:00
DBClusterParameterGroupName = parameter_group_name
)
parameter_group = response [ " DBClusterParameterGroups " ] [ 0 ]
2022-09-19 16:19:51 -07:00
except ClientError as err :
2023-10-18 10:35:05 -07:00
if err . response [ " Error " ] [ " Code " ] == " DBParameterGroupNotFound " :
2022-09-19 16:19:51 -07:00
logger . info ( " Parameter group %s does not exist. " , parameter_group_name )
else :
logger . error (
2023-10-18 10:35:05 -07:00
" Couldn ' t get parameter group %s . Here ' s why: %s : %s " ,
parameter_group_name ,
err . response [ " Error " ] [ " Code " ] ,
err . response [ " Error " ] [ " Message " ] ,
)
2022-09-19 16:19:51 -07:00
raise
else :
return parameter_group
2023-10-18 10:35:05 -07:00
2022-09-19 16:19:51 -07:00
# snippet-end:[python.example_code.aurora.DescribeDBClusterParameterGroups]
# snippet-start:[python.example_code.aurora.CreateDBClusterParameterGroup]
2023-10-18 10:35:05 -07:00
def create_parameter_group (
self , parameter_group_name , parameter_group_family , description
) :
2022-09-19 16:19:51 -07:00
"""
2022-09-26 15:04:55 -07:00
Creates a DB cluster parameter group that is based on the specified parameter group
2022-09-19 16:19:51 -07:00
family.
:param parameter_group_name: The name of the newly created parameter group.
:param parameter_group_family: The family that is used as the basis of the new
parameter group.
:param description: A description given to the parameter group.
:return: Data about the newly created parameter group.
"""
try :
response = self . rds_client . create_db_cluster_parameter_group (
DBClusterParameterGroupName = parameter_group_name ,
DBParameterGroupFamily = parameter_group_family ,
2023-10-18 10:35:05 -07:00
Description = description ,
)
2022-09-19 16:19:51 -07:00
except ClientError as err :
logger . error (
2023-10-18 10:35:05 -07:00
" Couldn ' t create parameter group %s . Here ' s why: %s : %s " ,
parameter_group_name ,
err . response [ " Error " ] [ " Code " ] ,
err . response [ " Error " ] [ " Message " ] ,
)
2022-09-19 16:19:51 -07:00
raise
else :
return response
2023-10-18 10:35:05 -07:00
2022-09-19 16:19:51 -07:00
# snippet-end:[python.example_code.aurora.CreateDBClusterParameterGroup]
# snippet-start:[python.example_code.aurora.DeleteDBClusterParameterGroup]
def delete_parameter_group ( self , parameter_group_name ) :
"""
2022-09-26 15:04:55 -07:00
Deletes a DB cluster parameter group.
2022-09-19 16:19:51 -07:00
:param parameter_group_name: The name of the parameter group to delete.
:return: Data about the parameter group.
"""
try :
response = self . rds_client . delete_db_cluster_parameter_group (
2023-10-18 10:35:05 -07:00
DBClusterParameterGroupName = parameter_group_name
)
2022-09-19 16:19:51 -07:00
except ClientError as err :
logger . error (
2023-10-18 10:35:05 -07:00
" Couldn ' t delete parameter group %s . Here ' s why: %s : %s " ,
parameter_group_name ,
err . response [ " Error " ] [ " Code " ] ,
err . response [ " Error " ] [ " Message " ] ,
)
2022-09-19 16:19:51 -07:00
raise
else :
return response
2023-10-18 10:35:05 -07:00
2022-09-19 16:19:51 -07:00
# snippet-end:[python.example_code.aurora.DeleteDBClusterParameterGroup]
# snippet-start:[python.example_code.aurora.DescribeDBClusterParameters]
2023-10-18 10:35:05 -07:00
def get_parameters ( self , parameter_group_name , name_prefix = " " , source = None ) :
2022-09-19 16:19:51 -07:00
"""
2022-09-26 15:04:55 -07:00
Gets the parameters that are contained in a DB cluster parameter group.
2022-09-19 16:19:51 -07:00
:param parameter_group_name: The name of the parameter group to query.
:param name_prefix: When specified, the retrieved list of parameters is filtered
to contain only parameters that start with this prefix.
:param source: When specified, only parameters from this source are retrieved.
For example, a source of ' user ' retrieves only parameters that
were set by a user.
:return: The list of requested parameters.
"""
try :
2023-10-18 10:35:05 -07:00
kwargs = { " DBClusterParameterGroupName " : parameter_group_name }
2022-09-19 16:19:51 -07:00
if source is not None :
2023-10-18 10:35:05 -07:00
kwargs [ " Source " ] = source
2022-09-19 16:19:51 -07:00
parameters = [ ]
2023-10-18 10:35:05 -07:00
paginator = self . rds_client . get_paginator ( " describe_db_cluster_parameters " )
2022-09-19 16:19:51 -07:00
for page in paginator . paginate ( * * kwargs ) :
parameters + = [
2023-10-18 10:35:05 -07:00
p
for p in page [ " Parameters " ]
if p [ " ParameterName " ] . startswith ( name_prefix )
]
2022-09-19 16:19:51 -07:00
except ClientError as err :
logger . error (
2023-10-18 10:35:05 -07:00
" Couldn ' t get parameters for %s . Here ' s why: %s : %s " ,
parameter_group_name ,
err . response [ " Error " ] [ " Code " ] ,
err . response [ " Error " ] [ " Message " ] ,
)
2022-09-19 16:19:51 -07:00
raise
else :
return parameters
2023-10-18 10:35:05 -07:00
2022-09-19 16:19:51 -07:00
# snippet-end:[python.example_code.aurora.DescribeDBClusterParameters]
2023-10-18 10:35:05 -07:00
2022-09-19 16:19:51 -07:00
# snippet-start:[python.example_code.aurora.ModifyDBClusterParameterGroup]
def update_parameters ( self , parameter_group_name , update_parameters ) :
"""
2022-09-26 15:04:55 -07:00
Updates parameters in a custom DB cluster parameter group.
2022-09-19 16:19:51 -07:00
:param parameter_group_name: The name of the parameter group to update.
:param update_parameters: The parameters to update in the group.
:return: Data about the modified parameter group.
"""
try :
response = self . rds_client . modify_db_cluster_parameter_group (
2023-10-18 10:35:05 -07:00
DBClusterParameterGroupName = parameter_group_name ,
Parameters = update_parameters ,
)
2022-09-19 16:19:51 -07:00
except ClientError as err :
logger . error (
2023-10-18 10:35:05 -07:00
" Couldn ' t update parameters in %s . Here ' s why: %s : %s " ,
parameter_group_name ,
err . response [ " Error " ] [ " Code " ] ,
err . response [ " Error " ] [ " Message " ] ,
)
2022-09-19 16:19:51 -07:00
raise
else :
return response
2023-10-18 10:35:05 -07:00
2022-09-19 16:19:51 -07:00
# snippet-end:[python.example_code.aurora.ModifyDBClusterParameterGroup]
# snippet-start:[python.example_code.aurora.DescribeDBClusters]
def get_db_cluster ( self , cluster_name ) :
"""
2022-09-26 15:04:55 -07:00
Gets data about an Aurora DB cluster.
2022-09-19 16:19:51 -07:00
2022-09-26 15:04:55 -07:00
:param cluster_name: The name of the DB cluster to retrieve.
:return: The retrieved DB cluster.
2022-09-19 16:19:51 -07:00
"""
try :
response = self . rds_client . describe_db_clusters (
2023-10-18 10:35:05 -07:00
DBClusterIdentifier = cluster_name
)
cluster = response [ " DBClusters " ] [ 0 ]
2022-09-19 16:19:51 -07:00
except ClientError as err :
2023-10-18 10:35:05 -07:00
if err . response [ " Error " ] [ " Code " ] == " DBClusterNotFoundFault " :
2022-09-19 16:19:51 -07:00
logger . info ( " Cluster %s does not exist. " , cluster_name )
else :
logger . error (
2023-10-18 10:35:05 -07:00
" Couldn ' t verify the existence of DB cluster %s . Here ' s why: %s : %s " ,
cluster_name ,
err . response [ " Error " ] [ " Code " ] ,
err . response [ " Error " ] [ " Message " ] ,
)
2022-09-19 16:19:51 -07:00
raise
else :
return cluster
2023-10-18 10:35:05 -07:00
2022-09-19 16:19:51 -07:00
# snippet-end:[python.example_code.aurora.DescribeDBClusters]
# snippet-start:[python.example_code.aurora.CreateDBCluster]
def create_db_cluster (
2023-10-18 10:35:05 -07:00
self ,
cluster_name ,
parameter_group_name ,
db_name ,
db_engine ,
db_engine_version ,
admin_name ,
admin_password ,
) :
2022-09-19 16:19:51 -07:00
"""
2022-09-26 15:04:55 -07:00
Creates a DB cluster that is configured to use the specified parameter group.
The newly created DB cluster contains a database that uses the specified engine and
2022-09-19 16:19:51 -07:00
engine version.
2022-09-26 15:04:55 -07:00
:param cluster_name: The name of the DB cluster to create.
2022-09-19 16:19:51 -07:00
:param parameter_group_name: The name of the parameter group to associate with
2022-09-26 15:04:55 -07:00
the DB cluster.
2022-09-19 16:19:51 -07:00
:param db_name: The name of the database to create.
:param db_engine: The database engine of the database that is created, such as MySql.
:param db_engine_version: The version of the database engine.
2022-09-26 15:04:55 -07:00
:param admin_name: The user name of the database administrator.
2022-09-19 16:19:51 -07:00
:param admin_password: The password of the database administrator.
2022-09-26 15:04:55 -07:00
:return: The newly created DB cluster.
2022-09-19 16:19:51 -07:00
"""
try :
response = self . rds_client . create_db_cluster (
DatabaseName = db_name ,
DBClusterIdentifier = cluster_name ,
DBClusterParameterGroupName = parameter_group_name ,
Engine = db_engine ,
EngineVersion = db_engine_version ,
MasterUsername = admin_name ,
2023-10-18 10:35:05 -07:00
MasterUserPassword = admin_password ,
)
cluster = response [ " DBCluster " ]
2022-09-19 16:19:51 -07:00
except ClientError as err :
logger . error (
2023-10-18 10:35:05 -07:00
" Couldn ' t create database %s . Here ' s why: %s : %s " ,
db_name ,
err . response [ " Error " ] [ " Code " ] ,
err . response [ " Error " ] [ " Message " ] ,
)
2022-09-19 16:19:51 -07:00
raise
else :
return cluster
2023-10-18 10:35:05 -07:00
2022-09-19 16:19:51 -07:00
# snippet-end:[python.example_code.aurora.CreateDBCluster]
# snippet-start:[python.example_code.aurora.DeleteDBCluster]
def delete_db_cluster ( self , cluster_name ) :
"""
2022-09-26 15:04:55 -07:00
Deletes a DB cluster.
2022-09-19 16:19:51 -07:00
2022-09-26 15:04:55 -07:00
:param cluster_name: The name of the DB cluster to delete.
2022-09-19 16:19:51 -07:00
"""
try :
self . rds_client . delete_db_cluster (
2023-10-18 10:35:05 -07:00
DBClusterIdentifier = cluster_name , SkipFinalSnapshot = True
)
2022-09-26 15:04:55 -07:00
logger . info ( " Deleted DB cluster %s . " , cluster_name )
2022-09-19 16:19:51 -07:00
except ClientError :
2022-09-26 15:04:55 -07:00
logger . exception ( " Couldn ' t delete DB cluster %s . " , cluster_name )
2022-09-19 16:19:51 -07:00
raise
2023-10-18 10:35:05 -07:00
2022-09-19 16:19:51 -07:00
# snippet-end:[python.example_code.aurora.DeleteDBCluster]
2023-10-18 10:35:05 -07:00
2022-09-19 16:19:51 -07:00
# snippet-start:[python.example_code.aurora.CreateDBClusterSnapshot]
def create_cluster_snapshot ( self , snapshot_id , cluster_id ) :
"""
2022-09-26 15:04:55 -07:00
Creates a snapshot of a DB cluster.
2022-09-19 16:19:51 -07:00
:param snapshot_id: The ID to give the created snapshot.
2022-09-26 15:04:55 -07:00
:param cluster_id: The DB cluster to snapshot.
2022-09-19 16:19:51 -07:00
:return: Data about the newly created snapshot.
"""
try :
response = self . rds_client . create_db_cluster_snapshot (
2023-10-18 10:35:05 -07:00
DBClusterSnapshotIdentifier = snapshot_id , DBClusterIdentifier = cluster_id
)
snapshot = response [ " DBClusterSnapshot " ]
2022-09-19 16:19:51 -07:00
except ClientError as err :
logger . error (
2023-10-18 10:35:05 -07:00
" Couldn ' t create snapshot of %s . Here ' s why: %s : %s " ,
cluster_id ,
err . response [ " Error " ] [ " Code " ] ,
err . response [ " Error " ] [ " Message " ] ,
)
2022-09-19 16:19:51 -07:00
raise
else :
return snapshot
2023-10-18 10:35:05 -07:00
2022-09-19 16:19:51 -07:00
# snippet-end:[python.example_code.aurora.CreateDBClusterSnapshot]
# snippet-start:[python.example_code.aurora.DescribeDBClusterSnapshots]
def get_cluster_snapshot ( self , snapshot_id ) :
"""
2022-09-26 15:04:55 -07:00
Gets a DB cluster snapshot.
2022-09-19 16:19:51 -07:00
:param snapshot_id: The ID of the snapshot to retrieve.
:return: The retrieved snapshot.
"""
try :
response = self . rds_client . describe_db_cluster_snapshots (
2023-10-18 10:35:05 -07:00
DBClusterSnapshotIdentifier = snapshot_id
)
snapshot = response [ " DBClusterSnapshots " ] [ 0 ]
2022-09-19 16:19:51 -07:00
except ClientError as err :
logger . error (
2023-10-18 10:35:05 -07:00
" Couldn ' t get DB cluster snapshot %s . Here ' s why: %s : %s " ,
snapshot_id ,
err . response [ " Error " ] [ " Code " ] ,
err . response [ " Error " ] [ " Message " ] ,
)
2022-09-19 16:19:51 -07:00
raise
else :
return snapshot
2023-10-18 10:35:05 -07:00
2022-09-19 16:19:51 -07:00
# snippet-end:[python.example_code.aurora.DescribeDBClusterSnapshots]
2023-10-18 10:35:05 -07:00
2022-09-19 16:19:51 -07:00
# snippet-start:[python.example_code.aurora.CreateDBInstance_InCluster]
2023-10-18 10:35:05 -07:00
def create_instance_in_cluster (
self , instance_id , cluster_id , db_engine , instance_class
) :
2022-09-19 16:19:51 -07:00
"""
2022-09-26 15:04:55 -07:00
Creates a database instance in an existing DB cluster. The first database that is
created defaults to a read-write DB instance.
2022-09-19 16:19:51 -07:00
2022-09-26 15:04:55 -07:00
:param instance_id: The ID to give the newly created DB instance.
:param cluster_id: The ID of the DB cluster where the DB instance is created.
:param db_engine: The database engine of a database to create in the DB instance.
2022-09-19 16:19:51 -07:00
This must be compatible with the configured parameter group
2022-09-26 15:04:55 -07:00
of the DB cluster.
:param instance_class: The DB instance class for the newly created DB instance.
:return: Data about the newly created DB instance.
2022-09-19 16:19:51 -07:00
"""
try :
response = self . rds_client . create_db_instance (
2023-10-18 10:35:05 -07:00
DBInstanceIdentifier = instance_id ,
DBClusterIdentifier = cluster_id ,
Engine = db_engine ,
DBInstanceClass = instance_class ,
)
db_inst = response [ " DBInstance " ]
2022-09-19 16:19:51 -07:00
except ClientError as err :
logger . error (
2023-10-18 10:35:05 -07:00
" Couldn ' t create DB instance %s . Here ' s why: %s : %s " ,
instance_id ,
err . response [ " Error " ] [ " Code " ] ,
err . response [ " Error " ] [ " Message " ] ,
)
2022-09-19 16:19:51 -07:00
raise
else :
return db_inst
2023-10-18 10:35:05 -07:00
2022-09-19 16:19:51 -07:00
# snippet-end:[python.example_code.aurora.CreateDBInstance_InCluster]
# snippet-start:[python.example_code.aurora.DescribeDBEngineVersions]
def get_engine_versions ( self , engine , parameter_group_family = None ) :
"""
Gets database engine versions that are available for the specified engine
and parameter group family.
:param engine: The database engine to look up.
:param parameter_group_family: When specified, restricts the returned list of
engine versions to those that are compatible with
this parameter group family.
:return: The list of database engine versions.
"""
try :
2023-10-18 10:35:05 -07:00
kwargs = { " Engine " : engine }
2022-09-19 16:19:51 -07:00
if parameter_group_family is not None :
2023-10-18 10:35:05 -07:00
kwargs [ " DBParameterGroupFamily " ] = parameter_group_family
2022-09-19 16:19:51 -07:00
response = self . rds_client . describe_db_engine_versions ( * * kwargs )
2023-10-18 10:35:05 -07:00
versions = response [ " DBEngineVersions " ]
2022-09-19 16:19:51 -07:00
except ClientError as err :
logger . error (
2023-10-18 10:35:05 -07:00
" Couldn ' t get engine versions for %s . Here ' s why: %s : %s " ,
engine ,
err . response [ " Error " ] [ " Code " ] ,
err . response [ " Error " ] [ " Message " ] ,
)
2022-09-19 16:19:51 -07:00
raise
else :
return versions
2023-10-18 10:35:05 -07:00
2022-09-19 16:19:51 -07:00
# snippet-end:[python.example_code.aurora.DescribeDBEngineVersions]
# snippet-start:[python.example_code.aurora.DescribeOrderableDBInstanceOptions]
def get_orderable_instances ( self , db_engine , db_engine_version ) :
"""
Gets DB instance options that can be used to create DB instances that are
compatible with a set of specifications.
2022-09-26 15:04:55 -07:00
:param db_engine: The database engine that must be supported by the DB instance.
:param db_engine_version: The engine version that must be supported by the DB instance.
:return: The list of DB instance options that can be used to create a compatible DB instance.
2022-09-19 16:19:51 -07:00
"""
try :
inst_opts = [ ]
2023-10-18 10:35:05 -07:00
paginator = self . rds_client . get_paginator (
" describe_orderable_db_instance_options "
)
for page in paginator . paginate (
Engine = db_engine , EngineVersion = db_engine_version
) :
inst_opts + = page [ " OrderableDBInstanceOptions " ]
2022-09-19 16:19:51 -07:00
except ClientError as err :
logger . error (
2022-09-26 15:04:55 -07:00
" Couldn ' t get orderable DB instances. Here ' s why: %s : %s " ,
2023-10-18 10:35:05 -07:00
err . response [ " Error " ] [ " Code " ] ,
err . response [ " Error " ] [ " Message " ] ,
)
2022-09-19 16:19:51 -07:00
raise
else :
return inst_opts
2023-10-18 10:35:05 -07:00
2022-09-19 16:19:51 -07:00
# snippet-end:[python.example_code.aurora.DescribeOrderableDBInstanceOptions]
# snippet-start:[python.example_code.aurora.DescribeDBInstances]
def get_db_instance ( self , instance_id ) :
"""
Gets data about a DB instance.
2022-09-26 15:04:55 -07:00
:param instance_id: The ID of the DB instance to retrieve.
2022-09-19 16:19:51 -07:00
:return: The retrieved DB instance.
"""
try :
response = self . rds_client . describe_db_instances (
2023-10-18 10:35:05 -07:00
DBInstanceIdentifier = instance_id
)
db_inst = response [ " DBInstances " ] [ 0 ]
2022-09-19 16:19:51 -07:00
except ClientError as err :
2023-10-18 10:35:05 -07:00
if err . response [ " Error " ] [ " Code " ] == " DBInstanceNotFound " :
2022-09-19 16:19:51 -07:00
logger . info ( " Instance %s does not exist. " , instance_id )
else :
logger . error (
2023-10-18 10:35:05 -07:00
" Couldn ' t get DB instance %s . Here ' s why: %s : %s " ,
instance_id ,
err . response [ " Error " ] [ " Code " ] ,
err . response [ " Error " ] [ " Message " ] ,
)
2022-09-19 16:19:51 -07:00
raise
else :
return db_inst
2023-10-18 10:35:05 -07:00
2022-09-19 16:19:51 -07:00
# snippet-end:[python.example_code.aurora.DescribeDBInstances]
# snippet-start:[python.example_code.aurora.DeleteDBInstance]
def delete_db_instance ( self , instance_id ) :
"""
Deletes a DB instance.
2022-09-26 15:04:55 -07:00
:param instance_id: The ID of the DB instance to delete.
:return: Data about the deleted DB instance.
2022-09-19 16:19:51 -07:00
"""
try :
response = self . rds_client . delete_db_instance (
2023-10-18 10:35:05 -07:00
DBInstanceIdentifier = instance_id ,
SkipFinalSnapshot = True ,
DeleteAutomatedBackups = True ,
)
db_inst = response [ " DBInstance " ]
2022-09-19 16:19:51 -07:00
except ClientError as err :
logger . error (
2023-10-18 10:35:05 -07:00
" Couldn ' t delete DB instance %s . Here ' s why: %s : %s " ,
instance_id ,
err . response [ " Error " ] [ " Code " ] ,
err . response [ " Error " ] [ " Message " ] ,
)
2022-09-19 16:19:51 -07:00
raise
else :
return db_inst
2023-10-18 10:35:05 -07:00
2022-09-19 16:19:51 -07:00
# snippet-end:[python.example_code.aurora.DeleteDBInstance]
2023-10-18 10:35:05 -07:00
2022-09-19 16:19:51 -07:00
# snippet-end:[python.example_code.aurora.helper.AuroraWrapper_full]