使用模块

您可以在其他模块或模板中使用模块。本文为您介绍如何使用模块及其相关注意事项。

前提条件

使用模块

您需要将模块当作单个资源进行处理。

  • 将其纳入到模板(或模块)的Resources部分中。

  • 为模块指定版本。

  • 为模块指定任何必要的属性。

为模块指定版本

通过Version字段为模块指定版本,Version取值如下:

  • 指定版本:格式为v+数字,例如v1v10

    使用公共模块时,建议使用此方式。

  • default:默认版本。

    只要模块未删除,模块始终存在一个可用的默认版本。

    您可以通过API或控制台自行设置自定义模块的默认版本。更多信息,请参见SetResourceType - 修改资源类型修改模块默认版本

    使用自定义模块时,建议使用此方式。

  • latest:最新版本。

    只要模块未删除,模块始终存在一个可用的最新版本。

    当模块创建新版本或删除最新版本时,最新版本会发生变化。

    开发调试模块时,建议使用此方式。

为模块指定属性

模块参数可以帮助您将自定义值从模板(或模块)输入到模块中,模块可以使用自定义值来设置资源(或子模块)的属性。如果模块参数未指定,且该参数有默认值(Default),则会使用默认值。

使用模板参数指定模块属性

您可以定义模板参数,用模板参数来设置模块属性,以便可以将输入的值传递给模块。定义模板参数的更多信息,请参见参数

您可以将模板中的自定义值传递给模块参数。包含MODULE::My::VPC::SampleVpc的模板定义了模板参数VpcName,您可以通过模板参数指定模块中的VPC名称。

ROSTemplateFormatVersion: '2015-09-01'
Parameters:
  VpcName:
    Description: Name for your sample vpc
    Type: String
Resources:
  MyVpc:
    Type: MODULE::My::VPC::SampleVpc
    Version: default
    Properties:
      VpcName:
        Ref: VpcName

在父模块中指定子模块的属性

如果模块和嵌套模块中包含相同的参数,以下示例为您展示如何为嵌套的子模块指定参数值。

您可以在父模块中为嵌套模块的参数指定值。MODULE::My::VPC::SampleVpcPrivate模块为子模块,该模块定义了两个参数:VpcNameCidrBlock。这些参数用于设置ALIYUN::ECS::VPC资源的VpcNameCidrBlock属性。子模块的代码示例如下所示。

ROSTemplateFormatVersion: '2015-09-01'
Description: A sample vpc.
Parameters:
  VpcName:
    Description: Name for the vpc
    Type: String
  CidrBlock:
    Description: Cidr block for the vpc
    Type: String
Resources:
  Vpc:
    Type: ALIYUN::ECS::VPC
    Properties:
      VpcName:
        Ref: VpcName
      CidrBlock:
        Ref: CidrBlock

将子模块MODULE::My::VPC::SampleVpcPrivate嵌套在父模块MODULE::My::VPC::SampleVpc中,父模块MODULE::My::VPC::SampleVpc通过以下方式设置子模块参数。父模块的代码示例如下所示。

  • 它将MODULE::My::VPC::SampleVpcPrivateCidrBlock参数设置为192.168.0.0/16

  • 对于VpcName参数,则定义了一个模块参数,该参数使得包含MODULE::My::VPC::SampleVpc的模板(或模块)能够指定VPC名称。

ROSTemplateFormatVersion: '2015-09-01'
Description: A sample vpc.
Parameters:
  VpcName:
    Description: Name for the vpc
    Type: String
Resources:
  MyVpc:
    Type: MODULE::My::VPC::SampleVpcPrivate
    Version: default
    Properties:
      VpcName:
        Ref: VpcName
      CidrBlock: 192.168.0.0/16

为模块参数指定约束

模块参数不支持约束强制执行。要对模块参数执行约束检查,请创建具有所需约束的模板参数,然后在模块参数中引用该模板参数。

为模块指定条件

与资源指定条件的方式相同。模块的条件会传递给所有资源和子模块。定义条件的更多信息,请参见条件(Conditions)

为模块指定依赖

与资源指定依赖的方式相同。模块的依赖会传递给所有资源和子模块。定义依赖的更多信息,请参见DependsOn

为模块指定删除策略

与资源指定删除策略的方式相同。模块的删除策略会传递给所有未指定删除策略的资源和子模块。定义删除策略的更多信息,请参见DeletionPolicy

