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 Relational
2022-09-26 15:04:55 -07:00
Database Service (Amazon RDS) DB instances.
2022-09-19 16:19:51 -07:00
"""
import json
import logging
import boto3
from botocore . exceptions import ClientError
logger = logging . getLogger ( __name__ )
# snippet-start:[python.example_code.rds.helper.InstanceWrapper_full]
# snippet-start:[python.example_code.rds.helper.InstanceWrapper_decl]
class InstanceWrapper :
2022-09-26 15:04:55 -07:00
""" Encapsulates Amazon RDS DB instance 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 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.rds.helper.InstanceWrapper_decl]
2022-09-19 16:19:51 -07:00
# snippet-start:[python.example_code.rds.DescribeDBParameterGroups]
def get_parameter_group ( self , parameter_group_name ) :
"""
Gets a DB parameter group.
:param parameter_group_name: The name of the parameter group to retrieve.
:return: The parameter group.
"""
try :
response = self . rds_client . describe_db_parameter_groups (
2023-10-18 10:35:05 -07:00
DBParameterGroupName = parameter_group_name
)
parameter_group = response [ " DBParameterGroups " ] [ 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.rds.DescribeDBParameterGroups]
# snippet-start:[python.example_code.rds.CreateDBParameterGroup]
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
"""
Creates a DB parameter group that is based on the specified parameter group
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_parameter_group (
DBParameterGroupName = 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.rds.CreateDBParameterGroup]
# snippet-start:[python.example_code.rds.DeleteDBParameterGroup]
def delete_parameter_group ( self , parameter_group_name ) :
"""
Deletes a DB parameter group.
:param parameter_group_name: The name of the parameter group to delete.
:return: Data about the parameter group.
"""
try :
self . rds_client . delete_db_parameter_group (
2023-10-18 10:35:05 -07:00
DBParameterGroupName = 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
2023-10-18 10:35:05 -07:00
2022-09-19 16:19:51 -07:00
# snippet-end:[python.example_code.rds.DeleteDBParameterGroup]
# snippet-start:[python.example_code.rds.DescribeDBParameters]
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
"""
Gets the parameters that are contained in a DB parameter group.
: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 = { " DBParameterGroupName " : 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_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.rds.DescribeDBParameters]
# snippet-start:[python.example_code.rds.ModifyDBParameterGroup]
def update_parameters ( self , parameter_group_name , update_parameters ) :
"""
Updates parameters in a custom DB parameter group.
: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_parameter_group (
2023-10-18 10:35:05 -07:00
DBParameterGroupName = 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.rds.ModifyDBParameterGroup]
# snippet-start:[python.example_code.rds.CreateDBSnapshot]
def create_snapshot ( self , snapshot_id , instance_id ) :
"""
Creates a snapshot of a DB instance.
:param snapshot_id: The ID to give the created snapshot.
2022-09-26 15:04:55 -07:00
:param instance_id: The ID of the DB instance to snapshot.
2022-09-19 16:19:51 -07:00
:return: Data about the newly created snapshot.
"""
try :
response = self . rds_client . create_db_snapshot (
2023-10-18 10:35:05 -07:00
DBSnapshotIdentifier = snapshot_id , DBInstanceIdentifier = instance_id
)
snapshot = response [ " DBSnapshot " ]
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 " ,
instance_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.rds.CreateDBSnapshot]
# snippet-start:[python.example_code.rds.DescribeDBSnapshots]
def get_snapshot ( self , snapshot_id ) :
"""
Gets a DB instance snapshot.
:param snapshot_id: The ID of the snapshot to retrieve.
:return: The retrieved snapshot.
"""
try :
response = self . rds_client . describe_db_snapshots (
2023-10-18 10:35:05 -07:00
DBSnapshotIdentifier = snapshot_id
)
snapshot = response [ " DBSnapshots " ] [ 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 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.rds.DescribeDBSnapshots]
# snippet-start:[python.example_code.rds.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.rds.DescribeDBEngineVersions]
# snippet-start:[python.example_code.rds.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.rds.DescribeOrderableDBInstanceOptions]
# snippet-start:[python.example_code.rds.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.rds.DescribeDBInstances]
# snippet-start:[python.example_code.rds.CreateDBInstance]
def create_db_instance (
2023-10-18 10:35:05 -07:00
self ,
db_name ,
instance_id ,
parameter_group_name ,
db_engine ,
db_engine_version ,
instance_class ,
storage_type ,
allocated_storage ,
admin_name ,
admin_password ,
) :
2022-09-19 16:19:51 -07:00
"""
Creates a DB instance.
2022-09-26 15:04:55 -07:00
:param db_name: The name of the database that is created in the DB instance.
:param instance_id: The ID to give the newly created DB instance.
:param parameter_group_name: A parameter group to associate with the DB instance.
:param db_engine: The database engine of a database to create in the DB instance.
2022-09-19 16:19:51 -07:00
:param db_engine_version: The engine version for the created database.
2022-09-26 15:04:55 -07:00
:param instance_class: The DB instance class for the newly created DB instance.
:param storage_type: The storage type of the DB instance.
:param allocated_storage: The amount of storage allocated on the DB instance, in GiBs.
2022-09-19 16:19:51 -07:00
:param admin_name: The name of the admin user for the created database.
:param admin_password: The admin password for the created database.
2022-09-26 15:04:55 -07:00
:return: Data about the newly created DB instance.
2022-09-19 16:19:51 -07:00
"""
try :
response = self . rds_client . create_db_instance (
DBName = db_name ,
DBInstanceIdentifier = instance_id ,
DBParameterGroupName = parameter_group_name ,
Engine = db_engine ,
EngineVersion = db_engine_version ,
DBInstanceClass = instance_class ,
StorageType = storage_type ,
AllocatedStorage = allocated_storage ,
MasterUsername = admin_name ,
2023-10-18 10:35:05 -07:00
MasterUserPassword = admin_password ,
)
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.rds.CreateDBInstance]
# snippet-start:[python.example_code.rds.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.rds.DeleteDBInstance]
2023-10-18 10:35:05 -07:00
2022-09-19 16:19:51 -07:00
# snippet-end:[python.example_code.rds.helper.InstanceWrapper_full]