You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在外部文本指定的CloudFormation UserData中使用内部函数

问题根因
  • CloudFormation 内置函数(!Sub、Fn::Sub、!Ref等)仅能在CloudFormation模板的YAML/JSON结构内被解析执行,你将包含这类函数的内容放在外部文件作为参数传入时,CloudFormation只会将其识别为普通文本字符串,不会触发函数执行逻辑,因此变量替换无法生效。
  • 你直接传入包含!Sub标签的文本到EC2 UserData后,cloud-init服务解析UserData时无法识别CloudFormation专属的YAML标签,就会抛出你遇到的格式报错。
可行解决方案

核心逻辑是把函数解析逻辑放在CloudFormation模板内部执行,外部文件仅保留纯脚本内容和占位符:

步骤1:调整外部UserData文件(userdata.txt)

移除所有CloudFormation专属语法,仅保留脚本内容和变量占位符:

#!/bin/bash
ENV_NAME=${EnvironmentName}
hostnamectl set-deployment $ENV_NAME

如果需要使用cloud-config格式,按cloud-init官方规范编写即可,占位符保持${变量名}格式不变。

步骤2:修改CloudFormation模板

在模板内对传入的UserData内容执行!Sub替换,再做Base64编码:

Parameters:
  EnvironmentName:
    Type: String
    Default: Development
  UserDataScript:
    Type: String

Resources:
  Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: ami-0194c3e07668a7e36
      UserData:
        Fn::Base64: !Sub !Ref UserDataScript

!Sub默认会自动匹配模板内的参数名、资源属性名作为替换变量,如果你需要自定义变量名,可以使用映射语法:

UserData:
  Fn::Base64: !Sub
    - ${script_content}
    - script_content: !Ref UserDataScript
      my_env: !Ref EnvironmentName

此时你的脚本内占位符就可以写${my_env}。

步骤3:调整CLI创建命令

传入的UserData参数仅需对纯脚本文件做Base64编码即可,注意添加-w0参数避免Base64自动换行导致格式错误:

aws cloudformation create-stack --stack-name my-stack \
        --template-body file://my-stack.yaml \
        --parameters ParameterKey=UserDataScript,ParameterValue=$(base64 -w0 userdata.txt) ParameterKey=EnvironmentName,ParameterValue=Development

内容的提问来源于stack exchange,提问作者arkie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 20:39:03