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

使用CloudFormation::Init将本地.zip文件复制到新建EC2实例

解决CloudFormation::Init部署本地制品到EC2的问题

方法一:自定义CloudFormation宏替换本地路径为S3 URL

你可以通过自定义CloudFormation宏,自动替换AWS::CloudFormation::Init的sources字段中的本地路径为对应S3 URL,步骤如下:

  1. 上传本地制品到S3
    先将本地的website.zip上传到目标S3桶:

    aws s3 cp applications/website.zip s3://your-target-bucket/path/website.zip
    
  2. 创建宏对应的Lambda函数
    编写Lambda函数遍历模板的Metadata部分,替换指定的本地路径。示例Python代码:

    import json
    
    def lambda_handler(event, context):
        template = event['fragment']
        # 定位到Init的sources配置
        init_sources = template.get('Metadata', {}).get('AWS::CloudFormation::Init', {}).get('config', {}).get('sources', {})
        # 替换目标路径
        for target_dir, local_path in init_sources.items():
            if local_path == 'applications/website.zip':
                init_sources[target_dir] = 's3://your-target-bucket/path/website.zip'
        # 返回修改后的模板
        return {
            'requestId': event['requestId'],
            'status': 'success',
            'fragment': template
        }
    
  3. 注册CloudFormation宏
    通过CloudFormation模板注册上述Lambda函数为宏:

    AWSTemplateFormatVersion: '2010-09-09'
    Resources:
      ReplaceLocalPathMacro:
        Type: AWS::CloudFormation::Macro
        Properties:
          Name: ReplaceLocalPath
          FunctionName: !Ref ReplaceLocalPathLambda
      ReplaceLocalPathLambda:
        Type: AWS::Lambda::Function
        Properties:
          Runtime: python3.9
          Handler: index.lambda_handler
          Code:
            ZipFile: |
              import json
    
              def lambda_handler(event, context):
                  template = event['fragment']
                  init_sources = template.get('Metadata', {}).get('AWS::CloudFormation::Init', {}).get('config', {}).get('sources', {})
                  for target_dir, local_path in init_sources.items():
                      if local_path == 'applications/website.zip':
                          init_sources[target_dir] = 's3://your-target-bucket/path/website.zip'
                  return {
                      'requestId': event['requestId'],
                      'status': 'success',
                      'fragment': template
                  }
          Role: !GetAtt LambdaExecutionRole.Arn
      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
    
  4. 在Webserver模板中启用宏
    在你的EC2堆栈模板开头添加Transform字段:

    AWSTemplateFormatVersion: '2010-09-09'
    Transform: ReplaceLocalPath
    # 剩余模板内容...
    

    部署时宏会自动替换sources中的本地路径为S3 URL。

方法二:预上传制品+参数化引用

这是更轻量化的方案,无需自定义宏:

  1. 上传本地文件到S3
    执行和方法一相同的s3 cp命令完成上传。

  2. 修改模板添加参数
    将S3 URL通过参数传入模板:

    AWSTemplateFormatVersion: '2010-09-09'
    Parameters:
      WebsiteArtifactS3Url:
        Type: String
        Description: S3 URL of the website.zip artifact
    
    Resources:
      WebServerInstance:
        Type: AWS::EC2::Instance
        Metadata:
          AWS::CloudFormation::Init:
            config:
              packages:
                yum:
                  npm: []
              sources:
                /home/ec2-user/developer-site: !Ref WebsiteArtifactS3Url
        # 实例其他配置...
    
  3. 部署时传递参数

    aws cloudformation deploy --stack-name WebServerStack --template-file your-template.yaml --parameter-overrides WebsiteArtifactS3Url=s3://your-target-bucket/path/website.zip
    

方法三:结合package命令与文本替换

如果模板中有其他需要cloudformation package处理的资源(如Lambda函数),可以先处理模板再替换路径:

  1. 模板中使用占位符
    将本地路径替换为占位符:

    sources:
      /home/ec2-user/developer-site: {{WEBSITE_S3_URL}}
    
  2. 运行package命令处理其他资源

    aws cloudformation package --template-file your-template.yaml --s3-bucket your-package-bucket --output-template-file packaged-template.yaml
    
  3. 上传制品并替换占位符

    # 上传本地文件
    aws s3 cp applications/website.zip s3://your-target-bucket/path/website.zip
    # 替换占位符
    sed -i 's|{{WEBSITE_S3_URL}}|s3://your-target-bucket/path/website.zip|g' packaged-template.yaml
    
  4. 部署处理后的模板

    aws cloudformation deploy --stack-name WebServerStack --template-file packaged-template.yaml
    

内容的提问来源于stack exchange,提问作者Pedro Hoehl Carvalho

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 20:38:22