3

依照指示操作,发现here,我创建了以下角色IAM如何使用CloudFormation将IAM角色与Aurora群集相关联?

"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" ] } 
      ] ] } } 
     ] 
    } 
} 

但是极光仍然是无法连接到S3,除非我手动通过控制台或使用CLI命令添加角色到DB-集群关联与集群的作用。

通过云形成文档进行挖掘不提供任何通过模板执行此操作的方法。 This documentation不提供任何允许角色关联的参数。

如何在不需要手动添加部署过程的情况下执行此操作?

+0

我认为你是正确的。您需要运行:aws rds add-role-to-db-cluster -db-cluster-identifier some-cluster-id -role-arn arn:aws:iam :: 1234567890:role/S3_ROLE – runamok

+0

有一件事I回想一下,您需要对S3 IAM策略持谨慎态度,因为资源的不同取决于您是否授予存储桶与对象的权限。 https://aws.amazon.com/blogs/security/writing-iam-policies-how-to-grant-access-to-an-amazon-s3-bucket/具体来说,你的代码应该以bucket arn/path/*结尾对于priv对象而言,只是以bucket arn结束。请注意上面链接中的细微差异。 – runamok

回答

3

这不是一个很好的解决方案,但我决定生成在输出中运行所需的命令。我将向亚马逊开放支持请求,以确认无法通过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群集设置就会集中在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"} 
     } 
    } 
} 

}