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

}