模板任务输出定义最佳实践

背景

在自定义模板创建过程中,我们针对任务输出进行了优化:免去定义任务输出。原先模板中的每个任务的输出必须先由用户先进行定义,然后在后续的任务中才可以作为引用参数进行使用,而经过优化后,用户现在无需定义任务输出直接在下游任务中引用前序任务的输出。您可以根据本次最佳实践来体验该功能优化。

详情

本次功能优化后,您在控制台编辑自定义模板时,无需在每个任务中单独定义任务输出

image.png

在后续任务输入中,选择引用参数/任务输出,即可在下拉框中选择任务输出参数任务输出参数将会自动展示您已设置的任务中所有可能的输出,您只需要直接选择需要的参数即可

image.png

模板语法示例:

  - Name: ExecuteApi
    Action: ACS::ExecuteApi
    Description: ''
    Properties:
      Service: oos
      API: DescribeRegions
    Outputs: {}
  - Action: ACS::ECS::StartInstance
    Name: StartInstance
    Description: ''
    Properties:
      regionId: '{{ ExecuteApi.Regions[]?.RegionId }}' # 此处直接引用了前序任务 ExecuteApi 的输出: RegionId
      instanceId: i-xxxxxxxxx

使用示例

场景

在不同地域拉起ECS实例时,往往希望能够获取相同的环境和镜像内容,但是在ECS控制台对已有ECS运行相关命令、打镜像再根据需求分发到不同地域,整个操作过程往往较为复杂,且异步操作多无法统一管理。而OOS支持统一的编排与管理,针对刚才的场景:根据已经的ECS实例和指定的命令,创建一个新的ECS镜像并且克隆新镜像到其他地域,通过创建OOS的自定义模板,您可以轻松编排这些复杂场景,并将其简化为一个执行模板,仅需一次执行即可实现定制化的需求

image.png

前置信息

  • 一台状态在运行中的ECS实例,并确保ECS实例的地域和您执行OOS模板所在的地域为同一地域

  • 需要运行的命令

  • 涉及到的Action

  • ACS::ECS::RunCommand 执行命令

  • ACS::ECS::CreateImage 创建镜像

  • ACS::ECS::CopyImage 复制镜像

如果您想要了解更多相关的Action,可以点击查看:动作目录

操作步骤

0、准备动作

通过OOS首页侧边栏进入自定义任务模板,点击创建模板进入操作界面

image.png

此处选择空白模板即可

image.png

随后,点击添加新任务开始进行创建活动

image.png

任务类型处选择具体的Action,若找不到可直接进行搜索

image.png

在右侧的模板参数列,选择添加模板参数

image.png

添加三个模板运行必要的参数,InstanceIdImageNameTargetRegionId,参数的参数类型均为字符串,这里ImageName默认值涉及到系统参数的使用,可以参考:伪参数

CreateImage_from_{{ACS::ExecutionId}}的含义为:在字符串CreateImage_from_后拼接本执行的执行ID,最终形式为:CreateImage_from_exec-xxxxxxx

image.png

请注意,TargetRegionId需要选择业务组件RegionId

image.png

InstanceId需要选择业务组件ALIYUN::ECS::Instance::InstanceId

image.png

借助业务组件能够在执行设置参数时更加便捷,对这部分感兴趣可以查看:AssociationPropertyAssociationPropertyMetadata

image.png

image.png

1、任务 RunCommand 构建

添加新任务,任务类型ACS::ECS::RunCommand,并在任务输入中选择引用参数/任务输出,即可选取模板设置的参数和前序任务的输出

image.png

地域ID直接选择系统参数执行所在地域即可

image.png

ECS实例ID可以直接引用模板参数,点击即可进行引用

image.png

这里加入您提前准备好的命令内容,根据实例类型以及命令语言选择合适的命令类型

image.png如果想要观察脚本的输出,可以在模板输出中进行设置

image.png

可以看到,任务RunCommand的输出可以直接选取

image.png

在原先的流程中,如果您想要获取执行命令的结果,需要在该任务处定义输出方可在模板输出中引用,现在已无需再额外定义。

image.png

2、任务 CreateImage 构建

任务类型选择ACS::ECS::CreateImage进行构建,任务输入的参数均选择引用参数/任务输出

image.png

可以看到下拉框可以选取包括任务输出参数模板参数以及系统参数在内的不同类型的参数

image.png

