有没有办法跨用户和 EC2 实例角色重用 AWS IAM 权限策略?

Is there a way to reuse AWS IAM permissions policy across users and EC2 instance roles?

我开始使用 AWS IAM instance roles,这对于提升我们的安全管理水平非常有用,但它增加了维护轻量级开发流程的一些挑战。

手头的问题是:

到目前为止,我想出的最好的办法可能是将政策文件存储在磁盘上,在版本控制下,并编写一个使用 aws api 的工具将政策文件上传到两者实例角色和组。这有点麻烦,所以我希望能更灵活一点。

你有更好的建议给我吗?...谢谢!

更新

AWS 刚刚推出 Managed Policies for AWS Identity & Access Management,它提供了一种跨 IAM 实体共享和维护 IAM 策略的全新方法,专门用于减少当前的信息和工作重复:

As the size and complexity of your AWS installation grows, you might find yourself editing multiple permission documents in order to add a new permission or to remove an existing one. Auditing and confirming permissions was also more difficult than necessary.

安全博客 post An Easier Way to Manage Your Policies 提供了更多详细信息。


初始答案

So far the best thing I came up with is perhaps to store the policy documents on disk, under version control, and write a tool that uses the aws api to upload the policy document to the both the instance role and the group. It's somewhat cumbersome so I was hoping for a little more agility.

这样的工具已经存在,实际上是许多 AWS 自己和第三方服务的主要支持技术 - 看看 AWS CloudFormation,它 为开发人员和系统提供管理员可以轻松创建和管理相关 AWS 资源的集合,以有序且可预测的方式配置和更新它们

更具体地说,AWS::IAM::Policy 资源 将 IAM 策略与 IAM 用户、角色或组相关联

{
   "Type": "AWS::IAM::Policy",
   "Properties": {
      "Groups" : [ String, ... ],
      "PolicyDocument" : JSON,
      "PolicyName" : String,
      "Roles" : [ String, ...
      "Users" : [ String, ... ],
   }
}

CloudFormation 当然还有更多功能,它是一个非常强大的工具(参见 Getting Started with AWS CloudFormation)。

感谢@Steffen 指出 CloudFormation,但我想我找到了一个更适合我的解决方案。
AWS 提供 Security Token Service,简而言之,它允许您 担任角色
这正是我一直在寻找的,因为我想定义一个角色一次(例如一组 AWS 权限),然后让 AWS EC2 实例自动承担这个角色(很容易做到)以及开发人员承担特定服务的角色他们正在发展。开发人员部分涉及更多,但我将在下面粘贴一些 Java 代码来说明如何执行此操作。

首先,在定义角色时,您必须说明允许哪些 负责人 担任此角色。为此,您可以编辑角色的 Trust Relationships 部分(位于 AWS 网站上角色定义页面的底部 UI)

例如,这里有一个信任关系文档,它允许 EC2 实例以及我域中的一些用户(替换 your-service-id-numberyour-user@example.com)承担这个角色:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::your-service-id-number:user/your-user@example.com",
        "Service": "ec2.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

然后 Java 在本地开发中 运行 承担此角色的代码:

此代码检查我是否在 EC2 实例上 运行,如果是,将承担实例的角色(否则,DefaultAWSCredentialsProviderChain 定义的任何内容,但在我的情况下,最佳实践是 - EC2 实例角色)。如果 运行 在开发环境中,例如在 EC2 之外然后它承担由 roleName

提供的角色
AWSCredentialsProvider getCredentialsProvider(String roleName) {
    if (isRunningOnEc2()) {
        return new DefaultAWSCredentialsProviderChain();
    }

    // If not running on EC2, then assume the role provided
    final AWSCredentials longLivedCredentialsProvider = new DefaultAWSCredentialsProviderChain().getCredentials(); // user credentials provided by env variables for ex.
    // The String roleArn is defined at the top of the Role page titled "Role ARN" ;-)
    final String roleArn = String.format("arn:aws:iam::your-service-id-number:role/%s", roleName);
    final String roleSessionName = "session" + Math.random(); // not sure it's really needed but what the heck..
    final STSAssumeRoleSessionCredentialsProvider credentialsProvider =
            new STSAssumeRoleSessionCredentialsProvider(longLivedCredentialsProvider, roleArn, roleSessionName);
    return credentialsProvider;
}

实用程序 isRunningOnEc2() 已提供:

public static boolean isRunningOnEc2() {
    try {
        final InetAddress byName = InetAddress.getByName("instance-data");
        return byName != null;
    } catch (final UnknownHostException e) {
        return false;
    }
}

按照 Steffen 的建议使用 CloudFormation,在一般意义上也可能有用,主要是为了保持一致性 b/w 我的代码库和实际的 AWS 部署,但那是另外一回事。

但有一个烦人的地方:可以将主体定义为实际用户名而不是用户组,因此您实际上不能这么说 "all developers are allowed to assume role x",而是必须具体列出每个开发人员。这很烦人,但我猜 I'm not the only one with this complaint