参数 - Amazon CloudFormation
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

参数

使用可选的 Parameters 部分来自定义模板。利用参数,您能够在每次创建或更新堆栈时将自定义值输入模板。

在模板中定义参数

以下示例声明名为 InstanceTypeParameter 的参数。利用此参数,您可以为堆栈指定 Amazon EC2 实例类型以在创建或更新堆栈时使用。

请注意,InstanceTypeParameter 具有默认值 t2.micro。除非提供有其他值,否则这是 Amazon CloudFormation 用于预置堆栈的值。

JSON

"Parameters" : { "InstanceTypeParameter" : { "Type" : "String", "Default" : "t2.micro", "AllowedValues" : ["t2.micro", "m1.small", "m1.large"], "Description" : "Enter t2.micro, m1.small, or m1.large. Default is t2.micro." } }

YAML

Parameters: InstanceTypeParameter: Type: String Default: t2.micro AllowedValues: - t2.micro - m1.small - m1.large Description: Enter t2.micro, m1.small, or m1.large. Default is t2.micro.

在模板中引用参数

您使用 Ref 内部函数来引用某个参数,Amazon CloudFormation 使用该参数的值来预置堆栈。您可以引用同一模板的 ResourcesOutputs 部分中的参数。

在以下示例中,EC2 实例资源的 InstanceType 属性引用了 InstanceTypeParameter 参数值:

JSON

"Ec2Instance" : { "Type" : "AWS::EC2::Instance", "Properties" : { "InstanceType" : { "Ref" : "InstanceTypeParameter" }, "ImageId" : "ami-0ff8a91507f77f867" } }

YAML

Ec2Instance: Type: AWS::EC2::Instance Properties: InstanceType: Ref: InstanceTypeParameter ImageId: ami-0ff8a91507f77f867

参数的一般要求

使用参数时存在以下要求:

  • 一个 Amazon CloudFormation 模板中最多可包含 200 个参数。

  • 必须为每个参数提供一个逻辑名称 (也称为逻辑 ID),该名称必须是字母数字,并且在模板内的所有逻辑名称中必须是唯一的。

  • 必须向每个参数分配一个受 Amazon CloudFormation 支持的参数类型。有关更多信息,请参阅类型

  • 必须向每个参数分配一个运行时的值,使 Amazon CloudFormation 能够成功预置堆栈。您可以选择为要使用的 Amazon CloudFormation 指定默认值,除非提供有其他值。

  • 必须在同一模板内声明和引用参数。您可以引用模板的 ResourcesOutputs 部分中的参数。

JSON

"Parameters" : { "ParameterLogicalID" : { "Type" : "DataType", "ParameterProperty" : "value" } }

YAML

Parameters: ParameterLogicalID: Type: DataType ParameterProperty: value

属性

AllowedPattern

一个正则表达式,表示要允许 StringCommaDelimitedList 类型使用的模式。应用于类型为 String 的参数时,模式必须与提供的整个参数值匹配。应用于类型为 CommaDelimitedList 的参数时,模式必须与列表中的每个值匹配。

必需:否

AllowedValues

包含参数允许值列表的阵列。应用于类型为 String 的参数时,该参数值必须是允许的值之一。应用于类型为 CommaDelimitedList 的参数时,列表中的每个值都必须是指定的允许的值之一。

必需:否

注意

如果您使用 YAML,并且想要在 AllowedValues 中使用 YesNo 字符串,请使用单引号来防止 YAML 解析器考虑这些布尔值。

ConstraintDescription

用于在违反约束时说明该约束的字符串。例如,在没有约束条件描述的情况下,具有允许的 [A-Za-z0-9]+ 模式的参数会在用户指定无效值时显示以下错误消息:

Malformed input-Parameter MyParameter must match pattern [A-Za-z0-9]+

通过添加约束描述(如 must only contain letters (uppercase and lowercase) and numbers),您可以显示以下自定义的错误消息:

Malformed input-Parameter MyParameter must only contain uppercase and lowercase letters and numbers

必需:否

Default

模板适当类型的值,用于在创建堆栈时未指定值的情况下。如果您定义参数的约束,则必须指定一个符合这些约束的值。

必需:否

Description

用于描述参数的长度最多为 4000 个字符的字符串。

