9

按照此处找到的说明,我创建了以下 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。

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

如何在无需在部署过程中添加手动步骤的情况下执行此操作?

4

1 回答 1

9

截至2019 年 8 月 29 日,这终于得到支持!

有一个名为AssociatedRoles的新属性采用DBClusterRoles数组。这些基本上是一个具有 RoleArn 和一个可选 FeatureName 的对象,根据这个显示SupportedFeatureNames.member.N的参考,目前只能是 s3Import 。

2017-06-30 的原始答案:

这不是一个很好的解决方案,但我决定生成在输出中运行所需的命令。我将向 Amazon 提出支持请求,以确认无法通过 DSL 向集群添加角色。

当我运行时,aws rds describe-db-clusters我看到一个“AssociatedRoles”条目,其中包含一组具有状态和 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"}
        }
    }
}

}

于 2017-06-27T23:57:26.997 回答