AWS:限制不同 IAM 用户可以将哪些 IAM 角色附加到 EC2 实例

AWS: Limit which IAM roles can be attached to an EC2 instance by different IAM users

我正在尝试弄清楚这是否可行。我有 2 个 IAM 用户。我希望每个人都能够 start/stop 同一个 EC2 实例,但每个 IAM 用户都能够将不同的 IAM 角色附加到这个 EC2 实例。换句话说,user1 应该 only 能够将 role1 附加到这个 ec2 实例,而 user2 应该 only 能够将 role2 附加到同一个 EC2实例。他们会在不同时间使用 ec2 实例。

我正在使用 aws ec2 associate-iam-instance-profile 命令将 IAM 配置文件附加到 EC2 实例,然后再启动它,然后在关闭它后分离该配置文件。我希望每个 IAM 用户只能将一个特定的 IAM 角色附加到这个 EC2 实例。

这可能吗?有什么想法或例子吗?谢谢!

两个用户的以下 IAM 策略应该足够了:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "ec2:AssociateIamInstanceProfile",
            "Resource": "<arn-of-the-instance>"
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": "iam:PassRole",
            "Resource": "arn:aws:iam::xxxx:role/<role-name>"
        }
    ]
}

以上只允许传递一个特定的角色和AssociateIamInstanceProfile到一个特定的实例。

但是,这不包括从实例中分离配置文件。

这是对我有用的解决方案(感谢 Marcin 在正确方向上的提示)。

  • 我有两个 IAM 用户:deploy-stagingdeploy-production
  • 我有一个 EC2 实例,可以部署到暂存环境或生产环境,具体取决于它承担的 IAM 角色。
  • deploy-staging IAM 用户附加了以下 IAM 策略。此策略将允许此用户 start/stop 用于将代码部署到 staging 的 EC2 实例和 attach/detach 正确的 IAM 角色 (deploy-role-staging)到那个 EC2 实例,这样它就可以拥有正确的权限来部署到暂存区。 这是此用户将能够附加到此 EC2 实例的唯一 IAM 角色
    {
      "Version": "2012-10-17",
      "Statement": [
          {
              "Sid": "VisualEditor0",
              "Effect": "Allow",
              "Action": [
                  "ec2:StartInstances",
                  "ec2:DisassociateIamInstanceProfile",
                  "ec2:ModifySecurityGroupRules",
                  "ec2:StopInstances",
                  "ec2:AssociateIamInstanceProfile",
                  "ec2:ReplaceIamInstanceProfileAssociation"
              ],
              "Resource": [
                  "arn:aws:ec2:*:account-id:security-group/sg-xxxxxxxxxxxxxx",
                  "arn:aws:ec2:us-east-1:account-id:instance/i-xxxxxxxxxxxxxx",
                  "arn:aws:ec2:*:account-id:security-group-rule/sgr-xxxxxxxxxxxxxx"
              ]
          },
          {
              "Sid": "VisualEditor1",
              "Effect": "Allow",
              "Action": [
                  "ec2:DescribeInstances",
                  "ec2:DescribeIamInstanceProfileAssociations"
              ],
              "Resource": "*"
          },
          {
              "Sid": "VisualEditor2",
              "Effect": "Allow",
              "Action": "iam:PassRole",
              "Resource": "arn:aws:iam::account-id:role/deploy-role-staging"
          }
      ]
    }
  • deploy-production IAM 用户附加了以下 IAM 策略。此策略将允许此用户 start/stop 用于将代码部署到 production 的 EC2 实例和 attach/detach 正确的 IAM 角色 (deploy-role-production)到该 EC2 实例,以便它可以具有部署到生产环境的正确权限。 这是此用户将能够附加到此 EC2 实例的唯一 IAM 角色
    {
      "Version": "2012-10-17",
      "Statement": [
          {
              "Sid": "VisualEditor0",
              "Effect": "Allow",
              "Action": [
                  "ec2:StartInstances",
                  "ec2:DisassociateIamInstanceProfile",
                  "ec2:ModifySecurityGroupRules",
                  "ec2:StopInstances",
                  "ec2:AssociateIamInstanceProfile",
                  "ec2:ReplaceIamInstanceProfileAssociation"
              ],
              "Resource": [
                  "arn:aws:ec2:*:account-id:security-group/sg-xxxxxxxxxxxxxx",
                  "arn:aws:ec2:us-east-1:account-id:instance/i-xxxxxxxxxxxxxx",
                  "arn:aws:ec2:*:account-id:security-group-rule/sgr-xxxxxxxxxxxxxx"
              ]
          },
          {
              "Sid": "VisualEditor1",
              "Effect": "Allow",
              "Action": [
                  "ec2:DescribeInstances",
                  "ec2:DescribeIamInstanceProfileAssociations"
              ],
              "Resource": "*"
          },
          {
              "Sid": "VisualEditor2",
              "Effect": "Allow",
              "Action": "iam:PassRole",
              "Resource": "arn:aws:iam::account-id:role/deploy-role-production"
          }
      ]
    }
  • deploy-role-staging IAM 角色附加了策略,允许它更新用于暂存的 S3 存储桶和用于暂存的 Cloudfront 分配。
    {
      "Version": "2012-10-17",
      "Statement": [
          {
              "Sid": "VisualEditor0",
              "Effect": "Allow",
              "Action": [
                  "cloudfront:GetInvalidation",
                  "cloudfront:CreateInvalidation"
              ],
              "Resource": [
                  "arn:aws:cloudfront::account-id:distribution/XXXXXXXXXXXXX"
              ]
          }
      ]
    }
    {
      "Version": "2012-10-17",
      "Statement": [
          {
              "Sid": "VisualEditor0",
              "Effect": "Allow",
              "Action": [
                  "s3:PutObject",
                  "s3:ListBucket",
                  "s3:DeleteObject",
                  "s3:PutObjectAcl"
              ],
              "Resource": [
                  "arn:aws:s3:::stagingXXX.example.com",
                  "arn:aws:s3:::stagingXXX.example.com/*"
              ]
          }
      ]
    }
  • deploy-role-production IAM 角色附加了策略,允许它更新用于生产的 S3 存储桶和用于生产的 Cloudfront 分发。
    They're the same as for staging, except the ID of Cloudfront distribution and the S3 bucket names are different.

