全部产品
云市场

OOS操作ECS分组资源的权限策略管理

更新时间:2019-11-15 12:18:25

背景

阿里云账号分为主账号(用户)和子账号(用户)两类,主账号为注册阿里云时的账号,其权限为root,出于安全考虑,建议实际操作时采用子账号。而操作员工的职责不同,不同子账号需要的权限也不同。此时,子账号权限策略的有效管理就很重要。
本文将介绍下,当某员工通过子账号,使用运维编排服务(OOS)执行某模版,来完成一些例行运维任务时,如何既使子账号顺利完成相应操作,又最大程度保障账号的安全。

场景介绍

某公司账号下购买了若干台ECS实例,其中2台被打上标签TagKey:TagValue进行了分组,某员工甲被分配的子账号为subUser1ForOOS,甲定期通过该账号在OOS中执行一个模版T,模版执行的任务是对标签TagKey:TagValue分组下的ECS实例批量执行shell指令。即该员工具有对模版T的只读和执行权限,以及有模版任务涉及API(如RunCommand)的操作权限,且可操作的API仅对标签TagKey:TagValue分组下的实例有效。

解决方案

为满足上述场景,权限管理要分两方面,即OOS资源操作和ECS资源操作。
OOS方面权限策略包括对模版的只读权限、对模版T的执行权限、对执行的查询权限。
ECS方面权限策略为对标签TagKey:TagValue下实例的操作权限,且操作权限仅限于模版中涉及的API。
以上的权限策略成功创建后,将其授权给员工甲使用的RAM子用户即可(或具有员工甲相同职责的用户组)。

操作步骤

步骤如下

  • ECS实例的分组
  • 创建OOS模版
  • 创建子账号(用户)
  • 创建自定义权限策略
  • 为子账号授权
  • 子账号执行OOS模版
  • 权限策略的补充验证

ECS实例的分组

  1. 使用阿里云主账号(或管理员账号)登录到ECS控制台oos
  2. 选择2台实例,在操作菜单下选择更多 > 实例设置 > 编辑标签
  3. 单击新建标签,输入标签键标签值,单击确定
    本文中标签键设为TagKey,标签值设为TagValue。oos
  4. 单击确定
  5. 打开实例列表栏,在搜索框中输入TagKey:TagValue,单击放大镜图标。 oos
  6. 确认搜索结果为刚刚打标签TagKey:TagValue的实例。 oos

创建OOS模版

  1. 使用阿里云主账号(或管理员账号)登录到运维编排控制台
  2. 单击我的模版,单击创建模版,选取空白模版,单击YAML
    本文中模版格式选择YAML。 oos
  3. 将附件中YAML的模版内容复制到空白模版中(若您对实例分组的标签键值不是TagKey:TagValue,请根据实际情况对模版中TagKey和TagValue进行修改)。

    oos

  4. 模版任务如下,请确认模版将执行的任务。

    1. 验证指定标签下是否存在实例。
    2. 根据标签下是否存在停止的实例选择后续任务。
    3. 如果标签下存在停止的实例,则启动这些实例。
    4. 为标签下所有实例安装云助手。
    5. 在标签下所有实例中运行Shell命令。
  5. 填写模板名称,单击创建模版
    本文中,模版名称设为TestOperatingByGroups。oos

  6. 我的模版栏,可查看成功创建的模版TestOperatingByGroups。

创建子账号(用户)

  1. 使用阿里云主账号(或管理员账号)登录RAM控制台
  2. 在左侧导航栏的人员管理菜单下,单击用户 > 新建用户
  3. 输入登录名称显示名称
    本文中的登录名称及显示名称均设为subUser1ForOOS。
  4. 勾选控制台密码登录,单击自定义登录密码并填写要设置的子账号密码。 oos
  5. 单击确定
  6. 用户栏中可查看成功创建的新账号。oos

