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

如何通过CloudFormation更新栈实现EC2实例文件的自动化同步更新?

Alright, let's walk through setting up this automated workflow so you can sync your local file changes to EC2 via CloudFormation with just a stack update. Here's how to do it step by step:

1. Automate Local File Upload to S3 First

First, we need to make sure every time you update the stack, your modified local file gets pushed to S3 automatically. The easiest way is to wrap the S3 upload and CloudFormation update into a single script.

Create a bash script (name it something like update-stack-with-sync.sh) with these contents:

#!/bin/bash
# Replace these values with your own
LOCAL_FILE="./your-local-file.txt"
S3_BUCKET_PATH="s3://your-bucket-name/path/to/remote-file.txt"
STACK_NAME="your-ec2-stack-name"
CFN_TEMPLATE="./your-cloudformation-template.yaml"

# Upload the updated file to S3 (enable versioning on your bucket for rollbacks!)
aws s3 cp "$LOCAL_FILE" "$S3_BUCKET_PATH"

# Trigger the CloudFormation stack update
aws cloudformation update-stack \
  --stack-name "$STACK_NAME" \
  --template-body file://"$CFN_TEMPLATE" \
  --capabilities CAPABILITY_NAMED_IAM # Add this only if your template uses IAM resources

Then make it executable:

chmod +x update-stack-with-sync.sh

From now on, after editing your local file, just run ./update-stack-with-sync.sh and it handles both upload and stack update.

2. Update Your CloudFormation Template to Sync to EC2

The original template probably copies the file once on instance creation. We need to adjust it so stack updates trigger a file sync to EC2. Here are two solid options:

Option 1: Use a Custom Resource + Lambda (Most Flexible)

This approach uses a Lambda function triggered by CloudFormation stack updates to send a command to your EC2 instance via SSM Run Command, pulling the latest file from S3.

Step 2.1 Add Lambda Resources to Your Template

Add these resources to your CloudFormation YAML:

Resources:
  # Your existing EC2 instance (keep this)
  MyEC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      # Your existing config (AMI, instance type, etc.)
      # Optional: Initial file copy on first launch
      UserData:
        Fn::Base64: !Sub |
          #!/bin/bash
          aws s3 cp s3://your-bucket-name/path/to/remote-file.txt /home/ec2-user/

  # IAM Role for Lambda to access SSM and CloudFormation
  SyncFileLambdaRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        - PolicyName: SyncFilePermissions
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - ssm:SendCommand
                  - ec2:DescribeInstances
                Resource: '*'
              - Effect: Allow
                Action:
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                Resource: 'arn:aws:logs:*:*:*'

  # Lambda Function to trigger SSM command on EC2
  SyncFileLambda:
    Type: AWS::Lambda::Function
    Properties:
      Handler: index.lambda_handler
      Runtime: python3.11
      Role: !GetAtt SyncFileLambdaRole.Arn
      Code:
        ZipFile: |
          import boto3
          ssm = boto3.client('ssm')

          def lambda_handler(event, context):
              instance_id = event['ResourceProperties']['InstanceId']
              s3_path = event['ResourceProperties']['S3FilePath']
              local_path = event['ResourceProperties']['LocalPath']

              try:
                  # Send command to EC2 to sync the file
                  response = ssm.send_command(
                      InstanceIds=[instance_id],
                      DocumentName='AWS-RunShellScript',
                      Parameters={'commands': [f'aws s3 cp {s3_path} {local_path}']}
                  )
                  return {'Status': 'SUCCESS', 'PhysicalResourceId': response['Command']['CommandId']}
              except Exception as e:
                  return {'Status': 'FAILED', 'Reason': str(e)}

  # Custom Resource that triggers Lambda on stack update
  SyncFileTrigger:
    Type: AWS::CloudFormation::CustomResource
    Properties:
      ServiceToken: !GetAtt SyncFileLambda.Arn
      InstanceId: !Ref MyEC2Instance
      S3FilePath: s3://your-bucket-name/path/to/remote-file.txt
      LocalPath: /home/ec2-user/ # Replace with your EC2 user's home directory
    DependsOn: MyEC2Instance

Notes for Option 1:

  • Your EC2 instance needs the SSM Agent installed (Amazon Linux 2/2023 have it by default) and must be able to reach SSM (either via public internet or VPC endpoints for SSM).
  • Make sure your EC2 instance's IAM role has permission to read from the S3 bucket.

Option 2: Use cfn-init (Simpler, No Lambda)

If you want to avoid Lambda, use CloudFormation's cfn-init tool to re-sync the file whenever the stack is updated. We'll add a parameter to force the sync trigger.

Step 2.1 Update Template with cfn-init

Parameters:
  FileSyncTrigger:
    Type: String
    Default: "v1"
    Description: "Change this value (e.g., v2, timestamp) to trigger a file sync on stack update"

Resources:
  MyEC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      # Your existing instance config
      UserData:
        Fn::Base64: !Sub |
          #!/bin/bash
          # Install cfn-bootstrap if not present
          yum install -y aws-cfn-bootstrap
          # Run cfn-init to sync the file
          /opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource MyEC2Instance --region ${AWS::Region}
      Metadata:
        AWS::CloudFormation::Init:
          configSets:
            default: [sync-file]
          sync-file:
            files:
              "/home/ec2-user/your-file.txt": # Target path on EC2
                source: !Sub "s3://your-bucket-name/path/to/remote-file.txt"
                mode: "000644"
                owner: "ec2-user"
                group: "ec2-user"

How Option 2 Works:

Every time you run the stack update script, just modify the FileSyncTrigger parameter (e.g., set it to v2, $(date +%s), etc.). CloudFormation detects the parameter change and re-runs cfn-init, which pulls the latest file from S3 to EC2.

3. Test the Workflow
  1. Edit your local file with changes
  2. Run your update script (for Option 1) or run the update command with a new FileSyncTrigger value (for Option 2)
  3. SSH into your EC2 instance and check the file in the home directory — it should match your local modified version!
Key Tips
  • Enable S3 Versioning on your bucket: This lets you roll back to previous file versions if something goes wrong.
  • IAM Permissions: Ensure your EC2 instance's role has s3:GetObject permission for the target file, and your local environment has permissions to run aws s3 cp and aws cloudformation update-stack.
  • SSM Access (Option 1): If your EC2 is in a private subnet, set up VPC endpoints for SSM and EC2 Messages so it can communicate with the SSM service without public internet access.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:03:24