amazon-web-services - CDK 中的高级权限处理:passRole、创建实例和传递多个权限
问题描述
我对 CDK 有一个非常讨厌的 IAM / 权限问题。我已经让它在控制台上工作了。这是一个分为两部分的问题,第一部分处理我已经完成的工作,第二部分研究如何在 CDK 中复制它。
现有解决方案
我有一个可以从多个来源触发的 Lambda 函数。每个源都提供了一些控制执行的参数。lambda 的主要任务是创建一个 EC2 实例并向其发送用户数据脚本以执行。虚拟机排队一个点实例以节省一些钱,当它完成时,它就会终止。这是一个相当庞大的虚拟机,因为它需要进行一些非常繁重的数据处理,但很少发生,因此我为什么不让它一直活着。
虚拟机本身需要 priveldeges 才能触发 SES 电子邮件,并访问 s3 存储桶进行读写。
权限
Lambda 在其角色中有 3 个策略文档:
- 基本执行。
- EC2 完全访问 AWS 托管策略。
- 自定义 Pass-Role 策略,如下:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "iam:PassRole",
"Resource": "arn:aws:iam::xxxxxxxxxxxxxxxxxxxx:role/EC2Role-Machine"
},
{
"Effect": "Allow",
"Action": [
"iam:CreateInstanceProfile",
"iam:AddRoleToInstanceProfile"
],
"Resource": "arn:aws:iam::xxxxxxxxxxxx:*"
}
]
}
pass-role 策略包含以下权限:
- 在我的帐户中创建“*”实例。
- 将角色添加到我帐户中的“*”实例。
- 传递角色(EC2-Custom-Role)
EC2 自定义角色
此 EC2 自定义角色包含 2 个策略
- SES 完全访问权限
- s3 对 4 个单独的存储桶资源的大约 8 个不同操作“s3:xxxxx”的访问。见下文。NB "s3:*" 在事情无法正常工作的情况下,在虚弱的时刻悄悄进入 - 需要一些令人头疼的问题来解释为什么这是必要的。
{
"Version":"2012-10-17",
"Statement":[
{
"Sid":"VisualEditor0",
"Effect":"Allow",
"Action":[
"s3:GetAccessPoint",
"s3:PutAccountPublicAccessBlock",
"s3:GetAccountPublicAccessBlock",
"s3:ListAllMyBuckets",
"s3:ListAccessPoints",
"s3:ListJobs",
"s3:CreateJob"
],
"Resource":"*"
},
{
"Sid":"VisualEditor1",
"Effect":"Allow",
"Action":[
"s3:*",
"s3:ListObjectsV2"
],
"Resource":[
"arn:aws:s3:::monkey.test.bucket/*",
"arn:aws:s3:::reports.monkeytronics.co.nz/*",
"arn:aws:s3:::analytics.monkeytronics.co.nz/*",
"arn:aws:s3:::analytics.monkeytronics.co.nz"
]
}
]
}
问题 1
虽然这有效......对吗?是否应该进行任何安全性或最佳实践改进?
问题2
这如何在 CDK 中复制。我已经开始研究它,但很快就碰壁了。触发 lambda 时出现错误。Lambda 的主要内容如下。基本上,它只是启动一个新的 EC2 实例并输入用户数据。完成后,EC2 终止。安全组、角色和密钥都已准备好,我知道它们从以前开始就可以正常工作。
// my custom AMI
var instanceParams = {
ImageId: 'ami-0dfxxxxxxxxxxxe',
InstanceType: 't2.xlarge',
KeyName: 'EC2-Test-Key-Pair',
MinCount: 1,
MaxCount: 1,
SecurityGroups: ['launch-wizard-1'],
UserData: userDataEncoded,
InstanceInitiatedShutdownBehavior: "terminate",
// InstanceMarketOptions: {
// "MarketType" : "spot",
// //"SpotOptions" : SpotOptions // max price / block period etc...
// },
IamInstanceProfile : {
"Arn" : "arn:aws:iam::xxxxxxxxxxx:instance-profile/EC2Role-R-Machine"
}
};
// Create a promise on an EC2 service object
var instancePromise = new AWS.EC2({apiVersion: '2016-11-15'}).runInstances(instanceParams).promise();
// Handle promise's fulfilled/rejected states
await instancePromise.then(
function(data) {
console.log(data);
var instanceId = data.Instances[0].InstanceId;
console.log("Created instance", instanceId);
}
);
这是来自 cloudwatch 的错误消息。恐怕不是很有帮助,但足以说明它在权限中。尽管已经在控制台中成功实现了这一点,但我不能说我真的牢牢掌握了这里使用 pass 角色和其他权限概念。
"errorType": "UnauthorizedOperation", "errorMessage": "您无权执行此操作。编码授权失败消息:OhVTfR8eBb7y.....
PS 感谢您整理出我乱七八糟的代码格式!
解决方案
问题 2 的答案如下所示:
对于动态 EC2 对象:
// create ec2 role & add policies.
const ec2RoleR = new iam.Role(this, 'ec2RoleR', {
assumedBy: new iam.ServicePrincipal('ec2.amazonaws.com'),
description: 'EC2 Role - SES & s3 access.',
roleName: 'sn-v1-EC2-Role-R'
});
ec2RoleR.addToPolicy(new iam.PolicyStatement({
resources: [
s3Reports.bucketArn,
s3Analytics.bucketArn
],
actions: [
's3:GetAccessPoint',
's3:PutAccountPublicAccessBlock',
's3:GetAccountPublicAccessBlock',
's3:ListAllMyBuckets',
's3:ListAccessPoints',
's3:ListJobs',
's3:CreateJob'
],
}));
ec2RoleR.addManagedPolicy(iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonSESFullAccess'));
对于 Lambda:
// Add necessary policies to Lambda
lambdaReportPutR.addToRolePolicy(new iam.PolicyStatement({ // needs SES & iotPublish permissions!
effect: Effect.ALLOW,
resources: [
"arn:aws:iam::xxxxxxxxx:role/EC2Role-R-Machine", // console role.
ec2RoleR.roleArn // cdk role above
],
actions: ['iam:PassRole'],
}));
// create & add role to * instance
lambdaReportPutR.addToRolePolicy(new iam.PolicyStatement({
effect: iam.Effect.ALLOW,
resources: ['arn:aws:iam::xxxxxxxxx:*'],
actions: [
"iam:CreateInstanceProfile",
"iam:AddRoleToInstanceProfile"
]
}));
// ec2 full access by lambda.
lambdaReportPutR.role?.addManagedPolicy(iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonEC2FullAccess'));
推荐阅读
- ms-access - 最小化访问应用程序,然后最大化它并将焦点重新设置为访问应用程序
- linux - 如何在 bash shell 脚本中添加另一个“for”循环?
- c# - EF将列表属性映射到不同表中的单个列
- html - 属性顺序重要吗?
- php - MAMP 不启动
- sql - MS SQL:连接三个表并仅从数值计算平均值
- javascript - 刷新网络浏览器时Firebase数据不起作用
- ios - 我正在尝试从我的 ios Swift 项目中的 Firestore 数据库中获取数据
- python - Seaborn:如何使用 PairGrid 获取 distplot 的 y 轴计数
- javascript - Onchange sessionStorage.clear() 不工作