必需:否

MaxLength

一个整数值,确定要允许 String 类型使用的字符的最大数目。

必需:否

MaxValue

一个数字值,确定要允许 Number 类型使用的最大数字值。

必需:否

MinLength

一个整数值,确定要允许 String 类型使用的字符的最小数目。

必需:否

MinValue

一个数字值,确定要允许 Number 类型使用的最小数字值。

必需:否

NoEcho

是否遮蔽参数值以防止在控制台、命令行或 API 中显示。如果您将 NoEcho 属性设置为 true,则对于描述堆栈或堆栈事件的任何调用,CloudFormation 返回使用星号 (*****) 遮蔽的参数值,但存储在下面指定位置的信息除外。

必需:否

重要

使用 NoEcho 属性不会遮蔽在以下各区段中存储的任何信息:

  • Metadata 模板区段。CloudFormation 不会转换、修改或编辑您在 Metadata 部分中包含的任何信息。有关更多信息,请参阅元数据

  • Outputs 模板区段。有关更多信息,请参阅输出

  • 资源定义的 Metadata 属性。有关更多信息,请参阅Metadata 属性

强烈建议您不要使用这些机制来包含敏感信息,例如密码。

重要

我们建议不要将敏感信息直接嵌入 CloudFormation 模板中,而应使用堆栈模板中的动态参数来引用在 CloudFormation 外部存储和管理的敏感信息,例如 Amazon Systems Manager Parameter Store 或 Amazon Secrets Manager 中的敏感信息。

有关更多信息,请参阅 请勿将凭证嵌入您的模板 最佳实践。

重要

我们建议不要在作为资源主标识符一部分的资源属性中包含 NoEcho 参数或任何敏感数据。

NoEcho 参数包含在构成主资源标识符的属性中时,CloudFormation 可能会在主资源标识符中使用实际明文值。此资源 ID 可能出现在任何派生输出或目标中。

要确定哪些资源属性构成了资源类型的主标识符,请参阅该资源的资源参考文档。在 Return values(返回值)部分,Ref 函数返回值,表示构成资源类型主标识符的资源属性。

Type

参数 (DataType) 的数据类型。

必需:是

Amazon CloudFormation 支持以下参数类型:

String

一个文字字符串。

例如,用户可指定 "MyUserName"

Number

整数或浮点数。Amazon CloudFormation 将参数值验证为数字;但当您在模板中的其他位置使用该参数时(例如,通过使用 Ref 内部函数),该参数值将变成字符串。

例如,用户可指定 "8888"

List<Number>

一组用逗号分隔的整数或浮点数。Amazon CloudFormation 将参数值验证为数字,但当您在模板中的其他位置使用该参数时(例如,通过使用 Ref 内部函数),该参数值将变成字符串列表。

例如,用户可指定 "80,20",并且 Ref 将生成 ["80","20"]

CommaDelimitedList

一组用逗号分隔的文本字符串。字符串的总数应比逗号总数多 1。此外,会对每个成员字符串进行空间修剪。

例如,用户可指定 "test,dev,prod",并且 Ref 将生成 ["test","dev","prod"]

特定于 Amazon 的参数类型

Amazon 值,例如 Amazon EC2 密钥对名称和 VPC ID。有关更多信息,请参阅特定于 Amazon 的参数类型

SSM 参数类型

与 Systems Manager Parameter Store 中的现有参数对应的参数。您指定 Systems Manager 参数密钥作为 SSM 参数的值,并且 Amazon CloudFormation 从 Parameter Store 提取最新值来用于堆栈。有关更多信息,请参阅SSM 参数类型

特定于 Amazon 的参数类型

要在开始创建或更新堆栈时捕获无效值,特定于 Amazon 的参数类型很有帮助。要使用特定于 Amazon 的类型指定参数,模板用户必须输入其 Amazon 账户中的现有 Amazon 值。Amazon CloudFormation 针对该账户中的现有值来验证这些输入值。例如,对于 AWS::EC2::VPC::Id 参数类型,用户必须输入在其中创建堆栈的账户和区域中的现有 VPC ID

如果要允许模板用户输入来自不同 Amazon 账户的输入值,请不要使用特定于 Amazon 的类型来定义参数,反之,您可以定义类型为 StringCommaDelimitedList 的参数。

