使用Terraform操作云工作流调度

Terraform是一种开源工具,用于安全高效地预览,配置和管理云基础架构和资源。云工作流调度使用EventBridge实现,该功能目前仅限控制台使用,未开放API,无法使用Terraform直接操作云工作流调度。如果您需要使用Terraform调度云工作流,可以通过使用Terraform创建EventBridge资源实现。

说明

当前示例代码支持一键运行,您可以直接运行代码。一键运行

前提条件

  • 开通云工作流服务

  • 开通事件总线EventBridge服务

  • 由于阿里云账号(主账号)具有资源的所有权限,一旦发生泄露将面临重大风险。建议您使用RAM用户,并为该RAM用户创建AccessKey,具体操作方式,请参见创建RAM用户创建AccessKey

  • 需要为该RAM用户授予以下权限:管理云工作流(FNF)资源的AliyunFnFFullAccess权限。具体操作方式,请参见RAM用户授权

  • 准备Terraform运行环境,您可以选择以下任一方式来使用Terraform。

    • Terraform Explorer中使用Terraform:阿里云提供了Terraform的在线运行环境,您无需安装Terraform,登录后即可在线使用和体验Terraform。适用于零成本、快速、便捷地体验和调试Terraform的场景。

    • Cloud Shell:阿里云Cloud Shell中预装了Terraform的组件,并已配置好身份凭证,您可直接在Cloud Shell中运行Terraform的命令。适用于低成本、快速、便捷地访问和使用Terraform的场景。

    • 在本地安装和配置Terraform:适用于网络连接较差或需要自定义开发环境的场景。

重要

请确保Terraform版本不低于v0.12.28。如需检查现有版本,请运行terraform --version命令。

使用的资源

