按照here发现的说明,我创建了以下IAM角色
"DatabaseS3Role": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": ["rds.amazonaws.com"]
},
"Action": "sts:AssumeRole"
}
]
},
"Policies": [
{
"PolicyName": "AllowAuroraToReadS3",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:GetObjectVersion", "s3:ListBucket"],
"Resource": {"Fn::Join": ["", [
"arn:aws:s3:::",
{"Fn::Join": ["-",[
{"Ref": "ClientName"},
{"Ref": "SourceBucketName"},
{"Ref": "EnvironmentType"},
{ "Fn::FindInMap" : [ "Regions", { "Ref" : "AWS::Region" }, "Name" ] }
]]} ,
"*"
]]}
}
]
}
}
]
}
}
我可以将它添加到群集参数组并使用以下内容关联它。
"RDSDBClusterParameterGroup" : {
"DependsOn": "DatabaseS3Role",
"Type": "AWS::RDS::DBClusterParameterGroup",
"Properties" : {
"Description" : "CloudFormation Aurora Cluster Parameter Group",
"Family" : "aurora5.6",
"Parameters" : {
"time_zone" : "US/Eastern",
"aws_default_s3_role": {"Fn::GetAtt": ["DatabaseS3Role", "Arn"]}
}
}
},
"RDSAuroraCluster" : {
"Type" : "AWS::RDS::DBCluster",
"Properties" : {
"MasterUsername" : { "Ref" : "Username" },
"MasterUserPassword" : { "Ref" : "Password" },
"Engine" : "aurora",
"DBSubnetGroupName" : { "Ref" : "RDSSubnetGroup" },
"DBClusterParameterGroupName" : { "Ref" : "RDSDBClusterParameterGroup" },
"VpcSecurityGroupIds" : [ { "Ref" : "SecurityGroupId" } ],
"Tags" : [
{ "Key" : "Name", "Value" : { "Fn::Join" : [ "-", [
{ "Ref" : "ClientName" },
"aurclstr001",
{"Ref" : "EnvironmentType" },
{ "Fn::FindInMap" : [ "Regions", { "Ref" : "AWS::Region" }, "Name" ] }
] ] } }
]
}
}
但是,除非我通过控制台或cli命令add-role-to-db-cluster手动将角色与群集关联,否则Aurora仍然无法连接到S3。
挖掘云形成文档并未提供通过模板执行此操作的任何方法。 This documentation未提供允许角色关联的任何参数。
如何在不必为部署过程添加手动步骤的情况下执行此操作?
答案 0 :(得分:5)
它不是一个很好的解决方案,但我决定生成在输出中运行所需的命令。我将向亚马逊开放支持请求,以确认无法通过DSL向群集添加角色。
当我运行aws rds describe-db-clusters
时,我看到" AssociatedRoles"的条目它包含一个具有Status和RoleArn的对象数组。
PostRunCommand:
Description: You must run this awscli command after the stack is created and may also need to reboot the cluster/instance.
Value: !Join [" ", [
"aws rds add-role-to-db-cluster --db-cluster-identifier",
!Ref AuroraSandboxCluster,
"--role-arn",
!GetAtt AuroraS3Role.Arn,
"--profile",
!FindInMap [ AccountNameMap, !Ref AccountNamespace, profile ]
]]
你很可能不会需要最后一部分WRT资料......
亚马逊回应我之后的后续行动。他们说:
我了解到您正在寻找一种方法将IAM角色与Cloudformation中的Aurora群集相关联,以代表您访问其他AWS服务。
正确地说,RDS群集资源没有角色属性,因为CloudFormation尚不支持它。已经有一个已经打开的功能请求,因为它是一个非常常见的问题,我已经添加了你的声音,以增加功能的重量。 像往常一样,我无法为您提供ETA,但是一旦发布,它应该发布在Cloudformation发布历史页面中:
http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/ReleaseHistory.html
但是,您可以创建一个CFN模板来创建RDS Aurora设置,并在模板的末尾创建一个自定义资源[1],作为Lambda函数,它进行API调用以将IAM角色附加到RDS集群,这样整个RDS Aurora Cluster设置就可以集中在CFN模板中,无需手动操作,集群也可以调用Lambda函数。
请附上一个"示例"上述解决方法的模板。
我还将代表您发送有关创建角色以向AWS服务委派权限所需的示例中缺少主要属性的反馈。
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "AWS Cloud resources for DevTools services.",
"Metadata": {
"Version": "0.2.0"
},
"Parameters": {
"RDSPassword": {
"Description": "Password for root user on the RDS instance.",
"Type": "String",
"NoEcho":"true"
},
"RDSDatabaseName": {
"Description": "DB Identifier for RDS instance.",
"Type": "String",
"Default": "mydbname"
},
"RDSClass": {
"Description": "RDS Instance Class",
"Type": "String",
"Default": "db.r3.xlarge"
},
"DBIdentifier": {
"Description": "Database Instance Identifier",
"Type": "String"
},
"DBSubnetGroupName": {
"Description": " The Subnet group Group for the RDS instance",
"Type": "String"
},
"RDSSecurityGroupId": {
"Description": "Existing internal SG for RDS instance access",
"Type": "AWS::EC2::SecurityGroup::Id"
},
"RDSRetention": {
"Description": "How long to retain RDS snapshots",
"Type": "String"
},
"RDSVpcId": {
"Description": "VpcId for RDS instance",
"Type": "AWS::EC2::VPC::Id"
},
"PubliclyAccessible": {
"Description": "Set the RDS to be publically available",
"Type": "String",
"AllowedValues" : ["true", "false"],
"Default": "true"
},
"DBClusterIdentifier": {
"Description": "The name of the DBCluster",
"Type": "String"
},
"RDSRoleTag": {
"Description": "sets if the tag for dev/prod use",
"Type": "String",
"Default": "dev"
}
},
"Resources": {
"LambdaRole" : {
"Type" : "AWS::IAM::Role",
"Properties" : {
"AssumeRolePolicyDocument" : {
"Version" : "2012-10-17",
"Statement" : [
{
"Effect" : "Allow",
"Principal" : {
"Service" : [
"lambda.amazonaws.com"
]
},
"Action" : [
"sts:AssumeRole"
]
}
]
}
}
},
"LambdaPolicy": {
"Type" : "AWS::IAM::Policy",
"Properties" : {
"PolicyName" : "LambdaPolicy",
"PolicyDocument" : {
"Version" : "2012-10-17",
"Statement": [ {
"Effect" : "Allow",
"Action" : [
"iam:*",
"ec2:*",
"rds:*",
"logs:*"
],
"Resource" : "*"
} ]
},
"Roles": [ { "Ref": "LambdaRole" } ]
}
},
"LambdaFunction": {
"Type" : "AWS::Lambda::Function",
"DeletionPolicy" : "Delete",
"DependsOn" : [
"LambdaRole"
],
"Properties" : {
"Code" : {
"ZipFile" : {
"Fn::Join" : [
"\n",
[
" var AWS = require('aws-sdk');",
" var rds = new AWS.RDS();",
" var response = require('cfn-response');",
" exports.handler = (event, context, callback) => {",
" var rolearn = event.ResourceProperties.RDSRole;",
" var dbclusteridentifier = event.ResourceProperties.DBClusterIdentifier;",
" var responseData = {};",
" console.log('Role ARN: ' + rolearn);",
" console.log('DBClusterIdentifier: ' + dbclusteridentifier);",
" var addroleparams = {",
" RoleArn: rolearn,",
" DBClusterIdentifier: dbclusteridentifier",
" };",
" if (event.RequestType == 'Delete') {",
" response.send(event, context, response.SUCCESS);",
" return;",
" }",
" rds.addRoleToDBCluster(addroleparams, function(err, data) {",
" if (err) {",
" console.log(err, err.stack); // an error occurred",
" responseData = {Error: 'Create call failed'};",
" response.send(event, context, response.FAILED, responseData);",
" }",
" else {",
" response.send(event, context, response.SUCCESS, responseData);",
" console.log(data); // successful response",
" }",
" });",
" };",
]
]
}
},
"Handler" : "index.handler",
"MemorySize" : 128,
"Role" : {
"Fn::GetAtt" : [
"LambdaRole",
"Arn"
]
},
"Runtime" : "nodejs4.3",
"Timeout" : 10
}
},
"RDSRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": ["rds.amazonaws.com"]
},
"Action": ["sts:AssumeRole"]
}
]
},
"Path": "/"
}
},
"RDSPolicy": {
"Type" : "AWS::IAM::Policy",
"Properties" : {
"PolicyName" : "RDSPolicy",
"PolicyDocument" : {
"Version" : "2012-10-17",
"Statement": [ {
"Effect" : "Allow",
"Action" : [
"lambda:InvokeFunction"
],
"Resource" : "*"
} ]
},
"Roles": [ { "Ref": "RDSRole" } ]
}
},
"RDSDBClusterParameterGroup" : {
"Type" : "AWS::RDS::DBClusterParameterGroup",
"Properties" : {
"Parameters" : {
"aws_default_lambda_role" : { "Fn::GetAtt" : [ "LambdaFunction", "Arn" ] }
},
"Family" : "aurora5.6",
"Description" : "A sample parameter group"
}
},
"RDSDBCluster": {
"Type" : "AWS::RDS::DBCluster",
"DeletionPolicy": "Retain",
"Properties" : {
"BackupRetentionPeriod" : { "Ref": "RDSRetention" },
"DatabaseName": { "Ref": "RDSDatabaseName" },
"DBSubnetGroupName": { "Ref": "DBSubnetGroupName" },
"DBClusterParameterGroupName": { "Ref" : "RDSDBClusterParameterGroup" },
"Engine" : "aurora",
"StorageEncrypted" : true,
"MasterUsername" : "sa",
"MasterUserPassword" : { "Ref": "RDSPassword" },
"Port" : 3306,
"Tags": [
{ "Key": "Role", "Value": { "Ref": "RDSRoleTag" } }
],
"VpcSecurityGroupIds": [{ "Ref": "RDSSecurityGroupId" } ]
}
},
"RDSInstance": {
"Type": "AWS::RDS::DBInstance",
"DeletionPolicy": "Retain",
"Properties": {
"AllowMajorVersionUpgrade": false,
"AutoMinorVersionUpgrade": true,
"DBClusterIdentifier" : { "Ref": "RDSDBCluster" },
"DBInstanceIdentifier": { "Ref": "DBIdentifier" },
"DBInstanceClass": { "Ref": "RDSClass" },
"Engine": "aurora",
"PubliclyAccessible": { "Ref": "PubliclyAccessible" },
"Tags": [
{ "Key": "Role", "Value": { "Ref": "RDSRoleTag" } }
]
}
},
"RDSInstanceSecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"DeletionPolicy": "Retain",
"Properties": {
"GroupDescription": "Security group for the RDSInstance resource",
"SecurityGroupEgress": [
{
"IpProtocol": "tcp",
"CidrIp": "127.0.0.1/32",
"FromPort": "1",
"ToPort": "1"
}
],
"SecurityGroupIngress": [
{
"IpProtocol": "tcp",
"SourceSecurityGroupId": { "Ref": "RDSSecurityGroupId" },
"FromPort": "3306",
"ToPort": "3306"
}
],
"VpcId": { "Ref": "RDSVpcId" },
"Tags": [
{ "Key": "Role", "Value": { "Ref": "RDSRoleTag" } }
]
}
},
"AddRoleToDBCluster": {
"DependsOn" : [
"RDSDBCluster",
"RDSInstance"
],
"Type": "Custom::AddRoleToDBCluster",
"Properties" : {
"ServiceToken" : {
"Fn::GetAtt" : [
"LambdaFunction",
"Arn"
]
},
"RDSRole" : { "Fn::GetAtt" : [ "RDSRole", "Arn" ] },
"DBClusterIdentifier" : {"Ref":"RDSDBCluster"}
}
}
}
}