支持的特定于 Amazon 的参数类型

Amazon CloudFormation 支持以下特定于 Amazon 的类型:

AWS::EC2::AvailabilityZone::Name

可用区,如 us-west-2a

AWS::EC2::Image::Id

Amazon EC2 映像 ID,如 ami-0ff8a91507f77f867。请注意,Amazon CloudFormation 控制台不会显示此参数类型的值的下拉列表。

AWS::EC2::Instance::Id

Amazon EC2 实例 ID,如 i-1e731a32

AWS::EC2::KeyPair::KeyName

Amazon EC2 密钥对名称。

AWS::EC2::SecurityGroup::GroupName

EC2-Classic 或默认 VPC 安全组名称,如 my-sg-abc

AWS::EC2::SecurityGroup::Id

安全组 ID,如 sg-a123fd85

AWS::EC2::Subnet::Id

子网 ID,如 subnet-123a351e

AWS::EC2::Volume::Id

Amazon EBS 卷 ID,如 vol-3cdd3f56

AWS::EC2::VPC::Id

VPC ID,如 vpc-a123baa3

AWS::Route53::HostedZone::Id

Amazon Route 53 托管区域 ID,如 Z23YXV4OVPL04A

List<AWS::EC2::AvailabilityZone::Name>

针对某个区域的一组可用区,如 us-west-2a, us-west-2b

List<AWS::EC2::Image::Id>

一组 Amazon EC2 映像 ID,如 ami-0ff8a91507f77f867, ami-0a584ac55a7631c0c。请注意,Amazon CloudFormation 控制台不会显示此参数类型的值的下拉列表。

List<AWS::EC2::Instance::Id>

一组 Amazon EC2 实例 ID,如 i-1e731a32, i-1e731a34

List<AWS::EC2::SecurityGroup::GroupName>

一组 EC2-Classic 或默认 VPC 安全组名称,如 my-sg-abc, my-sg-def

List<AWS::EC2::SecurityGroup::Id>

一组安全组 ID,如 sg-a123fd85, sg-b456fd85

List<AWS::EC2::Subnet::Id>

一组子网 ID,如 subnet-123a351e, subnet-456b351e

List<AWS::EC2::Volume::Id>

一组 Amazon EBS 卷 ID,如 vol-3cdd3f56, vol-4cdd3f56

List<AWS::EC2::VPC::Id>

一组 VPC ID,如 vpc-a123baa3, vpc-b456baa3

List<AWS::Route53::HostedZone::Id>

一组 Amazon Route 53 托管区域 ID,如 Z23YXV4OVPL04A, Z23YXV4OVPL04B

SSM 参数类型

SSM 参数类型与 Systems Manager Parameter Store 中的现有参数对应。您指定 Systems Manager 参数密钥作为 SSM 参数的值,并且 Amazon CloudFormation 从 Parameter Store 提取最新值来用于堆栈。对于存储在相同 Amazon Web Services 账户 的 SSM 参数,请输入参数名称。对于其他 Amazon Web Services 账户 共享的 SSM 参数,请输入完整的参数 ARN。有关 Systems Manager 参数的更多信息,请参阅《Amazon Systems Manager 用户指南》中的 Systems Manager Parameter Store使用共享参数

您也可以使用 ssmssm-secure 动态参数模式在模板中指定参数。有关更多信息,请参阅使用动态引用以指定模板值

当您创建或更新堆栈并创建更改集时,Amazon CloudFormation 会在此操作运行时使用 Parameter Store 中存在的任何值。如果某个指定的参数在调用方的 Amazon 账户下的参数仓库中不存在,Amazon CloudFormation 会返回验证错误。

当您执行更改集时,Amazon CloudFormation 将使用在更改集中指定的值。您应在执行更改集前检查这些值,因为在您创建更改集和运行更改集之间的时间内,它们可能会在 Parameter Store 中发生更改。

提示

您可以在控制台中或通过运行 describe-stacksdescribe-change-set 来查看堆栈的 Parameters(参数)选项卡上 SSM 参数的解析值。这些是目前在堆栈定义中用于相应的 Systems Manager 参数键的值。请注意,这些值是在创建或更新堆栈时设置的,因此它们可能与 Parameter Store 中的最新值不同。