引用模块

引用模块中的资源

模块中的资源可以通过完全限定逻辑名称进行引用,模块中的资源完全限定逻辑名称可以通过将以下名称相结合来构成。

  • 在模板(或模块)中为模块指定的逻辑名称。

  • 模块中指定的资源的逻辑名称。

您可以使用半角句号(.)作为分隔符来指定资源的完全限定逻辑名称。例如:ModuleLogicalName.ResourceLogicalNameParentModuleLogicalName.ChildModuleLogicalName.ResourceLogicalName

通过这种方式,您可以使用Fn::GetAttRefFn::Sub内部函数来访问模块资源(Resources)或其属性值。更多信息,请参见资源(Resources)

// Fn::GetAtt示例
GetAtt Example1:
  Fn::GetAtt:
    - ModuleLogicalName.ResourceLogicalName
    - AttributeName
GetAtt Example2:
  Fn::GetAtt:
    - ModuleLogicalName.ChildModuleLogicalName.ResourceLogicalName
    - AttributeName

// Ref示例
Ref Example1:
  Ref: ModuleLogicalName.ResourceLogicalName
Ref Example2:
  Ref: ModuleLogicalName.ChildModuleLogicalName.ResourceLogicalName

// Fn::Sub示例
Sub Example1:
  Fn::Sub: "${ModuleLogicalName.ResourceLogicalName}"
Sub Example2:
  Fn::Sub: "${ModuleLogicalName.ResourceLogicalName.AttributeName}"
Sub Example3:
  Fn::Sub: "${ModuleLogicalName.ChildModuleLogicalName.ResourceLogicalName}"
Sub Example4:
  Fn::Sub: "${ModuleLogicalName.ChildModuleLogicalName.ResourceLogicalName.AttributeName}"

在以下示例中:

  • 模板引用模块中的资源为模板本身的资源设置相应属性。

  • 模板引用模块中资源的输出作为模板本身的输出。

假设MODULE::My::VPC::SampleVpc模块包含逻辑名称为Vpc的资源ALIYUN::ECS::VPC。要使用Ref内部函数引用此资源的ID或Fn::GetAtt内部函数引用此资源的输出属性,需要将模板中模块的逻辑名称MyVpc与模块中资源的逻辑名称Vpc相结合,从而获得资源的完全限定逻辑名称:MyVpc.Vpc

说明

您可以在ROS中查看模块,并获取到资源的逻辑名称。更多信息,请参见查看自定义模块查看公共模块

Parameters:
  VpcName:
    Description: Name for your sample vpc
    Type: String
Resources:
  MyVpc:
    Type: MODULE::My::VPC::SampleVpc
    Version: default
    Properties:
      VpcName:
        Ref: VpcName
  MyVsw:
    Type: ALIYUN::ECS::VSwitch
    Properties:
      VpcId:
        Ref: MyVpc.Vpc
      CidrBlock: 192.168.1.0/24
      ZoneId:
        Fn::Select:
          - '0'
          - Fn::GetAZs:
              Ref: ALIYUN::Region
      VSwitchName: sample_vsw
Outputs:
  VpcId:
    Value:
      Fn::GetAtt:
        - MyVpc.Vpc
        - VpcId

引用模块中的输出

您可以把模块当作资源,其输出当作资源属性,使用Fn::GetAttFn::Sub内部函数访问模块输出。更多信息,请参见输出(Outputs)

// Fn::GetAtt示例
GetAtt Example1:
  Fn::GetAtt:
    - ModuleLogicalName
    - OutputName
GetAtt Example2:
  Fn::GetAtt:
    - ModuleLogicalName.ChildModuleLogicalName
    - OutputName

// Fn::Sub示例
Sub Example1:
  Fn::Sub: "${ModuleLogicalName.OutputName}"
Sub Example2:
  Fn::Sub: "${ModuleLogicalName.ChildModuleLogicalName.OutputName}"

引用模块中的条件

您可以把模块当作命名空间,从而得到完全限定名称,使用Fn::IfFn::OrFn::AndFn::Not内部函数来访问模块中的条件。更多信息,请参见条件(Conditions)

// Fn::If示例
If Example1:
  Fn::If:
    - ModuleLogicalName.ConditionName
    - Value for true
    - Value for false