地域ID选择系统参数中的执行所在地域镜像名称选择模板参数中的ImageNameECS实例ID选择任务输出参数中的Instances.Instance[].InstanceId

image.png

image.pngimage.png

其余的参数可根据需要进行配置。

在原先的流程中,仍需定义该任务的输出:生成的镜像ID,现已无需重复定义。

image.png

3、任务 CopyImage 构建

任务类型选择ACS::ECS::CopyImage进行构建,镜像ID直接选择任务CreateImage的输出参数imageId

image.png

源地域ID直接选择系统参数执行所在地域即可

image.png

目标地域ID选择模板参数中的TargetRegionId

image.png

目标镜像名称可以根据您的喜好进行命名,这里我采用'{{ CreateImage.imageId }}-{{ACS::ExecutionId}}',含义为镜像ID-执行ID,对任务CreateImage的输出进行引用,同时和系统参数{{ACS::ExecutionId}}相组合,拼接成一个目标镜像名称

image.png

在原先的流程中,仍需定义该任务的输出,才可以在模板输出中进行引用,获取相关信息,而现在已无需定义,可以直接进行引用。

image.png

4、设置模板输出

现在,我们可以直接在模板输出任意选择想要展示的任务输出,可以看到刚才设置好的任务输出都已经展示出来,我们可以选择任务CopyImage输出imageIdsWithRegion,进而在执行结束后直接获取分发结束后对应Region的镜像ID。

image.png

您可以根据自己的需要任意选择输出参数,以便自定义模板执行结束后直观的获取结果。

输出选择实例:

image.png

至此,一个自定义的模板就已经创建成功了,您可以在控制台进行执行并获取分发后的镜像ID。

实际执行后,您可以在输出界面看到所需的镜像ID以及执行命令的结果输出

image.png

模板内容对比

上述执行背后的模板展示如下:

FormatVersion: OOS-2019-06-01
Description: ''
Parameters:
  ImageName:
    Type: String
    Default: CreateImage_from_{{ACS::ExecutionId}}
  TargetRegionId:
    Label:
      en: TargetRegionIds
      zh-cn: 目标地域ID
    Type: String
    AssociationProperty: RegionId
  InstanceId:
    Type: String
    AssociationProperty: ALIYUN::ECS::Instance::InstanceId
Tasks:
  - Action: ACS::ECS::RunCommand
    Name: RunCommand
    Description: ''
    Properties:
      regionId: '{{ ACS::RegionId }}'
      commandContent: |-
        #!/bin/bash

        ##### 可在脚本开始运行时调用,打印当时的时间戳及PID。
        function job_start()
        {
            now=`date +'%Y-%m-%d %H:%M:%S'`
            echo "[$now][$$] job_start"
        }

        ##### 如果返回值为0,则认为此执行成功,如果非0,则认为执行失败
        job_start
      contentEncoding: PlainText
      workingDir: /root
      timeout: 600
      enableParameter: false
      parameters: {}
      username: ''
      windowsPasswordName: ''
      maxRetryInterval: 300
      instanceId: '{{ InstanceId }}'
      commandType: RunShellScript
  - Action: ACS::ECS::CreateImage
    Name: CreateImage
    Description: ''
    Properties:
      regionId: '{{ ACS::RegionId }}'
      tags: []
      imageFamily: ''
      imageDescription: ''
      resourceGroupId: ''
      detectionStrategy: ''
      instanceId: '{{ InstanceId }}'
      imageName: '{{ ImageName }}'
  - Action: ACS::ECS::CopyImage
    Name: CopyImage
    Description: ''
    Properties:
      targetImageName: '{{ CreateImage.imageId }}-{{ACS::ExecutionId}}'
      encrypted: false
      KMSKeyId: ''
      targetImageDescription: ''
      tags: []
      regionId: '{{ ACS::RegionId }}'
      targetRegionId: '{{ TargetRegionId }}'
      imageId: '{{ CreateImage.imageId }}'
Outputs:
  CommandOutput:
    Type: String
    Value: '{{ RunCommand.invocationOutput }}'
    Description: 执行命令结果
  ImageIdWithRegion:
    Type: String
    Value: '{{ CopyImage.imageIdWithRegion }}'