如果您使用 ssm-secure 模式指定参数值作为安全字符串,Amazon CloudFormation 不会存储安全字符串值或将其显示在控制台中或 API 调用的结果中。

由于 SSM 参数的值是 Systems Manager 参数键,因此您应了解以下行为:

  • 对于堆栈更新,控制台中的 Use existing value(使用现有值)选项和 update-stackUsePreviousValue 属性告知 Amazon CloudFormation 使用现有 Systems Manager 参数密钥,而不是其值。Amazon CloudFormation 在更新堆栈时始终从 Parameter Store 中提取最新值。

    但是,如果您使用 ssmssm-secure 动态参数模式来指定参数值,您必须指 Systems Manager 参数的版本以便 Amazon CloudFormation 使用。

  • Amazon CloudFormation 可以对 Systems Manager 参数密钥执行验证,但不能对其对应的值执行验证。为了进行验证,您可以将参数键视为字符串。您应为 Parameter Store 中的 Systems Manager 参数值执行任何验证。

有关使用 SSM 参数类型的示例,请参阅 SSM 参数类型

支持的 SSM 参数类型

Amazon CloudFormation 支持以下 SSM 参数类型:

AWS::SSM::Parameter::Name

Systems Manager 参数键的名称。

请在您要传递参数键时使用此参数。例如,您可以使用此类型验证此参数是否存在。

AWS::SSM::Parameter::Value<String>

其值是字符串的 Systems Manager 参数。这与 Parameter Store 中的 String 参数对应。

AWS::SSM::Parameter::Value<List<String>>AWS::SSM::Parameter::Value<CommaDelimitedList>

其值是字符串列表的 Systems Manager 参数。这与 Parameter Store 中的 StringList 参数对应。

AWS::SSM::Parameter::Value<AWS-specific parameter type>

其值是 特定于 Amazon 的参数类型的 Systems Manager 参数。例如,下面指定了 AWS::EC2::KeyPair::KeyName 类型:

AWS::SSM::Parameter::Value<AWS::EC2::KeyPair::KeyName>

AWS::SSM::Parameter::Value<List<AWS-specific parameter type>>

其值是 特定于 Amazon 的参数类型列表的 Systems Manager 参数。例如,下面指定了 AWS::EC2::KeyPair::KeyName 类型的列表:

AWS::SSM::Parameter::Value<List<AWS::EC2::KeyPair::KeyName>>

不支持的 SSM 参数类型

Amazon CloudFormation 不支持以下 SSM 参数类型:

  • SSM 参数类型的列表,例如:List<AWS::SSM::Parameter::Value<String>>

此外,Amazon CloudFormation 不支持将模板参数定义为 SecureString Systems Manager 参数类型。但是,您可以使用动态参数模式为某些资源指定安全字符串作为参数。有关更多信息,请参阅使用动态引用以指定模板值

在 Amazon CloudFormation 控制台中对参数进行分组和排序

使用 Amazon CloudFormation 控制台创建或更新堆栈时,控制台根据输入参数的逻辑 ID 按照字母顺序列出输入参数。要覆盖默认排序方式,您可以使用 AWS::CloudFormation::Interface 元数据键。通过对参数进行分组和排序,用户可更轻松地指定参数值。例如,您可以将所有 VPC 相关参数放到一个组中,免得它们散落在按字母排序的列表中而难以查找。

在元数据键中,您可以指定要创建的组、每个组包含的参数以及控制台在其分组中显示各个参数时的顺序。此外,您还可以定义易记参数名称,以便控制台显示描述性名称而不是逻辑 ID。在元数据键中引用的所有参数都必须在模板的 Parameters 部分中声明。

有关更多信息和 AWS::CloudFormation::Interface 元数据键的示例,请参阅 AWS::CloudFormation::Interface

示例

基本输入参数

以下示例 Parameters 部分声明有两个参数。DBPort 参数属于 Number 类型,默认值为 3306。可指定的最小值为 1150,可指定的最大值为 65535DBPwd 参数属于 String 类型,无默认值。NoEcho 属性设置为 true,以阻止描述堆栈调用(如 aws cloudformation describe-stacks Amazon CLI 命令)返回参数值。可指定的最小长度为 1,可指定的最大长度为 41。该模式允许小写和大写字母字符和数字。