If Example2:
  Fn::If:
    - ModuleLogicalName.ChildModuleLogicalName.ConditionName
    - Value for true
    - Value for false

// Fn::Or示例
Or Example:
  Fn::Or:
    - ModuleLogicalName.ConditionName
    - ModuleLogicalName.ChildModuleLogicalName.ConditionName

// Fn::And示例
And Example:
  Fn::And:
    - ModuleLogicalName.ConditionName
    - ModuleLogicalName.ChildModuleLogicalName.ConditionName

// Fn::Not示例
Not Example1:
  Fn::Not: ModuleLogicalName.ConditionName
Not Example2:
  Fn::Not: ModuleLogicalName.ChildModuleLogicalName.ConditionName

引用模块中的映射

您可以把模块当作命名空间,从而得到完全限定名称,使用Fn::FindInMap内部函数来访问模块中的映射。更多信息,请参见映射(Mappings)

// Fn::FindInMap示例
FindInMap Example1:
  Fn::FindInMap:
    - ModuleLogicalName.MappingName
    - Key
    - SubKey
FindInMap Example2:
  Fn::FindInMap:
    - ModuleLogicalName.ChildModuleLogicalName.MappingName
    - Key
    - SubKey

依赖模块中的资源

您需要使用资源的完全限定逻辑名称实现依赖模块中的资源。

Resource1:
  DependsOn: ModuleLogicalName.ResourceLogicalName
Resource2:
  DependsOn: ModuleLogicalName.ChildModuleLogicalName.ResourceLogicalName

依赖模块

资源(或模块)如果依赖于模块,则依赖于模块及其子模块中的所有资源。您需要使用模块的完全限定逻辑名称实现依赖模块。

Resource1:
  DependsOn: ModuleLogicalName
Resource2:
  DependsOn: ModuleLogicalName.ChildModuleLogicalName

注意事项

下列是使用模块的相关注意事项。

  • 使用模块不收取任何额外费用,您只需为模块解析到资源栈中的资源付费。

  • 如果模板使用了模块,模板会增加如下限制:

    • 参数名称中不能包含字符:.:

    • 资源逻辑名称中不能包含字符:.

    • 输出名称中不能包含字符:.

    • 条件名称中不能包含字符:&

    • 不能为模板指定TransformWorkspace

    • 不能为模块指定MetadataCount

    • 资源或模块的完全限定逻辑名称、条件完全限定名称和映射完全限定名称都不能重复。

  • ROS配额(例如资源栈中允许的最大资源数或模板正文的最多内容)适用于处理过的模板,无论该模板中包含的资源是否来自模块。更多信息,请参见使用限制

  • 您在资源栈级别指定的标签、资源组将分配给来自模块的各个资源。

  • 处理模板时,模块中的MetadataRules会被忽略。

  • 处理模块时,不会解析动态引用,而是在资源栈操作期间创建或更新单个资源时解析动态引用。关于动态引用的更多信息,请参见动态引用

  • 模块的输出不会传播变成模板的输出。您可以创建模板输出并引用模块输出。更多信息,请参见引用模块中的输出

  • 模块的参数不会传播变成模板的参数。您可以创建模板参数,然后在模块参数中引用该模板参数。更多信息,请参见使用模板参数指定模块属性

  • 如果使用模块时指定版本为默认版本(default),更改模块的默认版本不会启动任何资源栈更新操作。

    但是,在您下次使用包含该模块的任何模板执行资源栈操作(例如资源栈更新)时, ROS将在操作中使用新的默认版本。

  • 如果使用模块时指定版本为最新版本(latest),创建新的模块版本或删除最新模块版本不会启动任何资源栈更新操作。

    但是,在您下次使用包含该模块的任何模板执行资源栈操作(例如资源栈更新)时, ROS将在操作中使用新的最新版本。

  • 在资源栈操作期间,ROS会使用当前账户中注册的模块,包括嵌套在其他模块中的模块。

    如果您在不同账号的同一个模块的版本不一致,则使用同一个模板可能会导致不同的结果。

  • 为了保证结果统一,如果要在资源栈模板中纳入模块以用于资源栈组,则应确保在计划部署资源栈实例的所有账户中模块的一致性,其中包括嵌套在其他模块中的模块。更多信息,请参见资源栈组

    说明

    如果您想要在资源栈组所在账号中展开模块,需要在创建或更新资源栈组时勾选是否在当前账号展开模块