审批ACS::Approve

用于审批任务的动作。

用途

在自动化运维的一些场景中,有些特殊的操作需要被特殊关注,例如删除重要资源,或使用费用较高的实例等。如果把这些操作也纳入自动化的范畴,您可能会担心失去控制,超过预算。若不纳入自动化的范畴,又会导致这些操作退化到手工执行或其他非自动化方式。审批动作能够让您在自动化和特殊关注之间寻找一个平衡。

当执行一个模板中包括审批动作,且执行到审批动作这一步时,OOS执行引擎会暂停执行,执行进入等待中状态,并发送一个包含通知的审批链接到管理员用户。在访问审批链接后,管理员可根据业务需求做出决定,同意或拒绝,同意后则OOS引擎继续执行后续任务,拒绝后引擎停止执行,执行状态为取消(Cancelled)。

Webhook 语法

对于钉钉,可以通过Webhook的方式支持。

  • YAML格式

Tasks:
  - Name: approvalTask
    Action: ACS::Approve
    Properties:
      AppendExecutionLink: 'true' # 是否附加执行详情链接,可选项true和false。ACS::Approve动作默认为true。
      Approvers: ["user1", "user2", "user3"] # 待审批的RAM子账号名字。
      MinRequiredApprovals: 2  # 审批通过时至少需要赞同的人数。
      NotifyType: WebHook
      WebHook:
        URI: url # 必填,webhook地址,如https://oapi.dingtalk.com/robot/send?access_token=xxxxxx
        Headers: # 可选,Http请求的Headers,如Content-Type
          Content-Type: 'application/json; charset=utf-8'
        Content: # 必填,根据具体的Webhook要求提供,如钉钉webhook要求如下:https://open-doc.dingtalk.com/docs/doc.htm?treeId=257&articleId=105735&docType=1 
          msgtype: text
          text:
            content: 'the approve notify to user'  # 必填,发送审批通知的内容。
          at:  # 在钉钉群中@的用户
            atMobiles: # 可选,@群里面的指定用户,此处的手机号为用户注册钉钉的手机号。
                        - 138albb1234
                        - 130albb1234
            isAtAll: 'false'  # 可选,是否@所有用户,可选true 或 false,默认为false。
  • JSON格式(请参照YAML注释说明)

{
  "Tasks": [
    {
      "Name": "approvalTask",
      "Action": "ACS::Approve",
      "Properties": {
        "AppendExecutionLink": "true",
        "Approvers": [
          "user1",
          "user2",
          "user3"
        ],
        "MinRequiredApprovals": 2,
        "NotifyType": "WebHook",
        "WebHook": {
          "URI": "url",
          "Headers": {
            "Content-Type": "application/json; charset=utf-8"
          },
          "Content": {
            "msgtype": "text",
            "text": {
              "content": "the approve notify to user"
            },
            "at": {
              "atMobiles": [
                "138albb1234",
                "130albb1234"
              ],
              "isAtAll": "false"
            }
          }
        }
      }
    }
  ]
}

Webhook 示例

以下模板:在删除实例前需要审批。

  • YAML格式

---
FormatVersion: OOS-2019-06-01
Description:
  en: Bulky restarts the ECS instances with Approval.
  zh-cn: 批量重启ECS实例带审批。
  name-en: BulkyRebootInstancesWithApproval
  name-zh-cn: 批量重启ECS实例带审批
