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

CloudFormation移除参数短横线及嵌套栈资源命名适配咨询

CloudFormation中动态移除栈名短横线的解决方案

你说得完全对——CloudFormation的内置函数(比如Fn::Split/Fn::Select)只能处理短横线数量固定的场景,没法直接实现全局替换。不过我之前解决过类似的问题,有两种靠谱的方法可以满足你的需求,适配任意数量短横线的栈名称:

方案1:使用CloudFormation宏(推荐复用场景)

宏是CloudFormation的扩展功能,允许你自定义字符串处理逻辑,非常适合这种全局替换的需求。你只需要创建一次宏,之后所有模板都能调用它来清理栈名称。

第一步:部署字符串替换宏

先创建一个包含Lambda函数的宏模板,这个Lambda会用正则做全局替换:

AWSTemplateFormatVersion: '2010-09-09'
Resources:
  StringReplaceMacro:
    Type: AWS::CloudFormation::Macro
    Properties:
      Name: StringReplace
      FunctionName: !GetAtt StringReplaceFunction.Arn

  StringReplaceFunction:
    Type: AWS::Lambda::Function
    Properties:
      Runtime: python3.9
      Handler: index.lambda_handler
      Role: !GetAtt LambdaExecutionRole.Arn
      Code:
        ZipFile: |
          import re
          def lambda_handler(event, context):
              raw_str = event['params']['RawString']
              old_char = event['params']['OldChar']
              new_char = event['params']['NewChar']
              # 全局替换目标字符
              processed_str = re.sub(old_char, new_char, raw_str)
              return {
                  "requestId": event['requestId'],
                  "status": "success",
                  "fragment": processed_str
              }

  LambdaExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole

部署这个模板后,你的账号里就有了一个可复用的字符串替换宏。

第二步:在嵌套栈中调用宏

现在可以在你的模板里用这个宏处理AWS::StackName,生成符合要求的资源名:

AWSTemplateFormatVersion: '2010-09-09'
Transform:
  - StringReplace

Resources:
  # S3存储桶:移除短横线+转全小写
  MyAppS3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !ToLower 
        !Join ['-', [
            !StringReplace {
              RawString: !Ref AWS::StackName,
              OldChar: '-',
              NewChar: ''
            },
            'app-data-bucket'
          ]]

  # Cognito身份池:仅移除短横线
  MyAppIdentityPool:
    Type: AWS::Cognito::IdentityPool
    Properties:
      IdentityPoolName: !Join ['-', [
          !StringReplace {
            RawString: !Ref AWS::StackName,
            OldChar: '-',
            NewChar: ''
          },
          'user-identity-pool'
        ]]
      AllowUnauthenticatedIdentities: false

不管你的栈名有多少个短横线,都会被全部替换为空,完美适配动态场景。

方案2:使用自定义Lambda资源(适合单次使用)

如果不想维护宏,也可以直接在模板里定义自定义资源,通过Lambda函数返回处理后的字符串:

AWSTemplateFormatVersion: '2010-09-09'
Resources:
  # 自定义资源:处理栈名称
  CleanStackName:
    Type: Custom::CleanString
    Properties:
      ServiceToken: !GetAtt CleanStringFunction.Arn
      RawString: !Ref AWS::StackName
      RemoveChar: '-'

  CleanStringFunction:
    Type: AWS::Lambda::Function
    Properties:
      Runtime: python3.9
      Handler: index.lambda_handler
      Role: !GetAtt LambdaExecutionRole.Arn
      Code:
        ZipFile: |
          import re
          import cfnresponse

          def lambda_handler(event, context):
              try:
                  raw_str = event['ResourceProperties']['RawString']
                  remove_char = event['ResourceProperties']['RemoveChar']
                  cleaned_str = re.sub(remove_char, '', raw_str)
                  cfnresponse.send(event, context, cfnresponse.SUCCESS, {'CleanedString': cleaned_str})
              except Exception as e:
                  cfnresponse.send(event, context, cfnresponse.FAILED, {'Error': str(e)})

  LambdaExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole

  # 使用处理后的名称创建资源
  MyAppS3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !ToLower 
        !Join ['-', [
            !GetAtt CleanStackName.CleanedString,
            'app-data-bucket'
          ]]

  MyAppIdentityPool:
    Type: AWS::Cognito::IdentityPool
    Properties:
      IdentityPoolName: !Join ['-', [
          !GetAtt CleanStackName.CleanedString,
          'user-identity-pool'
        ]]
      AllowUnauthenticatedIdentities: false

这种方案不需要额外管理宏,所有逻辑都在当前模板里,适合只在单个模板中使用的场景。

小提示

  • S3桶名必须全小写,所以一定要加上!ToLower确保合规。
  • 宏的方案更适合多模板复用,一次部署后可以在所有需要字符串处理的模板中调用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:26:21