在控制台上创建只读副本时,可以使用多可用区部署。 AWS also announced last year只读副本支持MutliAZ
但是,当尝试在Cloudformation中复制它时,出现此错误
这是我Cloudformation中的摘录:
Resources:
MasterDB:
Type: AWS::RDS::DBInstance
Properties:
AllocatedStorage: 100
BackupRetentionPeriod: 10
DBInstanceClass: !Ref DBInstanceClass
Engine: postgres
EngineVersion: '10.6'
MasterUsername: !Ref DBUsername
MasterUserPassword: !Ref DBPassword
MultiAZ: false
PubliclyAccessible: true
ReplicaDB:
Type: AWS::RDS::DBInstance
Properties:
DBInstanceClass: !Ref DBInstanceClass
SourceDBInstanceIdentifier: !Ref MasterDB
MultiAZ: true
PubliclyAccessible: true
在documentation中,它指出:
将只读副本创建为多可用区数据库实例独立于 源数据库是否为多可用区数据库实例。
...因此MasterDB未设置为MultiAZ应该不是问题。
我的Cloudformation模板是否有错误?还是Cloudformation不支持MultiAZ for Read Replicas?
谢谢!
答案 0 :(得分:0)
我有同样的问题。我能够解决的唯一方法是在CloudFormation中使用自定义资源lambda。 lambda获取数据库实例的ID(在本例中为副本ID),然后使用boto3将其更改为Multi-Az副本。
这是lambda函数的模板:
# Create a python lambda function which
# can enable Multi-AZ for read replicas.
#
# This lambda is meant to be executed by custom resource
# from other template in CloudFormaton
---
Resources:
EnableMultiAz:
Type: AWS::Lambda::Function
Properties:
Description: Create an AMI of an instance
FunctionName: EnableMultiAzForDBInstance
Handler: index.lambda_handler
Role: !GetAtt LambdaExecutionRole.Arn
Runtime: python3.7
Timeout: 60
Code:
ZipFile: |
import json
import boto3
import logging
import time
from botocore.vendored import requests
logger = logging.getLogger()
logger.setLevel(logging.INFO)
SUCCESS = "SUCCESS"
FAILED = "FAILED"
# from https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-lambda-function-code-cfnresponsemodule.html
def send(event, context, responseStatus, responseData, physicalResourceId=None, noEcho=False):
responseUrl = event['ResponseURL']
print(responseUrl)
responseBody = {
'Status': responseStatus,
'Reason': 'See ' + context.log_stream_name,
'PhysicalResourceId': physicalResourceId or context.log_stream_name,
'StackId': event['StackId'],
'RequestId': event['RequestId'],
'LogicalResourceId': event['LogicalResourceId'],
'NoEcho': noEcho,
'Data': responseData
}
json_responseBody = json.dumps(responseBody)
print("Response body:\n" + json_responseBody)
headers = {
'content-type' : '',
'content-length' : str(len(json_responseBody))
}
try:
response = requests.put(responseUrl,
data=json_responseBody,
headers=headers)
print("Status code: " + response.reason)
except Exception as e:
print("send(..) failed executing requests.put(..): " + str(e))
def lambda_handler(event, context):
print('event: ', json.dumps(event))
try:
return_data = {}
if 'RequestType' in event:
rds = boto3.client('rds')
dbinstance_id = event['ResourceProperties']['DBinstanceId']
if event['RequestType'] == 'Create':
r = rds.modify_db_instance(
DBInstanceIdentifier=dbinstance_id,
MultiAZ=True, ApplyImmediately=True)
send(event, context, SUCCESS, return_data)
except Exception as e:
logger.error('custom response lambda failed due to: ' + str(e))
send(event, context, FAILED, {})
LambdaExecutionRole:
Type: AWS::IAM::Role
Properties:
RoleName: lambda-execution-role-with-rds
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal: {'Service': ['lambda.amazonaws.com']}
Action: ['sts:AssumeRole']
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AWSLambdaExecute
Path: '/'
Policies:
- PolicyName: PassRolePolicy
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Action: "iam:PassRole"
Resource: "*"
- PolicyName: EnableMultiAZReadReplica
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Action:
- "rds:ModifyDBInstance"
Resource: "*"
Outputs:
LambdaArn:
Value: !GetAtt EnableMultiAz.Arn
LambdaRoleArn:
Value: !GetAtt LambdaExecutionRole.Arn
您将此lambda模板放置在S3中,然后将其作为父模板:
# Define nested stack that creates the lambda
MyCustomLambdaToMakeMultiAzReplicas:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: "<url to lambda template in s3>"
TimeoutInMinutes: 1
# Define a custom resource using the lambda. Replica
# db instance id is passed to the lambda and the lambda is
# executed
EnableMultiAzForReplica:
Type: "Custom::CustomLambdaToMakeMultiAzReplicas"
Properties:
ServiceToken: !GetAtt MyCustomLambdaToMakeMultiAzReplicas.Outputs.LambdaArn
DBinstanceId: !Ref ReadReplicaDbInstanceId