创建自定义权限策略

  1. 使用阿里云主账号登录RAM控制台
  2. 在左侧导航栏的权限管理菜单下,单击权限策略管理
  3. 单击新建权限策略
    创建第一条策略用来管理OOS资源操作。
  4. 填写策略名称备注
    本文中策略名称设置为OOSResourceManage。
  5. 配置模式选择脚本配置,并将下述的第一段JSON策略样例拷贝到策略内容区域,并根据实际情况进行修改(将JSON中所有以$为前缀的变量名替换掉)。
    将第一段JSON中的$AliyunMasterAccountID、$RegionID、$TemplateName1修改为您所使用的阿里云主账号ID、OOS及ECS资源所在地域ID(本文中为cn-hangzhou)、允许子账号可执行的模版名称(本文中为TestOperatingByGroups。))。
    oos
    操作OOS的策略
    该段策略表示:被授权RAM用户具有对$RegionID地域下模版的只读权限、对模版$TemplateName1的执行权限、对$RegionID地域下OOS执行的查询权限。

    1. {
    2. "Statement": [
    3. {
    4. "Action": [
    5. "oos:StartExecution",
    6. "oos:List*",
    7. "oos:Get*"
    8. ],
    9. "Resource": [
    10. "acs:oos:$RegionID:$AliyunMasterAccountID:template/$TemplateName1",
    11. "acs:oos:$RegionID:$AliyunMasterAccountID:execution/*"
    12. ],
    13. "Effect": "Allow"
    14. },
    15. {
    16. "Action": [
    17. "oos:List*",
    18. "oos:Get*"
    19. ],
    20. "Resource": [
    21. "acs:oos:$RegionID:$AliyunMasterAccountID:template/*"
    22. ],
    23. "Effect": "Allow"
    24. }
    25. ],
    26. "Version": "1"
    27. }
  6. 单击确定

  7. 单击新建权限策略,创建第二条策略用来管理ECS资源操作。
  8. 填写策略名称备注
  9. 配置模式选择脚本配置,将下述的第二段JSON策略样例拷贝到策略内容区域,并根据实际情况进行修改(将JSON中所有以$为前缀的变量名替换掉)。
    将第二段JSON中的$AliyunMasterAccountID、$TagKey、$TagValue、$RegionID修改为您所使用的阿里云主账号ID、实例所属标签键和标签值(本文中根据ECS实例的分组,键及值应设为TagKey和TagValue)、OOS及ECS资源所在地域ID。(本文中为cn-hangzhou)。
    ecs
    操作ECS的策略
    该段策略表示:被授权RAM用户具有对标签$TagKey:$TagValue下实例的操作权限,且仅可操作模版中涉及的API。

    1. {
    2. "Statement": [
    3. {
    4. "Effect": "Allow",
    5. "Action": [
    6. "ecs:DescribeInstances",
    7. "ecs:RebootInstance"
    8. ],
    9. "Resource": "acs:ecs:$RegionID:$AliyunMasterAccountID:instance/*",
    10. "Condition": {
    11. "StringEquals": {
    12. "ecs:tag/$TagKey": [
    13. "$TagValue"
    14. ]
    15. }
    16. }
    17. },
    18. {
    19. "Effect": "Allow",
    20. "Action": [
    21. "ecs:DescribeCloudAssistantStatus",
    22. "ecs:InstallCloudAssistant"
    23. ],
    24. "Resource": "acs:ecs:*:$AliyunMasterAccountID:instance/*",
    25. "Condition": {
    26. "StringEquals": {
    27. "ecs:tag/$TagKey": [
    28. "$TagValue"
    29. ]
    30. }
    31. }
    32. },
    33. {
    34. "Action": "ecs:DescribeTagKeys",
    35. "Effect": "Allow",
    36. "Resource": "*"
    37. },
    38. {
    39. "Action": "ecs:DescribeTags",
    40. "Effect": "Allow",
    41. "Resource": "*"
    42. },
    43. {
    44. "Effect": "Deny",
    45. "Action": [
    46. "ecs:DeleteTags",
    47. "ecs:UntagResources",
    48. "ecs:CreateTags",
    49. "ecs:TagResources"
    50. ],
    51. "Resource": "*"
    52. },
    53. {
    54. "Effect": "Allow",
    55. "Action": [
    56. "ecs:RunCommand"
    57. ],
    58. "Resource": "acs:ecs:*:$AliyunMasterAccountID:instance/*",
    59. "Condition": {
    60. "StringEquals": {
    61. "ecs:tag/$TagKey": [
    62. "$TagValue"
    63. ]
    64. }
    65. }
    66. },
    67. {
    68. "Action": [
    69. "ecs:RunCommand"
    70. ],
    71. "Resource": [
    72. "acs:ecs:*:$AliyunMasterAccountID:command/*"
    73. ],
    74. "Effect": "Allow"
    75. },
    76. {
    77. "Action": [
    78. "ecs:DescribeInvocations",
    79. "ecs:DescribeInvocationResults"
    80. ],
    81. "Resource": [
    82. "*"
    83. ],
    84. "Effect": "Allow"
    85. }
    86. ],
    87. "Version": "1"
    88. }
  10. 单击确定