Parameters:
  targets:
    Type: Json
    AssociationProperty: Targets
    AssociationPropertyMetadata:
      ResourceType: 'ALIYUN::ECS::Instance'
  rateControl:
    Description:
      en: Concurrency ratio of task execution.
      zh-cn: 任务执行的并发比率。
    Type: Json
    AssociationProperty: RateControl
    Default:
      Mode: Concurrency
      MaxErrors: 0
      Concurrency: 100%
  webHookUrl:
    Description:
      en: >-
        The webHook url of dingtalk group assistant,
        e.g.https://oapi.dingtalk.com/robot/send?access_token=1234zxcvaksdq31414.
      zh-cn: >-
        钉钉群助手的webhook地址,形如https://oapi.dingtalk.com/robot/send?access_token=1234zxcvaksdq31414。
    Type: String
  atMobiles:
    Description:
      en: >-
        The telephone numbers of member in dingtalk group assistant @, when
        notify comes.
      zh-cn: 当群助手向钉钉群中发送审批通知时,要被@的群成员注册钉钉所用手机号。
    Type: List
    Default:
      - '1390000****'
  atAll:
    Description:
      en: 'assistant @ all members in dingtalk group or not, when notify comes.'
      zh-cn: 当群助手向钉钉群中发送审批通知时是否@所有人。
    Type: String
    Default: 'false'
  OOSAssumeRole:
    Description:
      en: The RAM role to be assumed by OOS.
      zh-cn: OOS扮演的RAM角色。
    Type: String
    Default: OOSServiceRole
RamRole: '{{ OOSAssumeRole }}'
Tasks:
  - Name: getInstance
    Description:
      en: Views the ECS instances.
      zh-cn: 获取ECS实例。
    Action: 'ACS::SelectTargets'
    Properties:
      ResourceType: 'ALIYUN::ECS::Instance'
      Filters:
        - '{{ targets }}'
    Outputs:
      instanceIds:
        Type: List
        ValueSelector: 'Instances.Instance[].InstanceId'
      instanceNames:
        Type: List
        ValueSelector: 'Instances.Instance[].InstanceName'
  - Name: approveRestart
    Action: 'ACS::Approve'
    Properties:
      NotifyType: WebHook
      WebHook:
        URI: '{{webhookUrl}}'
        Headers:
          Content-Type: application/json
        Content:
          msgtype: text
          text:
            content: >-
              Notify: please approve instances restart, instance names to
              approve  are {{getInstance.instanceNames}}, sent by
              {{ACS::RegionId}} oos {{ACS::ExecutionId}}.
          at:
            atMobiles: '{{atMobiles}}'
            isAtAll: '{{atAll}}'
  - Name: rebootInstance
    Action: 'ACS::ECS::RebootInstance'
    Description:
      en: Restarts the ECS instances.
      zh-cn: 重启实例。
    Properties:
      instanceId: '{{ ACS::TaskLoopItem }}'
    Loop:
      RateControl: '{{ rateControl }}'
      Items: '{{ getInstance.instanceIds }}'
Outputs:
  instanceIds:
    Type: List
    Value: '{{ getInstance.instanceIds }}'
  • JSON格式