使用Terraform操作云工作流调度

  1. 创建一个工作目录,并且在工作目录中创建以下名为main.tf的配置文件。main.tfTerraform主文件,定义了将要部署的资源。

    variable "region" {
      default = "cn-hangzhou"
    }
    provider "alicloud" {
      region = var.region
    }
    # 变量定义名称。
    variable "name" {
      default = "test-mns"
    }
    # 变量定义策略名称。
    variable "policy_name" {
      type = string
      description = "The name of the policy."
      default = "test-policy"
    }
    # 定义变量角色名称
    variable "role_name" {
      type = string
      description = "The role for eb to start execution of flow."
      default = "eb-to-fnf-role"
    }
    # 变量定义云工作流名称
    variable "flow_name" {
      type = string
      description = "The name of the flow."
      default = "test-flow"
    }
    # 定义流的描述
    variable "flow_description" {
      default = "For flow_description"
    }
    # 定义变量总线名称。
    variable "event_bus_name" {
      type = string
      description = "The name of the event bus."
      default = "test-eventbus1"
    }
    # 定义变量总线描述。
    variable "event_bus_description" {
      default = "For event_bus_description"
    }
    # 定义变量事件源的代码名称
    variable "event_source_name" {
      type = string
      description = "The name of the event source."
      default = "test-eventsource1"
    }
    # 定义事件规则名称
    variable "event_rule_name" {
        type = string
        description = "The name of the event rule."
        default = "test-eventrule1"
    }
    # 自定义事件目标的 ID
    variable "target_id" {
        type = string
        description = "The ID of the target."
        default = "test-target1"
    }
    # 获取当前阿里云uid
    data "alicloud_account" "current" {
    }
    # 创建随机数
    resource "random_integer" "default" {
      min = 10000
      max = 99999
    }
    # 创建一个RAM策略来定义权限。
    resource "alicloud_ram_policy" "policy_exmaple" {
      # RAM 策略的名称。
      policy_name     = "${var.policy_name}-${random_integer.default.result}"
      # (可选)此参数用于资源销毁。默认值为 false。
      force           = true 
      # RAM 策略的文档
       policy_document = <<EOF
      {
        "Statement": [
          {
            "Action": [
              "fnf:*",        
              "mns:*",         
              "eventbridge:*",       
              "ram:*"  
            ],
            "Effect": "Allow",
            "Resource": [
              "*"
            ]
          }
        ],
          "Version": "1"
      }
      EOF
    }
    # 创建一个RAM角色。
    resource "alicloud_ram_role" "role_example" {
      # 角色名称
      name     = var.role_name
      # (可选)此参数用于资源销毁。默认值为 false。
      force           = true 
      # 角色策略文档
      document = <<EOF
      {
        "Statement": [
          {
            "Action": "sts:AssumeRole",
            "Effect": "Allow",
            "Principal": {
              "Service": [
                "fnf.aliyuncs.com"
              ]
            }
          }
        ],
        "Version": "1"
      }
      EOF
    }
    # 将创建的RAM策略附加到RAM角色上,以授予该角色相应的权限。
    resource "alicloud_ram_role_policy_attachment" "attach_example" {
      # RAM策略名称
      policy_name = alicloud_ram_policy.policy_exmaple.policy_name
      # RAM策略类型
      policy_type = alicloud_ram_policy.policy_exmaple.type
      # RAM角色名称
      role_name   = alicloud_ram_role.role_example.name
    }
    # 创建一个云工作流资源
    resource "alicloud_fnf_flow" "flow_example" {
      depends_on = [alicloud_ram_role_policy_attachment.attach_example]
      # (必填) 流的定义。必须符合流定义语言(FDL)的语法。
      definition  = <<EOF
      Type: StateMachine
      Name: ${var.flow_name}
      SpecVersion: v1
      StartAt: Hello World
      States:
      - Type: Pass
        Name: Hello World
        End: true
      EOF
      # 无服务器工作流在执行流时使用的指定 RAM 角色的 ARN。
      role_arn    = alicloud_ram_role.role_example.arn
      # 流的描述
      description = var.flow_description
      # 流的名称
      name        = var.flow_name
      # 流的类型有效值为 FDL 或 DEFAULT。
      type        = "FDL"
    }
    # 创建一个事件总线来接收和路由事件。
    resource "alicloud_event_bridge_event_bus" "eventbus_example" {
      # 事件总线名称
      event_bus_name = var.event_bus_name
      # (可选)事件总线的描述
      description = var.event_bus_description
    }
    # 创建 MNS 队列资源
    resource "alicloud_mns_queue" "example" {
      # 名字
      name = "${var.name}-${random_integer.default.result}"
      # 此属性定义发送到队列的每条消息在出队后延迟的时间(以秒为单位)
      delay_seconds            = 0
      # 此属性指示发送到队列的任何消息体的最大长度(以字节为单位)
      maximum_message_size     = 65536
      # 消息在队列中被删除的时间段,无论它们是否已被激活。此属性定义每条消息在队列中的有效期(以秒为单位)。
      message_retention_period = 345600
      # 队列的可见性超时属性。
      visibility_timeout       = 30
      # 长轮询的时间,以秒为单位
      polling_wait_seconds     = 0
    }
    # 创建一个事件源,用于生成定时事件。
    resource "alicloud_event_bridge_event_source" "eventsource_example" {
      # 事件总线的名称。
      event_bus_name         = alicloud_event_bridge_event_bus.eventbus_example.event_bus_name
      # 事件源的代码名称
      event_source_name      = var.event_source_name
      # (可选,计算得出)是否连接到外部数据源。默认值:false。
      linked_external_source = true
      # (可选)外部数据源的类型。有效值:RabbitMQ、RocketMQ 和 MNS。注意:仅当 linked_external_source 为 true 时,此字段有效。
      external_source_type   = "MNS"
      # (可选,映射)外部源的配置。
      external_source_config = {
        QueueName = alicloud_mns_queue.example.name
      }
    }
    
    # 定义一个本地变量,用于存储云工作流的ARN。
    locals {
        flow_arn = format("acs:fnf:::flow/%s", var.flow_name)
    }
    
    # 创建一个事件规则,用于匹配事件源生成的事件,并将这些事件路由到指定的云工作流。
    resource "alicloud_event_bridge_rule" "eventrule_example" {
      # 事件总线的名称。
      event_bus_name = alicloud_event_bridge_event_bus.eventbus_example.event_bus_name
      # 事件规则名称
      rule_name      = var.event_rule_name
      # 匹配感兴趣事件的模式。事件模式,JSON 格式。值的描述如下:stringEqual 模式,stringExpression 模式。
      filter_pattern = format("{\"source\":[\"%s\"]}", var.event_source_name)
      # 规则的目标
      targets {
        #  自定义事件目标的 ID。
        target_id = var.target_id
        # 事件目标的端点。
        endpoint  = local.flow_arn
        # 事件目标的类型。
        type      = "acs.fnf"
        param_list {
          resource_key = "Input"
          form         = "ORIGINAL"
        }
        param_list {
          form         = "CONSTANT"
          resource_key = "FlowName"
          value        = var.flow_name
        }
        param_list {
          form         = "CONSTANT"
          resource_key = "RoleName"
          value        = var.role_name
        }
      }
    }
  2. 执行以下命令,初始化Terraform运行环境。

    terraform init

    返回如下信息,表示Terraform初始化成功。

    Initializing the backend...
    
    Initializing provider plugins...
    - Finding latest version of hashicorp/alicloud...
    - Installing hashicorp/alicloud v1.234.0...
    - Installed hashicorp/alicloud v1.234.0 (signed by HashiCorp)
    
    Terraform has created a lock file .terraform.lock.hcl to record the provider
    selections it made above. Include this file in your version control repository
    so that Terraform can guarantee to make the same selections by default when
    you run "terraform init" in the future.
    
    Terraform has been successfully initialized!
    
    You may now begin working with Terraform. Try running "terraform plan" to see
    any changes that are required for your infrastructure. All Terraform commands
    should now work.
    
    If you ever set or change modules or backend configuration for Terraform,
    rerun this command to reinitialize your working directory. If you forget, other
    commands will detect it and remind you to do so if necessary.
  3. 创建执行计划,并预览变更。

    terraform plan
  4. 执行以下命令,创建云工作流调度。

    terraform apply

    在执行过程中,根据提示输入yes并按下Enter键,等待命令执行完成,若出现以下信息,则表示创建云工作流调度成功。

    Plan: 9 to add, 0 to change, 0 to destroy.
    
    Do you want to perform these actions?
      Terraform will perform the actions described above.
      Only 'yes' will be accepted to approve.
    
      Enter a value: yes
    
    random_integer.default: Creating...
    random_integer.default: Creation complete after 0s [id=10***]
    alicloud_ram_policy.policy_exmaple: Creating...
    alicloud_ram_role.role_example: Creating...
    alicloud_mns_queue.example: Creating...
    alicloud_event_bridge_event_bus.eventbus_example: Creating...
    alicloud_mns_queue.example: Creation complete after 0s [id=test-mns-10***]
    alicloud_ram_policy.policy_exmaple: Creation complete after 1s [id=test-policy-10***]
    alicloud_ram_role.role_example: Creation complete after 1s [id=eb-to-fnf-r***]
    alicloud_ram_role_policy_attachment.attach_example: Creating...
    alicloud_ram_role_policy_attachment.attach_example: Creation complete after 0s [id=role:test-policy-10486:Custom:eb-to-f***]
    alicloud_fnf_flow.flow_example: Creating...
    alicloud_fnf_flow.flow_example: Creation complete after 0s [id=test-f***]
    alicloud_event_bridge_event_bus.eventbus_example: Creation complete after 2s [id=test-event***]
    alicloud_event_bridge_rule.eventrule_example: Creating...
    alicloud_event_bridge_event_source.eventsource_example: Creating...
    alicloud_event_bridge_event_source.eventsource_example: Creation complete after 0s [id=test-eventsour***]
    alicloud_event_bridge_rule.eventrule_example: Creation complete after 0s [id=test-eventbus1:test-event***]
    
    Apply complete! Resources: 9 added, 0 changed, 0 destroyed.
  5. 验证结果 。

    执行terraform show命令

    您可以使用以下命令查询Terraform已创建的资源详细信息:

    terraform show

    image

    登录云工作流Cloud Flow控制台

    创建完成后,您可以通过OpenAPI、SDK或者登录云工作流Cloud Flow控制台,检查操作是否正确完成。image