为子账号(或用户组)授权

  1. 使用阿里云主账号(或管理员账号)登录RAM控制台
  2. 在左侧导航栏的权限管理菜单下,单击授权
  3. 单击新增授权
  4. 被授权主体中输入子账号名称(或用户组名称)并选中,在选择权限中选择自定义权限策略,在左侧权限策略名称列表下,单击选择需要授予给子账号(或用户组)的权限策略。
    • 本文输入的子账号名称为subUser1ForOOS。
    • 本文选择的权限策略名称为OOSResourceManage和ECSResourceManage。
    • 在右侧区域框,若撤销对某策略的选择,可单击某条策略的×。oos
  5. 单击确定
  6. 单击完成

执行OOS模版

  1. 使用主账号(或管理员账号)登录RAM概览,在右侧获取子账号登录地址。 oos
  2. 退出主账号(或管理员账号)的登录,访问刚获取的子账号登录地址,登录子账号。
    • 本文中登录的子账号为subUser1ForOOS。oos
  3. 登录成功后,进入运维编排控制台
  4. 单击我的模版,找到TestOperatingByGroups模版,单击创建执行oos
  5. 单击 下一步,设置参数
  6. 设置参数。
    • commandContent 将要执行的shell命令。
    • rateControl 模版执行时任务循环的并发速率及最大失败任务数。oos
  7. 单击 下一步,确认,单击创建执行
  8. 执行管理中可查看刚刚创建的执行。
    若创建执行成功,且执行状态处于运行中,则表示命令已开始执行。
  9. 当执行状态转换为成功时,则表示命令执行成功。
  10. 如需了解执行细节,单击该执行的详情,查看执行日志

权限策略的补充验证

OOS模版执行成功后,表示子账号subUser1ForOOS的权限策略支持模版TestOperatingByGroups执行需要的权限,也可在OOS控制台验证子账号无法执行未授权的模版。另外,若想验证子账号无法对标签以外实例的操作,可在登录子账号subUser1ForOOS后,通过Open Api 调试台对可操作API权限进行验证。