JSON

"Parameters" : { "DBPort" : { "Default" : "3306", "Description" : "TCP/IP port for the database", "Type" : "Number", "MinValue" : "1150", "MaxValue" : "65535" }, "DBPwd" : { "NoEcho" : "true", "Description" : "The database admin account password", "Type" : "String", "MinLength" : "1", "MaxLength" : "41", "AllowedPattern" : "^[a-zA-Z0-9]*$" } }

YAML

Parameters: DBPort: Default: 3306 Description: TCP/IP port for the database Type: Number MinValue: 1150 MaxValue: 65535 DBPwd: NoEcho: true Description: The database admin account password Type: String MinLength: 1 MaxLength: 41 AllowedPattern: ^[a-zA-Z0-9]*$

特定于 Amazon 的参数类型

当您使用特定于 Amazon 的参数类型时,使用您的模板创建或更新堆栈的用户必须指定其用户账户中和当前堆栈所在区域中的现有 Amazon 值。特定于 Amazon 的参数类型可帮助确保在 Amazon CloudFormation 创建或更新任何资源之前,这些类型的输入值存在且正确。例如,如果使用 AWS::EC2::KeyPair::KeyName 参数类型,Amazon CloudFormation 在创建任何资源(如 Amazon EC2 实例)之前,将针对用户的现有密钥对名称验证输入值。

如果用户使用 Amazon Web Services Management Console,则 Amazon CloudFormation 向特定于 Amazon 的参数类型预填充有效值。这样一来,用户便无需记住和正确输入特定的名称或 ID,只需从下拉列表中选择一个或多个值。此外,根据参数类型,用户还可以按 ID、名称或名称标签值来搜索值。有关更多信息,请参阅指定堆栈名称和参数

以下示例声明类型 AWS::EC2::KeyPair::KeyNameAWS::EC2::Subnet::Id 的两个参数。这些类型限制现有密钥对名称和子网 ID 的有效值。因为将 mySubnetIDs 参数指定为列表,所以用户可指定一个或多个子网 ID。

JSON

"Parameters" : { "myKeyPair" : { "Description" : "Amazon EC2 Key Pair", "Type" : "AWS::EC2::KeyPair::KeyName" }, "mySubnetIDs" : { "Description" : "Subnet IDs", "Type" : "List<AWS::EC2::Subnet::Id>" } }

YAML

Parameters: myKeyPair: Description: Amazon EC2 Key Pair Type: "AWS::EC2::KeyPair::KeyName" mySubnetIDs: Description: Subnet IDs Type: "List<AWS::EC2::Subnet::Id>"

Amazon CLI 和 API 支持

目前,用户无法使用 Amazon CLI 或 Amazon CloudFormation API 查看特定于 Amazon 的参数的有效值列表。但用户可通过使用 aws cloudformation get-template-summary 命令或 GetTemplateSummary API 来查看有关每个参数的信息,如参数类型。

逗号分隔列表参数类型

您可使用 CommaDelimitedList 参数类型在一个参数中指定多个字符串值。这样一来,您可使用一个参数而不是许多不同的参数来指定多个值。例如,如果您使用各自不同的 CIDR 块分别创建三个不同子网,则可以使用三个不同参数指定三个不同 CIDR 块。不过更简单的方法是使用包括三个 CIDR 块的列表的单个参数,如以下代码段所示:

JSON

"Parameters" : { "DbSubnetIpBlocks": { "Description": "Comma-delimited list of three CIDR blocks", "Type": "CommaDelimitedList", "Default": "10.0.48.0/24, 10.0.112.0/24, 10.0.176.0/24" } }

YAML

Parameters: DbSubnetIpBlocks: Description: "Comma-delimited list of three CIDR blocks" Type: CommaDelimitedList Default: "10.0.48.0/24, 10.0.112.0/24, 10.0.176.0/24"

从逗号分隔列表参数返回值

要引用列表中的特定值,请在模板的 Fn::Select 部分中使用 Resources 内部函数。可传递所需对象的索引值和对象列表,如以下代码段所示:

JSON
"DbSubnet1" : { "Type" : "AWS::EC2::Subnet", "Properties" : { "AvailabilityZone" : {"Fn::Join" : ["",[ { "Ref" : "AWS::Region" }, { "Fn::Select" : [ "0", {"Ref" : "VpcAzs"} ] } ] ]} , "VpcId" : { "Ref" : "VPC" }, "CidrBlock" : { "Fn::Select" : [ "0", {"Ref" : "DbSubnetIpBlocks"} ] } } }, "DbSubnet2" : { "Type" : "AWS::EC2::Subnet", "Properties" : { "AvailabilityZone" : {"Fn::Join" : ["",[ { "Ref" : "AWS::Region" }, { "Fn::Select" : [ "1", {"Ref" : "VpcAzs"} ] } ] ]} , "VpcId" : { "Ref" : "VPC" }, "CidrBlock" : { "Fn::Select" : [ "1", {"Ref" : "DbSubnetIpBlocks"} ] } } }, "DbSubnet3" : { "Type" : "AWS::EC2::Subnet", "Properties" : { "AvailabilityZone" : {"Fn::Join" : ["",[ { "Ref" : "AWS::Region" }, { "Fn::Select" : [ "2", {"Ref" : "VpcAzs"} ] } ] ]} , "VpcId" : { "Ref" : "VPC" }, "CidrBlock" : { "Fn::Select" : [ "2", {"Ref" : "DbSubnetIpBlocks"} ] } } }
YAML
DbSubnet1: Type: AWS::EC2::Subnet Properties: AvailabilityZone: !Sub - "${AWS::Region}${AZ}" - AZ: !Select [0, !Ref VpcAzs] VpcId: !Ref VPC CidrBlock: !Select [0, !Ref DbSubnetIpBlocks] DbSubnet2: Type: AWS::EC2::Subnet Properties: AvailabilityZone: !Sub - "${AWS::Region}${AZ}" - AZ: !Select [1, !Ref VpcAzs] VpcId: !Ref VPC CidrBlock: !Select [1, !Ref DbSubnetIpBlocks] DbSubnet3: Type: AWS::EC2::Subnet Properties: AvailabilityZone: !Sub - "${AWS::Region}${AZ}" - AZ: !Select [2, !Ref VpcAzs] VpcId: !Ref VPC CidrBlock: !Select [2, !Ref DbSubnetIpBlocks]

SSM 参数类型

AWS::SSM::Parameter::Value<String> 类型

以下模板声明 AWS::SSM::Parameter::Value<String> 参数类型。

JSON
{ "Parameters": { "InstanceType": { "Type": "AWS::SSM::Parameter::Value<String>" } }, "Resources": { "Instance": { "Type": "AWS::EC2::Instance", "Properties": { "InstanceType": { "Ref": "InstanceType" } } } } }
YAML
Parameters: InstanceType: Type: 'AWS::SSM::Parameter::Value<String>' Resources: Instance: Type: 'AWS::EC2::Instance' Properties: InstanceType: !Ref InstanceType

以下命令基于示例模板创建堆栈。它提供 Systems Manager 参数键 (myInstanceType) 作为 InstanceType 模板参数的值。这假定 myInstanceType 参数在调用方的 Amazon 账户下的参数仓库中存在。

aws cloudformation create-stack --stack-name S1 --template-body example template --parameters ParameterKey=InstanceType,ParameterValue=myInstanceType

 

AWS::SSM::Parameter::Value<AWS::EC2::Image::Id> 类型

以下模板声明 AWS::SSM::Parameter::Value<AWS::EC2::Image::Id> 参数类型。

JSON
{ "Parameters": { "ImageId": { "Type": "AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>" } }, "Resources": { "Instance": { "Type": "AWS::EC2::Instance", "Properties": { "ImageId": { "Ref": "ImageId" } } } } }
YAML
Parameters: ImageId: Type: 'AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>' Resources: Instance: Type: 'AWS::EC2::Instance' Properties: ImageId: !Ref ImageId

以下命令基于示例模板创建堆栈。它提供 Systems Manager 参数键 (myLatestAMI) 作为 ImageId 模板参数的值。这假定 myLatestAMI 参数在调用方的 Amazon 账户下的参数仓库中存在。

aws cloudformation create-stack --stack-name S2 --template-body example template --parameters ParameterKey=ImageId,ParameterValue=myLatestAMI