清理资源

当您不再需要上述通过Terraform创建或管理的资源时,请运行以下命令以释放资源。关于terraform destroy的更多信息,请参见Terraform常用命令

terraform destroy

完整示例

说明

当前示例代码支持一键运行,您可以直接运行代码。一键运行

示例代码

variable "region" {
  default = "cn-hangzhou"
}
provider "alicloud" {
  region = var.region
}
# 变量定义名称。
variable "name" {
  default = "test-mns"
}
# 变量定义策略名称。
variable "policy_name" {
  type = string
  description = "The name of the policy."
  default = "test-policy"
}
# 定义变量角色名称
variable "role_name" {
  type = string
  description = "The role for eb to start execution of flow."
  default = "eb-to-fnf-role"
}
# 变量定义云工作流名称
variable "flow_name" {
  type = string
  description = "The name of the flow."
  default = "test-flow"
}
# 定义流的描述
variable "flow_description" {
  default = "For flow_description"
}
# 定义变量总线名称。
variable "event_bus_name" {
  type = string
  description = "The name of the event bus."
  default = "test-eventbus1"
}
# 定义变量总线描述。
variable "event_bus_description" {
  default = "For event_bus_description"
}
# 定义变量事件源的代码名称
variable "event_source_name" {
  type = string
  description = "The name of the event source."
  default = "test-eventsource1"
}
# 定义事件规则名称
variable "event_rule_name" {
    type = string
    description = "The name of the event rule."
    default = "test-eventrule1"
}
# 自定义事件目标的 ID
variable "target_id" {
    type = string
    description = "The ID of the target."
    default = "test-target1"
}
# 获取当前阿里云uid
data "alicloud_account" "current" {
}
# 创建随机数
resource "random_integer" "default" {
  min = 10000
  max = 99999
}
# 创建一个RAM策略来定义权限。
resource "alicloud_ram_policy" "policy_exmaple" {
  # RAM 策略的名称。
  policy_name     = "${var.policy_name}-${random_integer.default.result}"
  # (可选)此参数用于资源销毁。默认值为 false。
  force           = true 
  # RAM 策略的文档
   policy_document = <<EOF
  {
    "Statement": [
      {
        "Action": [
          "fnf:*",        
          "mns:*",         
          "eventbridge:*",       
          "ram:*"  
        ],
        "Effect": "Allow",
        "Resource": [
          "*"
        ]
      }
    ],
      "Version": "1"
  }
  EOF
}
# 创建一个RAM角色。
resource "alicloud_ram_role" "role_example" {
  # 角色名称
  name     = var.role_name
  # (可选)此参数用于资源销毁。默认值为 false。
  force           = true 
  # 角色策略文档
  document = <<EOF
  {
    "Statement": [
      {
        "Action": "sts:AssumeRole",
        "Effect": "Allow",
        "Principal": {
          "Service": [
            "fnf.aliyuncs.com"
          ]
        }
      }
    ],
    "Version": "1"
  }
  EOF
}
# 将创建的RAM策略附加到RAM角色上,以授予该角色相应的权限。
resource "alicloud_ram_role_policy_attachment" "attach_example" {
  # RAM策略名称
  policy_name = alicloud_ram_policy.policy_exmaple.policy_name
  # RAM策略类型
  policy_type = alicloud_ram_policy.policy_exmaple.type
  # RAM角色名称
  role_name   = alicloud_ram_role.role_example.name
}
# 创建一个云工作流资源
resource "alicloud_fnf_flow" "flow_example" {
  depends_on = [alicloud_ram_role_policy_attachment.attach_example]
  # (必填) 流的定义。必须符合流定义语言(FDL)的语法。
  definition  = <<EOF
  Type: StateMachine
  Name: ${var.flow_name}
  SpecVersion: v1
  StartAt: Hello World
  States:
  - Type: Pass
    Name: Hello World
    End: true
  EOF
  # 无服务器工作流在执行流时使用的指定 RAM 角色的 ARN。
  role_arn    = alicloud_ram_role.role_example.arn
  # 流的描述
  description = var.flow_description
  # 流的名称
  name        = var.flow_name
  # 流的类型有效值为 FDL 或 DEFAULT。
  type        = "FDL"
}
# 创建一个事件总线来接收和路由事件。
resource "alicloud_event_bridge_event_bus" "eventbus_example" {
  # 事件总线名称
  event_bus_name = var.event_bus_name
  # (可选)事件总线的描述
  description = var.event_bus_description
}
# 创建 MNS 队列资源
resource "alicloud_mns_queue" "example" {
  # 名字
  name = "${var.name}-${random_integer.default.result}"
  # 此属性定义发送到队列的每条消息在出队后延迟的时间(以秒为单位)
  delay_seconds            = 0
  # 此属性指示发送到队列的任何消息体的最大长度(以字节为单位)
  maximum_message_size     = 65536
  # 消息在队列中被删除的时间段,无论它们是否已被激活。此属性定义每条消息在队列中的有效期(以秒为单位)。
  message_retention_period = 345600
  # 队列的可见性超时属性。
  visibility_timeout       = 30
  # 长轮询的时间,以秒为单位
  polling_wait_seconds     = 0
}
# 创建一个事件源,用于生成定时事件。
resource "alicloud_event_bridge_event_source" "eventsource_example" {
  # 事件总线的名称。
  event_bus_name         = alicloud_event_bridge_event_bus.eventbus_example.event_bus_name
  # 事件源的代码名称
  event_source_name      = var.event_source_name
  # (可选,计算得出)是否连接到外部数据源。默认值:false。
  linked_external_source = true
  # (可选)外部数据源的类型。有效值:RabbitMQ、RocketMQ 和 MNS。注意:仅当 linked_external_source 为 true 时,此字段有效。
  external_source_type   = "MNS"
  # (可选,映射)外部源的配置。
  external_source_config = {
    QueueName = alicloud_mns_queue.example.name
  }
}