附件:OOS模版- - -在某标签下的所有ECS实例中执行命令

  • 模板内容(YAML格式)
  1. FormatVersion: OOS-2019-06-01
  2. Description:
  3. en: Run a specific command in specified ECS instances.
  4. zh-cn: 对某些实例执行具体命令。
  5. name-en: RunSpecificCommandInSpecifiedInstances
  6. name-zh-cn: 指定的实例上执行具体命令。
  7. Parameters:
  8. commandContent:
  9. Description:
  10. en: commandContent.
  11. zh-ch: shell指令内容。
  12. Type: String
  13. Default: echo hello
  14. rateControl:
  15. Description:
  16. en: Concurrency rate of task execution.
  17. zh-cn: 任务执行的并发比率。
  18. Type: Json
  19. AssociationProperty: RateControl
  20. Default:
  21. Mode: Concurrency
  22. MaxErrors: 0
  23. Concurrency: 100%
  24. Tasks:
  25. - Name: CheckInstancesExistInTag
  26. Action: 'ACS::CheckFor'
  27. Description:
  28. en: Check for whether instances exist in specified tag.
  29. zh-cn: 验证指定标签下是否存在实例。
  30. Properties:
  31. Service: ECS
  32. API: DescribeInstances
  33. Parameters:
  34. Tags:
  35. - Key: TagKey
  36. Value: TagValue
  37. NotDesiredValues:
  38. - []
  39. PropertySelector: Instances.Instance|map(.InstanceId)
  40. Outputs:
  41. instanceIds:
  42. Type: List
  43. ValueSelector: 'Instances.Instance[].InstanceId'
  44. stoppedInstanceIdsExist:
  45. Type: String
  46. ValueSelector: >-
  47. Instances.Instance[]|select(.Status=="Stopped")|.InstanceId|[.]|all|tostring
  48. stoppedInstanceIds:
  49. Type: List
  50. ValueSelector: 'Instances.Instance[]|select(.Status=="Stopped")|.InstanceId'
  51. - Name: whetherStoppedInstancesExist
  52. Action: 'ACS::Choice'
  53. Description:
  54. en: Choose next task by stopped instances exist.
  55. zh-cn: 根据标签下是否存在停止的实例选择后续任务。
  56. Properties:
  57. DefaultTask: installCloudAssistant
  58. Choices:
  59. - When:
  60. 'Fn::Equals':
  61. - 'true'
  62. - '{{ CheckInstancesExistInTag.stoppedInstanceIdsExist }}'
  63. NextTask: startInstances
  64. - Name: startInstances
  65. Action: 'ACS::ECS::StartInstance'
  66. Description:
  67. en: Start Instance.
  68. zh-cn: 启动标签下停止的实例。
  69. Properties:
  70. instanceId: '{{ ACS::TaskLoopItem }}'
  71. Loop:
  72. Items: '{{ CheckInstancesExistInTag.stoppedInstanceIds }}'
  73. RateControl: '{{ rateControl }}'
  74. - Name: installCloudAssistant
  75. Action: 'ACS::ECS::InstallCloudAssistant'
  76. Description:
  77. en: Install cloud assostant for ECS instances in tag.
  78. zh-cn: 给标签下所有实例安装云助手。
  79. Properties:
  80. instanceId: '{{ ACS::TaskLoopItem }}'
  81. Loop:
  82. Items: '{{ CheckInstancesExistInTag.instanceIds }}'
  83. RateControl: '{{ rateControl }}'
  84. - Name: runCommand
  85. Action: 'ACS::ECS::RunCommand'
  86. Description:
  87. en: Run cloud assostant command on ECS instances in tag.
  88. zh-cn: 在标签下所有实例中运行云助手命令。
  89. Properties:
  90. commandContent: '{{ commandContent }}'
  91. commandType: RunShellScript
  92. instanceId: '{{ ACS::TaskLoopItem }}'
  93. Loop:
  94. Items: '{{ CheckInstancesExistInTag.instanceIds }}'
  95. RateControl: '{{ rateControl }}'
  96. Outputs:
  97. invocationOutputs:
  98. AggregateType: 'Fn::ListJoin'
  99. AggregateField: invocationOutput
  100. Outputs:
  101. invocationOutput:
  102. Type: String
  103. ValueSelector: .invocationOutput
  104. Outputs:
  105. invocationOutput:
  106. Type: List
  107. Value: '{{ runCommand.invocationOutputs }}'
  • 模板内容(JSON格式)
  1. {
  2. "FormatVersion": "OOS-2019-06-01",
  3. "Description": {
  4. "en": "Run a specific command in specified ECS instances.",
  5. "zh-cn": "对某些实例执行具体命令。",
  6. "name-en": "RunSpecificCommandInSpecifiedInstances",
  7. "name-zh-cn": "指定的实例上执行具体命令。"
  8. },
  9. "Parameters": {
  10. "commandContent": {
  11. "Description": {
  12. "en": "commandContent.",
  13. "zh-ch": "shell指令内容。"
  14. },
  15. "Type": "String",
  16. "Default": "echo hello"
  17. },
  18. "rateControl": {
  19. "Description": {
  20. "en": "Concurrency rate of task execution.",
  21. "zh-cn": "任务执行的并发比率。"
  22. },
  23. "Type": "Json",
  24. "AssociationProperty": "RateControl",
  25. "Default": {
  26. "Mode": "Concurrency",
  27. "MaxErrors": 0,
  28. "Concurrency": "100%"
  29. }
  30. }
  31. },
  32. "Tasks": [
  33. {
  34. "Name": "CheckInstancesExistInTag",
  35. "Action": "ACS::CheckFor",
  36. "Description": {
  37. "en": "Check for whether instances exist in specified tag.",
  38. "zh-cn": "验证指定标签下是否存在实例。"
  39. },
  40. "Properties": {
  41. "Service": "ECS",
  42. "API": "DescribeInstances",
  43. "Parameters": {
  44. "Tags": [
  45. {
  46. "Key": "TagKey",
  47. "Value": "TagValue"
  48. }
  49. ]
  50. },
  51. "NotDesiredValues": [
  52. []
  53. ],
  54. "PropertySelector": "Instances.Instance|map(.InstanceId)"
  55. },
  56. "Outputs": {
  57. "instanceIds": {
  58. "Type": "List",
  59. "ValueSelector": "Instances.Instance[].InstanceId"
  60. },
  61. "stoppedInstanceIdsExist": {
  62. "Type": "String",
  63. "ValueSelector": "Instances.Instance[]|select(.Status==\"Stopped\")|.InstanceId|[.]|all|tostring"
  64. },
  65. "stoppedInstanceIds": {
  66. "Type": "List",
  67. "ValueSelector": "Instances.Instance[]|select(.Status==\"Stopped\")|.InstanceId"
  68. }
  69. }
  70. },
  71. {
  72. "Name": "whetherStoppedInstancesExist",
  73. "Action": "ACS::Choice",
  74. "Description": {
  75. "en": "Choose next task by stopped instances exist.",
  76. "zh-cn": "根据标签下是否存在停止的实例选择后续任务。"
  77. },
  78. "Properties": {
  79. "DefaultTask": "installCloudAssistant",
  80. "Choices": [
  81. {
  82. "When": {
  83. "Fn::Equals": [
  84. "true",
  85. "{{ CheckInstancesExistInTag.stoppedInstanceIdsExist }}"
  86. ]
  87. },
  88. "NextTask": "startInstances"
  89. }
  90. ]
  91. }
  92. },
  93. {
  94. "Name": "startInstances",
  95. "Action": "ACS::ECS::StartInstance",
  96. "Description": {
  97. "en": "Start Instance.",
  98. "zh-cn": "启动标签下停止的实例。"
  99. },
  100. "Properties": {
  101. "instanceId": "{{ ACS::TaskLoopItem }}"
  102. },
  103. "Loop": {
  104. "Items": "{{ CheckInstancesExistInTag.stoppedInstanceIds }}",
  105. "RateControl": "{{ rateControl }}"
  106. }
  107. },
  108. {
  109. "Name": "installCloudAssistant",
  110. "Action": "ACS::ECS::InstallCloudAssistant",
  111. "Description": {
  112. "en": "Install cloud assostant for ECS instances in tag.",
  113. "zh-cn": "给标签下所有实例安装云助手。"
  114. },
  115. "Properties": {
  116. "instanceId": "{{ ACS::TaskLoopItem }}"
  117. },
  118. "Loop": {
  119. "Items": "{{ CheckInstancesExistInTag.instanceIds }}",
  120. "RateControl": "{{ rateControl }}"
  121. }
  122. },
  123. {
  124. "Name": "runCommand",
  125. "Action": "ACS::ECS::RunCommand",
  126. "Description": {
  127. "en": "Run cloud assostant command on ECS instances in tag.",
  128. "zh-cn": "在标签下所有实例中运行云助手命令。"
  129. },
  130. "Properties": {
  131. "commandContent": "{{ commandContent }}",
  132. "commandType": "RunShellScript",
  133. "instanceId": "{{ ACS::TaskLoopItem }}"
  134. },
  135. "Loop": {
  136. "Items": "{{ CheckInstancesExistInTag.instanceIds }}",
  137. "RateControl": "{{ rateControl }}",
  138. "Outputs": {
  139. "invocationOutputs": {
  140. "AggregateType": "Fn::ListJoin",
  141. "AggregateField": "invocationOutput"
  142. }
  143. }
  144. },
  145. "Outputs": {
  146. "invocationOutput": {
  147. "Type": "String",
  148. "ValueSelector": ".invocationOutput"
  149. }
  150. }
  151. }
  152. ],
  153. "Outputs": {
  154. "invocationOutput": {
  155. "Type": "List",
  156. "Value": "{{ runCommand.invocationOutputs }}"
  157. }
  158. }
  159. }