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

如何通过CloudFormation基于东京区域今日AMIs创建对应数量EC2实例?

Alright, let's tackle this problem step by step. The core challenge here is that CloudFormation doesn't natively support dynamic resource creation based on runtime data like today's freshly backed-up AMIs. But we can solve this with a Lambda-backed Custom Resource to fetch the AMI list, then use CloudFormation's dynamic iteration tools to spin up matching EC2 instances. Here's a practical, production-ready solution:

Solution: Launch EC2 Instances Matching Today's AMIs in Tokyo Region

Core Approach

We'll break this into three key parts:

  1. A Lambda function that queries your Tokyo region (ap-northeast-1) for self-owned AMIs created today.
  2. A CloudFormation Custom Resource that invokes this Lambda to get the AMI list at stack deployment time.
  3. Dynamic EC2 instance creation using CloudFormation's Fn::ForEach to build one instance per AMI.

Step 1: Define the Lambda Function & IAM Role

First, we need a Lambda function with permissions to describe your AMIs, plus an IAM role to grant those permissions.

AWSTemplateFormatVersion: '2010-09-09'
Resources:
  # IAM Role for Lambda to access EC2 and write logs
  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
      Policies:
        - PolicyName: EC2DescribeImagesAccess
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action: ec2:DescribeImages
                Resource: '*'

  # Lambda Function to fetch today's self-owned AMIs
  FetchTodayAmisFunction:
    Type: AWS::Lambda::Function
    Properties:
      Handler: index.lambda_handler
      Runtime: python3.11
      Role: !GetAtt LambdaExecutionRole.Arn
      Code:
        ZipFile: |
          import boto3
          import datetime
          import json
          from botocore.exceptions import ClientError

          ec2 = boto3.client('ec2', region_name='ap-northeast-1')

          def lambda_handler(event, context):
              # Calculate today's start time in UTC (adjust to JST if needed)
              today = datetime.datetime.now(datetime.timezone.utc).replace(
                  hour=0, minute=0, second=0, microsecond=0
              )
              today_iso = today.isoformat()
              
              try:
                  # Filter AMIs: self-owned, created today
                  response = ec2.describe_images(
                      Owners=['self'],
                      Filters=[
                          {
                              'Name': 'creation-date',
                              'Values': [f'>={today_iso}']
                          }
                      ]
                  )
                  # Extract AMI IDs
                  ami_ids = [ami['ImageId'] for ami in response['Images']]
                  
                  # Return success to CloudFormation
                  return {
                      'Status': 'SUCCESS',
                      'PhysicalResourceId': context.log_stream_name,
                      'Data': {'AmiIds': ','.join(ami_ids)}
                  }
              except ClientError as e:
                  # Return error details if something breaks
                  return {
                      'Status': 'FAILED',
                      'PhysicalResourceId': context.log_stream_name,
                      'Reason': str(e)
                  }
      Timeout: 30

Step 2: Add the Custom Resource to Fetch AMIs

Next, we'll define a Custom Resource that calls the Lambda function to get our AMI list when the stack deploys:

# Custom Resource to retrieve today's AMIs
  TodayAmis:
    Type: Custom::FetchTodayAmis
    Properties:
      ServiceToken: !GetAtt FetchTodayAmisFunction.Arn

Step 3: Dynamically Create EC2 Instances

Finally, we use CloudFormation's Fn::ForEach (requires the latest template features) to iterate over the AMI list and create one EC2 instance per AMI:

# Dynamically create EC2 instances for each AMI
  EC2InstanceStack:
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateBody:
        AWSTemplateFormatVersion: '2010-09-09'
        Resources:
          Fn::ForEach::AmiIteration:
            - AmiId
            - !Split [",", !GetAtt TodayAmis.AmiIds]
            - !Sub "EC2Instance-${AmiId}":
                Type: AWS::EC2::Instance
                Properties:
                  ImageId: !Ref AmiId
                  InstanceType: t2.micro # Replace with your desired instance type
                  # Add your required config here: SecurityGroups, KeyName, SubnetId, etc.
                  SecurityGroups: [!Ref InstanceSecurityGroup] # Example reference

  # Example Security Group (customize to your needs)
  InstanceSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Basic security group for EC2 instances
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: 0.0.0.0/0 # Restrict this to your IP range in production

Key Notes & Customizations

  • Instance Configuration: Replace t2.micro with your preferred instance type, and add critical properties like KeyName, SubnetId, or additional SecurityGroups based on your VPC setup.
  • Timezone Adjustment: The Lambda uses UTC for the "today" cutoff. If you need to use Tokyo local time (JST, UTC+9), adjust the datetime calculation to offset accordingly.
  • AMI Filtering: If your daily backups use specific tags (e.g., BackupType: Daily), add an extra filter to the Lambda's describe_images call to avoid picking up unrelated AMIs.
  • Legacy CloudFormation Support: If you can't use Fn::ForEach, you can modify the Lambda to directly create EC2 instances—but this means CloudFormation won't manage their lifecycle (not recommended for long-term use).

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:41:08