# 定义一个本地变量,用于存储云工作流的ARN。
locals {
    flow_arn = format("acs:fnf:::flow/%s", var.flow_name)
}

# 创建一个事件规则,用于匹配事件源生成的事件,并将这些事件路由到指定的云工作流。
resource "alicloud_event_bridge_rule" "eventrule_example" {
  # 事件总线的名称。
  event_bus_name = alicloud_event_bridge_event_bus.eventbus_example.event_bus_name
  # 事件规则名称
  rule_name      = var.event_rule_name
  # 匹配感兴趣事件的模式。事件模式,JSON 格式。值的描述如下:stringEqual 模式,stringExpression 模式。
  filter_pattern = format("{\"source\":[\"%s\"]}", var.event_source_name)
  # 规则的目标
  targets {
    #  自定义事件目标的 ID。
    target_id = var.target_id
    # 事件目标的端点。
    endpoint  = local.flow_arn
    # 事件目标的类型。
    type      = "acs.fnf"
    param_list {
      resource_key = "Input"
      form         = "ORIGINAL"
    }
    param_list {
      form         = "CONSTANT"
      resource_key = "FlowName"
      value        = var.flow_name
    }
    param_list {
      form         = "CONSTANT"
      resource_key = "RoleName"
      value        = var.role_name
    }
  }
}

如果您想体验更多完整示例,请前往更多完整示例中对应产品的文件夹查看。