在 AWS 中设置我的组织时,我遇到了一个问题。我们计划使用 AWS Organizations 将不同的部门(开发、运营、IT、项目)划分到不同的 AWS 账户中,并使用 AWS SSO 来管理跨账户访问。在某些部门(开发、项目)中
我希望一些用户能够创建自己的 IAM 用户(称为“功能用户”)以用于编程访问。这些功能用户不应有权自己创建用户,也不应设置更新任何访问密钥。此外,这些用户(或其访问密钥)应仅在有限的时间内有效。这个想法是,如果员工离开公司,则创建的功能用户仅在有限的时间内有效(如果在停用员工用户时未找到)。
我计划通过每天调用一次 lambda 函数来实现时间限制,以停用所有超过给定时间的功能用户的访问密钥。
我的问题是设置所创建用户的权限限制。我创建了一个 SSO 权限集(映射到每个帐户中的角色),其中附加了 AWS 托管策略“IAMReadOnlyAccess”。此外,它还具有以下内联策略:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "CreateUsersWithTag",
"Effect": "Allow",
"Action": [
"iam:CreateUser",
"iam:DeleteUserPolicy",
"iam:AttachUserPolicy",
"iam:DetachUserPolicy",
"iam:PutUserPermissionsBoundary"
],
"Resource": "*",
"Condition": {
"StringEquals": {
"aws:RequestTag/Owner": "${aws:username}",
"iam:PermissionsBoundary": "arn:aws:iam::12356789012:policy/FunctionUserBoundary"
}
}
}
]
}
通过此策略,我尝试强制所有创建的用户都具有与创建用户相同的标签(以识别功能用户并允许该用户更新访问密钥)。我还尝试强制新创建的用户执行 IAM 策略,即deny
功能用户的任何 IAM 访问权限。
我的问题是该策略的 ARN。它位于组织的主帐户中。因此,用户在创建用户时无法在子帐户中引用它。
有没有办法允许子账户访问另一个账户的 IAM 策略?另一个选择是编写一个在创建账户时触发的 Lambda 函数,该函数在每个新账户中创建 FunctionUserBoundary 策略并将值更改iam:PermissionsBoundary
为arn:aws:iam::*:policy/FunctionUserBoundary
,但当我稍后更改策略时,不同账户中的策略版本将不同。
有没有办法实现我的计划,或者我的计划从根本上就是错误的?
答案1
我使用了MLu 的回答:
我创建了一个 CloudFormation StackSet,它可以执行所有策略,并且每次创建新帐户以将其添加到 StackSet 时都会调用一个自定义 lambda 函数。
这是我做的:
- 首先创建一个名为的自定义策略,
OrganizationAdministrator
其策略文档如下:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::*:role/OrganizationAccountAccessRole"
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": [
"organizations:ListAccounts",
"organizations:DescribeOrganization"
],
"Resource": "*"
}
]
}
AWSCloudFormationStackSetAdministrationRole
如果不存在此策略,则将其添加到创建策略中。使用以下属性创建一个新的 CloudFormation StackSet:
AccountInitalization
作为名称- 包含所有个人资料的模板
OrganizationAccountAccessRole
作为执行角色。组织在创建新帐户时会自动生成此角色。AWSCloudFormationStackSetAdministrationRole
作为管理员角色- 添加所有现有帐户
InitiateAccounts
使用以下代码创建一个新的 Lambda 函数:
require 'json'
def lambda_handler(event:, context:)
require 'aws-sdk-organizations'
require 'aws-sdk-cloudformation'
#First get the accounts already in the stackset
cloudformation = Aws::CloudFormation::Client.new(region: 'eu-central-1')
resp = cloudformation.list_stack_instances({ stack_set_name: 'AccountInitalization',})
stack_set_accounts = []
resp[:summaries].each do |summary|
stack_set_accounts << summary.account
end
#Iterate over existing accounts and collect accounts to add
organizations = Aws::Organizations::Client.new(region: 'us-east-1')
accounts = organizations.list_accounts({})
orga = organizations.describe_organization({})
add_accounts = []
accounts[:accounts].each do |account|
#First assume role in Account
next if account.arn == orga[:organization].master_account_arn
next if account.status == 'SUSPENDED'
add_accounts << account.id if ! stack_set_accounts.include?(account.id)
end
if add_accounts.any? then
cloudformation.create_stack_instances({
stack_set_name: "AccountInitalization",
accounts: add_accounts,
regions: ['eu-central-1'],
})
end
#return added accounts
add_accounts
end
OrganizationsCreateAccount
使用 Lambda 函数作为订阅者创建 SNS 主题创建以 SNS 主题为目标的 Cloudwatch 事件规则
OrganizationsCreateAccount
以及以下事件模式:
{
"source": [
"aws.organizations"
],
"detail-type": [
"AWS API Call via CloudTrail"
],
"detail": {
"eventSource": [
"organizations.amazonaws.com"
],
"eventName": [
"CreateAccount"
]
}
}
答案2
我认为您无法从子帐户引用主帐户中的 IAM 策略。您必须FunctionUserBoundary
在每个子帐户中创建该策略。
然而,这应该使用一些自动化工具(例如 CloudFormation、Ansible 或某些 CI/CD),并且每当您更新中央存储库中的主策略文件时,它都应自动重新部署/传播到您的所有组织帐户。
希望有帮助:)