如何优化AWS CodePipeline,仅在指定时段向EC2部署代码?
Great question! Since your EC2 instances only run between 7:00-21:00, you need a reliable way to gate your CodePipeline deployments to that window. Here are two practical, AWS-native approaches to implement the time-based check you're thinking about:
Approach 1: Add a Lambda Check Stage Before Each CodeDeploy Action
This method inserts a validation step directly into your pipeline, ensuring deployments only proceed during your EC2's active window.
Step-by-Step Setup:
Create a Time-Check Lambda Function
Write a Python (or your preferred language) function that checks if the current time falls within your target window. Remember AWS uses UTC by default, so convert to your local timezone first:import datetime import pytz import json def lambda_handler(event, context): # Set your target timezone (e.g., Beijing/Shanghai time) target_tz = pytz.timezone('Asia/Shanghai') current_hour = datetime.datetime.now(target_tz).hour # Check if we're within 7:00-21:00 if 7 <= current_hour < 21: # Return success to let the pipeline proceed return { 'statusCode': 200, 'body': json.dumps("Deployment window active. Proceeding to deploy.") } else: # Throw an exception to trigger pipeline retries raise Exception(f"Current time ({current_hour}:00) is outside deployment window. Will retry later.")Attach an IAM policy to this Lambda that allows it to interact with CodePipeline (specifically
codepipeline:PutJobSuccessResultandcodepipeline:PutJobFailureResult).Insert the Lambda Stage into Your Pipeline
- Open your CodePipeline in the AWS Console.
- For both
codedeploy_to_testandcodedeploy_to_prodstages, add a new Invoke action before the CodeDeploy action. - Configure the action to use your time-check Lambda function.
- Enable Retry Policy for this action: set a retry interval (e.g., 1 hour) and maximum retry attempts (or leave it unlimited if you want it to keep trying until the window opens).
How It Works:
When the pipeline runs, the Lambda will first validate the time. If it's within your window, the pipeline moves to CodeDeploy. If not, the Lambda throws an error, triggering the retry policy—so the pipeline will pause and retry every hour until the deployment window opens.
Approach 2: Filter S3 Trigger Events with Lambda (Avoid Pipeline Runs Outside Windows)
If you prefer to prevent the pipeline from starting entirely during off-hours, you can add a Lambda filter between your S3 trigger and CodePipeline.
Step-by-Step Setup:
- Modify Your CloudWatch Events Trigger
- Instead of pointing your S3 object-creation event directly to CodePipeline, update the rule to send events to a new Lambda function.
- Build the Event Filter Lambda
This function will check the time, and only trigger the pipeline if it's within your window. For off-hour events, you can queue them to process later:import boto3 import datetime import pytz from botocore.exceptions import ClientError codepipeline = boto3.client('codepipeline') sqs = boto3.client('sqs') def lambda_handler(event, context): target_tz = pytz.timezone('Asia/Shanghai') current_hour = datetime.datetime.now(target_tz).hour if 7 <= current_hour < 21: # Trigger the pipeline immediately try: codepipeline.start_pipeline_execution( name='Your-Pipeline-Name' ) return {'statusCode': 200, 'body': "Pipeline triggered successfully."} except ClientError as e: return {'statusCode': 500, 'body': str(e)} else: # Send the event to an SQS queue for later processing sqs.send_message( QueueUrl='Your-SQS-Queue-URL', MessageBody=str(event) ) return {'statusCode': 202, 'body': "Event queued for deployment window."} - Add a Scheduled Trigger for Off-Hour Events
Create a CloudWatch Events rule that runs daily at 7:00 AM (your local time) and triggers another Lambda function. This function will read the SQS queue and start the pipeline for all queued events.
How It Works:
Off-hour S3 changes are stored in SQS instead of triggering the pipeline. At the start of your deployment window, the scheduled Lambda processes all queued events and runs the pipeline—ensuring all off-hour changes are deployed once your EC2 instances are active.
Key Notes:
- Timezone Awareness: Always convert UTC time to your local timezone in Lambda functions to avoid mismatches.
- IAM Permissions: Make sure all Lambda functions have the necessary permissions to interact with CodePipeline, SQS, and CloudWatch Events.
- Retry vs. Queuing: Choose Approach 1 if you want immediate retries once the window opens, or Approach 2 if you prefer batch processing of off-hour changes.
内容的提问来源于stack exchange,提问作者user389955

