3

suivant les instructions here, j'ai créé l'AIM en mesure RôleComment associer un rôle IAM à un cluster Aurora à l'aide de CloudFormation?

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

suivant, je dois l'ajouter à un groupe de paramètres de cluster et de l'associer à l'aide de ce qui suit.

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

Cependant Aurora est toujours pas en mesure de se connecter à S3 à moins que j'associer manuellement un rôle avec le cluster via la console ou avec la commande cli add-rôle à db-cluster. La recherche dans la documentation sur la formation au cloud ne fournit aucun moyen de le faire via le modèle. This documentation ne fournit aucun paramètre permettant d'associer un rôle.

Comment faire ceci sans avoir à ajouter manuellement une étape au processus de déploiement?

+0

Je pense que vous avez raison.Vous auriez besoin d'exécuter: aws rds add-rôle-à-db-cluster --db-cluster-identifiant un-cluster-id --role-arn arn: aws: iam :: 1234567890: rôle/S3_ROLE – runamok

+0

Une chose que je rappelez-vous que vous devez être prudent avec les stratégies SAM IAM car les ressources diffèrent selon que vous accordez un privilège sur un compartiment ou sur un objet. https://aws.amazon.com/blogs/security/writing-iam-policies-how-to-grant-access-to-an-amazon-s3-bucket/ Plus précisément votre code devrait se terminer par bucket arn/path/* pour les privs de l'objet, mais se terminent simplement par arn de seau pour les privs du bucket. Notez la différence subtile dans le lien ci-dessus. – runamok

Répondre

3

Ce n'est pas une bonne solution mais j'ai décidé de générer la commande nécessaire pour l'exécution dans la sortie. J'ouvrirai une demande de support avec Amazon pour confirmer qu'il n'y a aucun moyen d'ajouter un rôle au cluster via la DSL.

Lorsque j'exécute aws rds describe-db-clusters, je vois une entrée pour "AssociatedRoles" qui contient un tableau d'objets avec un Status et 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 ] 
    ]] 

Vous aurez probablement pas besoin de la dernière partie de profil ... WRT

Un suivi après Amazon m'a répondu. Ils ont dit:

Je comprends que vous cherchiez un moyen d'associer un rôle IAM à un cluster Aurora dans Cloudformation pour accéder à d'autres services AWS en votre nom.

Comme vous l'avez indiqué correctement, il n'y a pas de propriété de rôle pour une ressource de cluster RDS car CloudFormation ne la prend pas encore en charge. Il y a une demande de fonctionnalité déjà ouverte pour cela car c'est un problème très courant et j'ai ajouté votre voix pour ajouter la fonctionnalité avec encore plus de poids. Comme d'habitude, je ne peux pas vous donner une ETA, mais dès qu'il est libéré, il devrait être publié dans la page historique des versions CloudFormation:

http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/ReleaseHistory.html

Cependant, vous pouvez créer un modèle CFN qui crée un Configuration RDS Aurora et à la fin du modèle une ressource personnalisée [1], en tant que fonction Lambda, qui effectue un appel API pour attacher le rôle IAM au cluster RDS, de cette façon toute l'installation RDS Aurora Cluster reste centralisée dans le CFN Modèle sans actions manuelles et le cluster pourra invoquer la fonction Lambda.

Veuillez trouver ci-joint un modèle «exemple» de cette solution de contournement décrite ci-dessus.

Je vais également envoyer un commentaire en votre nom sur l'absence de la propriété principale dans les exemples qui est nécessaire pour créer un rôle pour déléguer des autorisations à un service 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"} 
     } 
    } 
} 

}