Metadata:
  ALIYUN::OOS::Interface:
    ParameterGroups:
      - Parameters:
          - regionId
          - instanceId
        Label:
          default:
            zh-cn: 选择实例
            en: Select Ecs Instances
      - Parameters:
          - targetImageName
          - tags
        Label:
          default:
            zh-cn: 镜像设置
            en: Image Configure
      - Parameters:
          - commandType
          - commandContent
        Label:
          default:
            zh-cn: 发送远程命令
            en: Run Command
      - Parameters:
          - targetRegionIds
          - accountIds
        Label:
          default:
            zh-cn: 镜像分发
            en: Copy Image
      - Parameters:
          - scalingConfigurationIds
          - launchTemplateNames
          - rateControl
          - OOSAssumeRole
        Label:
          default:
            zh-cn: 高级选项
            en: Control Options

在未优化之前,实现相同逻辑的模板展示如下:

FormatVersion: OOS-2019-06-01
Description: ''
Parameters:
  ImageName:
    Type: String
    Default: CreateImage_from_{{ACS::ExecutionId}}
  TargetRegionId:
    Label:
      en: TargetRegionIds
      zh-cn: 目标地域ID
    Type: String
    AssociationProperty: RegionId
  InstanceId:
    Type: String
    AssociationProperty: ALIYUN::ECS::Instance::InstanceId
Tasks:
  - Action: ACS::ECS::RunCommand
    Name: RunCommand
    Description: ''
    Properties:
      regionId: '{{ ACS::RegionId }}'
      commandContent: |-
        #!/bin/bash

        ##### 可在脚本开始运行时调用,打印当时的时间戳及PID。
        function job_start()
        {
            now=`date +'%Y-%m-%d %H:%M:%S'`
            echo "[$now][$$] job_start"
        }

        ##### 如果返回值为0,则认为此执行成功,如果非0,则认为执行失败
        job_start
      contentEncoding: PlainText
      workingDir: /root
      timeout: 600
      enableParameter: false
      parameters: {}
      username: ''
      windowsPasswordName: ''
      maxRetryInterval: 300
      instanceId: '{{ InstanceId }}'
      commandType: RunShellScript
    Outputs:
      commandOutput:
        Type: String
        ValueSelector: invocationOutput
  - Action: ACS::ECS::CreateImage
    Name: CreateImage
    Description: ''
    Properties:
      regionId: '{{ ACS::RegionId }}'
      tags: []
      imageFamily: ''
      imageDescription: ''
      resourceGroupId: ''
      detectionStrategy: ''
      instanceId: '{{ InstanceId }}'
      imageName: '{{ ImageName }}'
    Outputs:
      ImageId:
        Type: String
        ValueSelector: imageId
  - Action: ACS::ECS::CopyImage
    Name: CopyImage
    Description: ''
    Properties:
      targetImageName: '{{ CreateImage.imageId }}-{{ACS::ExecutionId}}'
      encrypted: false
      KMSKeyId: ''
      targetImageDescription: ''
      tags: []
      regionId: '{{ ACS::RegionId }}'
      targetRegionId: '{{ TargetRegionId }}'
      imageId: '{{ CreateImage.ImageId }}'
    Outputs:
      CopyImageId:
        Type: String
        ValueSelector: imageId
      CopyImageIdWithRegion:
        Type: List
        ValueSelector: imageIdWithRegion
Outputs:
  CommandOutput:
    Type: String
    Value: '{{ RunCommand.commandOutput }}'
    Description: 执行命令结果
  ImageIdWithRegion:
    Type: String
    Value: '{{ CopyImage.CopyImageIdWithRegion }}'
Metadata:
  ALIYUN::OOS::Interface:
    ParameterGroups:
      - Parameters:
          - regionId
          - instanceId
        Label:
          default:
            zh-cn: 选择实例
            en: Select Ecs Instances
      - Parameters:
          - targetImageName
          - tags
        Label:
          default:
            zh-cn: 镜像设置
            en: Image Configure
      - Parameters:
          - commandType
          - commandContent
        Label:
          default:
            zh-cn: 发送远程命令
            en: Run Command
      - Parameters:
          - targetRegionIds
          - accountIds
        Label:
          default:
            zh-cn: 镜像分发
            en: Copy Image
      - Parameters:
          - scalingConfigurationIds
          - launchTemplateNames
          - rateControl
          - OOSAssumeRole
        Label:
          default:
            zh-cn: 高级选项
            en: Control Options

可以看出所有的任务输出均无需定义,可以直接引用,减少了很多准备工作,能够让您更好的通过自定义模板编排自己想要实现的功能,在创建自定义模板时获得更好的体验。