总结:每个用户只能让 EC2 实例承担特定角色,从而使该 EC2 实例能够访问不同的资源。

不要忘记使用这些 CLI 命令示例(通过 /bin/bash):/bin/bash 将代码实际写入 start/stop EC2 实例,attach/detach IAM 角色

    # Get the current IAM role association for the EC2 instance.
    EC2_IAM_ROLE_ASSOCIATION_ID=`aws ec2 describe-iam-instance-profile-associations --filters Name=instance-id,Values=XXXXXXXXXXXX --query 'IamInstanceProfileAssociations[*].AssociationId' --output text --profile XXXX`

    # Only disassociate an IAM role if one is attached to the EC2 instance.
    if [ "$EC2_IAM_ROLE_ASSOCIATION_ID" ]; then
      # Disassociate any IAM role from the EC2 instance.
      aws ec2 disassociate-iam-instance-profile --association-id $EC2_IAM_ROLE_ASSOCIATION_ID --profile XXXX
    fi

    # Attach the correct IAM Role to the EC2 instance.
    EC2_IAM_ROLE_ASSOCIATION_ID=`aws ec2 associate-iam-instance-profile --instance-id XXXXXXXXXXXX --iam-instance-profile Name="$IAM_ROLE" --query 'IamInstanceProfileAssociation.AssociationId' --output text --profile XXXX`

    # Disassociate any IAM Role from the EC2 instance.
    aws ec2 disassociate-iam-instance-profile --association-id $EC2_IAM_ROLE_ASSOCIATION_ID --query 'IamInstanceProfileAssociation.State' --output text --profile XXXX