{
  "FormatVersion": "OOS-2019-06-01",
  "Description": {
    "en": "Bulky restarts the ECS instances with Approval.",
    "zh-cn": "批量重启ECS实例带审批。",
    "name-en": "BulkyRebootInstancesWithApproval",
    "name-zh-cn": "批量重启ECS实例带审批"
  },
  "Parameters": {
    "targets": {
      "Type": "Json",
      "AssociationProperty": "Targets",
      "AssociationPropertyMetadata": {
        "ResourceType": "ALIYUN::ECS::Instance"
      }
    },
    "rateControl": {
      "Description": {
        "en": "Concurrency ratio of task execution.",
        "zh-cn": "任务执行的并发比率。"
      },
      "Type": "Json",
      "AssociationProperty": "RateControl",
      "Default": {
        "Mode": "Concurrency",
        "MaxErrors": 0,
        "Concurrency": "100%"
      }
    },
    "webHookUrl": {
      "Description": {
        "en": "The webHook url of dingtalk group assistant, e.g.https://oapi.dingtalk.com/robot/send?access_token=1234zxcvaksdq31414.",
        "zh-cn": "钉钉群助手的webhook地址,形如https://oapi.dingtalk.com/robot/send?access_token=1234zxcvaksdq31414。"
      },
      "Type": "String"
    },
    "atMobiles": {
      "Description": {
        "en": "The telephone numbers of member in dingtalk group assistant @, when notify comes.",
        "zh-cn": "当群助手向钉钉群中发送审批通知时,要被@的群成员注册钉钉所用手机号。"
      },
      "Type": "List",
      "Default": [
        "1390000****"
      ]
    },
    "atAll": {
      "Description": {
        "en": "assistant @ all members in dingtalk group or not, when notify comes.",
        "zh-cn": "当群助手向钉钉群中发送审批通知时是否@所有人。"
      },
      "Type": "String",
      "Default": "false"
    },
    "OOSAssumeRole": {
      "Description": {
        "en": "The RAM role to be assumed by OOS.",
        "zh-cn": "OOS扮演的RAM角色。"
      },
      "Type": "String",
      "Default": "OOSServiceRole"
    }
  },
  "RamRole": "{{ OOSAssumeRole }}",
  "Tasks": [
    {
      "Name": "getInstance",
      "Description": {
        "en": "Views the ECS instances.",
        "zh-cn": "获取ECS实例。"
      },
      "Action": "ACS::SelectTargets",
      "Properties": {
        "ResourceType": "ALIYUN::ECS::Instance",
        "Filters": [
          "{{ targets }}"
        ]
      },
      "Outputs": {
        "instanceIds": {
          "Type": "List",
          "ValueSelector": "Instances.Instance[].InstanceId"
        },
        "instanceNames": {
          "Type": "List",
          "ValueSelector": "Instances.Instance[].InstanceName"
        }
      }
    },
    {
      "Name": "approveRestart",
      "Action": "ACS::Approve",
      "Properties": {
        "NotifyType": "WebHook",
        "WebHook": {
          "URI": "{{webhookUrl}}",
          "Headers": {
            "Content-Type": "application/json"
          },
          "Content": {
            "msgtype": "text",
            "text": {
              "content": "Notify: please approve instances restart, instance names to approve  are {{getInstance.instanceNames}}, sent by {{ACS::RegionId}} oos {{ACS::ExecutionId}}."
            },
            "at": {
              "atMobiles": "{{atMobiles}}",
              "isAtAll": "{{atAll}}"
            }
          }
        }
      }
    },
    {
      "Name": "rebootInstance",
      "Action": "ACS::ECS::RebootInstance",
      "Description": {
        "en": "Restarts the ECS instances.",
        "zh-cn": "重启实例。"
      },
      "Properties": {
        "instanceId": "{{ ACS::TaskLoopItem }}"
      },
      "Loop": {
        "RateControl": "{{ rateControl }}",
        "Items": "{{ getInstance.instanceIds }}"
      }
    }
  ],
  "Outputs": {
    "instanceIds": {
      "Type": "List",
      "Value": "{{ getInstance.instanceIds }}"
    }
  }
}

Mail 语法

  • YAML格式

Tasks:
  - Action: ACS::Approve
    Name: ApproveByMail
    Properties:
      NotifyType: Mail
      Mail:
      	Host: SMTPHostAddress # SMTP 服务器主机地址如 smtp.example1.com
        Port: SMTPPort # SMTP 服务器端口如 465
        Username: sender  # 代发送的邮箱用户如 usr001@example1.com
        Password: senderPassword # 需要填写的是"IMAP/SMTP服务"的授权码,而不是邮箱登录密码
        Subject: mailSubject # 邮件主题如 hello world
        Body: mailBody # 邮件正文如 hello world !!!
        From: senderAddress # 邮件来自如 usr001@example1.com
        To: # 收件人邮箱地址列表如 [usr1234@example2.com,usr123@example2.com]
        	- usr123@example2.com
        	- usr1234@example2.com
  • JSON格式(请参照YAML注释说明)

{
  "Tasks": [
    {
      "Action": "ACS::Approve",
      "Name": "ApproveByMail",
      "Properties": {
        "NotifyType": "Mail",
        "Mail": {
          "Host": "SMTPHostAddress",
          "Port": "SMTPPort",
          "Username": "sender",
          "Password": "senderPassword",
          "Subject": "mailSubject",
          "Body": "mailBody",
          "From": "senderAddress",
          "To": [
            "usr123@example2.com,usr1234@example2.com"
          ]
        }
      }
    }
  ]
}