共计 4169 个字符,预计需要花费 11 分钟才能阅读完成。
什么是运维编排服务?
阿里云运维编排服务(Operation Orchestration Service,简称 OOS)是云上的自动化运维平台,提供运维任务的管理和执行。典型使用场景包括:事件驱动运维,批量操作运维,定时运维任务,跨地域运维等,OOS 为重要运维场景提供审批,通知等功能。OOS 帮用户实现标准化运维任务,从而实践运维即代码(Operations as Code)的先进理念。OOS 支持跨产品使用,用户可以使用 OOS 管理 ECS、RDS、SLB、VPC 等云产品。
用大白话讲,就是阿里云的用户编写一个包含运维逻辑的模板,提交给 OOS,然后 OOS 在云端,以用户的身份执行这个模板里面的运维逻辑。
阿里云 OOS 的公共模板已经开源在 github
更多的信息请参考之前的文章 阿里云重磅发布云上自动化利器——运维编排 OOS
或参考运维编排官方帮助文档
权限相关的三个基本概念:用户,授权策略,角色
先说用户,用户就是账号,这个概念很好理解。用户分为两类:主账号和子账号。
阿里云上的用户在最开始使用阿里云服务的时候,都会注册一个云账号,这个注册生成的账号就叫做主账号,可以理解为 root 账号,拥有最高的权限。
接下来,拥有主账号的用户如果想要创建子账号,就需要开通一个叫做 RAM (Resource Access Management) 的云产品。开通 RAM 之后,就可以在 RAM 控制台上,创建子账户。创建子账户的目的,是为了限制子账户的权限,避免 root 账户被滥用和泄露的风险。
那么,子账户的权限如何限制呢?这儿就要先引入授权策略的概念。授权策略表示一组权限的集合,比如针对 ECS 的创建销毁启停的权限集合。授权策略也分两类,一类是阿里云内置的系统授权策略,另一类是用户自定义的授权策略。OOS 服务默认包含了两个系统授权策略,一个叫做 OOSFullAccess,相当于拥有了 OOS 这个服务的全部权限,另一个叫做 OOSReadOnlyAccess,相当于只能读取 OOS 的模板和历史执行的数据,不能做修改模板也不能启动执行。
账号和授权策略之间,是多对多的关系。主账户或者管理员,可以决定,每一个子账号拥有哪些权限策略。比如,给 user1 分配 OOSFullAccess 权限策略,而给 user2 分配 OOSReadOnlyAccess 权限策略。
那么,什么是角色(Role)呢?角色是一种虚拟的用户,它不对应任何可以控制台登录的账户,但主账号或管理员可以创建 Role 并给 Role 像普通用户一样赋予授权策略。那么谁来使用这些虚拟用户(Role)呢?典型的使用场景就是云产品。主账户或者管理员,可以为角色配置“信任关系”,也就是可以决定哪些云产品能够使用这些虚拟账户。
权限问题 1:Assume Role
OOS 的核心功能,是要按照用户的身份去执行用户提前编写好的模板。这里面就涉及到了一个基本问题:OOS 作为一个云产品,用什么样的身份去执行用户编写的模板呢?
如果单从简单实现的角度,而不考虑安全,那么阿里云直接给 OOS 赋予一个超级权限就可以了,反正是“自家”产品。这样做可以吗?我们认为不可以。用户需要有能力对 OOS 进行限制,需要可以决定 OOS 可以操作哪些资源,不可以操作哪些资源。也就是说,OOS 在执行用户的模板的时候,一定是“扮演”了某个用户可控的身份。
相信聪明的读者已经想到了,这里用到了前面介绍的角色(Role),以及 Assume Role 这个功能。Assume Role,就是云产品,扮演用户的某个角色。用户,需要进行两个操作步骤:第一步,就是创建一个角色(Role),并且信任运维编排服务,如下图所示:
第二步,就是给这个角色赋予权限策略,用户如果希望 OOS 来管理 ECS,就可以考虑把 AliyunECSFullAccess 这个权限策略赋予给这个角色。
那么,接下来,OOS 是怎么 Assume Role 执行模板的呢?在 OOS 模板里面,可以通过“RamRole”这个字段指定一个角色,OOS 在后台执行这个模板的时候,就会尝试扮演这个 Role。如果模板没有指定,那么 OOS 就会尝试扮演默认的角色,也就是 OOSServiceRole 这个角色。
FormatVersion: OOS-2019-06-01
RamRole: 'OOSServiceRole'
Tasks:
- Name: describeRunningInstancesByTag
Action: ACS::ExecuteApi
Description: Views running ECS instances by specifying tag.
Properties:
Service: ECS
API: DescribeInstances
Parameters:
Status: Running
Tags:
- Key: 'tagkey'
Value: 'tagvalue'
如果用户没有预先创建相应的角色,那么在执行的时候,就会报错,错误消息类似于“:Assumes role failed. Code: EntityNotExist.Role, msg: The role not exists: acs::111111:role/OOSServiceRole.”
如果用户创建了这个角色,但是并没有信任运维编排服务,那么,就会报错,错误消息类似于“Assumes role failed. Code: NoPermission, msg: You are not authorized to do this action. You should be authorized by RAM.”
用户可以手动编辑该 Role 对应的信任策略
{
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": ["oos.aliyuncs.com"]
}
}
],
"Version": "1"
}
权限问题 2:Pass Role
如果操作 OOS 的都是主账号或者管理员,那么问题似乎已经解决了。但事实上,企业 IT 部门,都会有子账户的需求。子账户的权限,往往各种各样。虽然管理员信任 OOS 服务来扮演模板中指定的角色,但是管理员未必信任所有的子账户,通过执行 OOS 服务来使用上述的角色。这里面,OOS 服务成了一个中间人,子账户使用 OOS,OOS 使用角色。那么,如何决定子账户对于角色的间接使用权限呢?这就利用到了角色传递(Pass Role)这个功能。
下面,我们都过两个不同场景,来解释和说明。
场景 1:子账户执行一个公共模板,比如给一批 ECS 设置定时启动,并选择使用非默认的角色 MyOOSRole(我们的公共模板,是允许用户在执行时选择角色的)。这个场景非常常见。管理员要提前做两步动作:第一步,准备一个权限策略,要允许 PassRole 调用 MyOOSRole 这个角色,权限策略具体内容如下:
{
"Version": "1",
"Statement": [
{
"Effect": "Allow",
"Action": "ram:PassRole",
"Resource": "acs:ram::{parent_uid}:role/myoosrole"
}
]
}
第二步,把这个权限策略赋予该子账户。
如果子账户没有相应的 PassRole 权限,会报错提示“User has no permission to do the action: (PassRole)”。
场景 2:委托授权。我们想象一个场景,高规格的 ECS 是需要部门经理审批后才能创建的,按照前面介绍的 PassRole 场景,我们可以把“申请 - 审批 - 创建 ECS- 给 ECS 初始化”的整个工作流编排到一个模板里,同时准备一个拥有 ECS 权限并且信任 OOS 服务的角色,然后把这个模板交给普通用户使用。这里面有个问题,就是我们既不希望给普通用户授予 PassRole 权限,也不希望给普通用户授予创建 ECS 的权限,怎么办呢?为了同时实现安全性和方便性,我们推荐“委托授权”。在这个场景里面,有两类不同的子账户,第一类是模板的管理者,负责自定义模板的开发和维护工作,比如“申请一台高规格的 ECS 实例”的模板。另一类子账户是模板的执行者,需要通过执行这个模板来发起对于 ECS 的申请。模板的管理者拥有模板编辑的权限,给模板指定了一个角色,并拥有该角色对应的 PassRole 权限。而模板的执行者,只需要拥有该模板的执行权限就可以了,并不需要感知模板后面对应的角色,更不需要该角色的 PassRole 权限。这种场景,就叫做模板的管理者把 PassRole 权限“委托授权”给了模板的执行者。
在委托授权的场景下,PassRole 的鉴权动作,发生在模板管理员创建模板的时候,而不是在模板执行者执行模板的时候,理由是该模板的角色(假设为 OOSServiceRole)是在创建时刻被模板管理员指定的,执行者不感知角色。在权限策略的分配上,模板管理者需要 PassRole 调用 OOSServiceRole 的权限 + 编辑模板的权限,模板执行者只需要读取和执行模板的权限。请注意,这不适用于场景 1 中,子账户在执行模板时自主选择角色的情况。
在实际使用中,管理员可能会创建多个角色,都信任给 OOS 来扮演。那么在给子账户赋予 PassRole 权限的时候,如果把角色一个个都列出来,也会很繁琐。为了简化,管理员可以决定,只要是 OOS 能扮演的角色,就都允许某个子账户 PassRole 调用。比如,AliyunOOSFullAccess 这个系统权限策略就是:
{
"Statement": [
{
"Action": "oos:*",
"Effect": "Allow",
"Resource": "*"
},
{
"Action": "ram:PassRole",
"Resource": "*",
"Effect": "Allow",
"Condition": {
"StringEquals": {"acs:Service": "oos.aliyuncs.com"}
}
}
],
"Version": "1"
}
欢迎使用 OOS
OOS 管理控制台的链接: https://home.console.aliyun.com/redirect.htm?productId=ecs&path=automation/region/
OOS 帮助文档的链接
本文作者:云普
阅读原文
本文为云栖社区原创内容,未经允许不得转载。