import boto3
from datetime import datetime
def get_load_balancer_arns():
elbv2 = boto3.client('elbv2', region_name='us-east-1')
response = elbv2.describe_load_balancers()
load_balancer_arns = [lb['LoadBalancerArn'] for lb in response['LoadBalancers'] if
lb['Type'] == 'application' and not lb['Scheme'] == 'internal' and lb[
'LoadBalancerName'] not in ['in-hk-test-alb', 'CL-Pr-LoadB-26SNF9ERPK26']]
return load_balancer_arns
def create_cloudwatch_alarm(alarm_name, load_balancer_name):
cloudwatch = boto3.client('cloudwatch', region_name='us-east-1')
response = cloudwatch.put_metric_alarm(
AlarmName=alarm_name,
MetricName='TargetResponseTime',
Namespace='AWS/ApplicationELB',
Statistic='Average',
Dimensions=[
{
'Name': 'LoadBalancer',
'Value': load_balancer_name
},
],
Period=60,
EvaluationPeriods=20,
DatapointsToAlarm=1,
Threshold=5.0,
ComparisonOperator='GreaterThanOrEqualToThreshold',
TreatMissingData='notBreaching', #notBreaching缺失数据不告警;missing缺失数据告警
Unit='Seconds'
)
def create_route53_health_check(alarm_name):
route53 = boto3.client('route53')
current_time = datetime.now().strftime("%Y-%m-%d-%H:%M:%S")
response = route53.create_health_check(
CallerReference=f'{current_time}',
HealthCheckConfig={
'Type': 'CLOUDWATCH_METRIC',
'Inverted': False,
'Disabled': False,
'AlarmIdentifier': {
'Region': 'us-east-1',
'Name': f'{alarm_name}'
},
'InsufficientDataHealthStatus': 'LastKnownStatus'
}
)
health_check_arn = response["HealthCheck"]["Id"]
return health_check_arn
def shield_is_alb_protected(alb_arn):
shield = boto3.client('shield')
protected_resources = []
response = shield.list_protections(MaxResults=100)
protected_resources.extend([protection['ResourceArn'] for protection in response['Protections']])
while 'NextToken' in response:
response = shield.list_protections(MaxResults=100, NextToken=response['NextToken'])
protected_resources.extend([protection['ResourceArn'] for protection in response['Protections']])
return alb_arn in protected_resources
def create_shield_protection(alb_arn, protection_name):
shield = boto3.client('shield')
response = shield.create_protection(
Name=protection_name,
ResourceArn=alb_arn
)
return response
def protect_alb(alb_arn):
protection_name = alb_arn.split("/")[-1]
response = create_shield_protection(alb_arn, protection_name)
protection_id = response['ProtectionId']
return protection_id
def associate_health_check(health_check_arn, protection_id):
shield = boto3.client('shield')
response = shield.associate_health_check(
ProtectionId=protection_id,
HealthCheckArn=health_check_arn
)
return response
def enable_shield_automatic_response(resource_arn, action):
shield = boto3.client('shield')
response = shield.enable_application_layer_automatic_response(ResourceArn=resource_arn,Action={f'{action}':{}})
return response
# Usage
# Check if ALB is protected
load_balancer_arns = get_load_balancer_arns()
for alb_arn in load_balancer_arns:
alarm_name = f'TargetResponseTime-{alb_arn.split("/")[-1]}'
load_balancer_name = '/'.join(alb_arn.split("/")[+1:])
is_protected = is_alb_protected(alb_arn)
if not is_protected:
create_cloudwatch_alarm(alarm_name, load_balancer_name)
health_check_id = create_route53_health_check(alarm_name)
protection_id = protect_alb(alb_arn)
health_check_arn = "arn:aws:route53:::healthcheck/" + health_check_id
response = associate_health_check(health_check_arn,protection_id)
action = 'Count'
response = enable_shield_automatic_response(alb_arn, action)
print(response["ResponseMetadata"]["HTTPStatusCode"])
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
- 74.
- 75.
- 76.
- 77.
- 78.
- 79.
- 80.
- 81.
- 82.
- 83.
- 84.
- 85.
- 86.
- 87.
- 88.
- 89.
- 90.
- 91.
- 92.
- 93.
- 94.
- 95.
- 96.
- 97.
- 98.
- 99.
- 100.
- 101.
- 102.
- 103.
- 104.
- 105.
- 106.
- 107.
- 108.
- 109.
- 110.