-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvpn tunnel state alarm.yml
126 lines (116 loc) · 4.54 KB
/
vpn tunnel state alarm.yml
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
AWSTemplateFormatVersion: '2010-09-09'
Description: CloudFormation Template to create IAM Role, Lambda Function, CloudWatch Event Rule, and Lambda Permission with VPN existing scan feature.
Resources:
# Lambda Execution Role
UmamDplyLambdaExecutionRole:
Type: 'AWS::IAM::Role'
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- sts:AssumeRole
Policies:
- PolicyName: ummdplyLambdaPolicy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
- ec2:DescribeVpnConnections
- cloudwatch:PutMetricAlarm
Resource: '*'
DeletionPolicy: Retain
# Lambda Function
UmamDplyLambdaFunction:
Type: 'AWS::Lambda::Function'
Properties:
FunctionName: ummdplyVpnTunnelAlarm
Handler: index.handler
Role: !GetAtt UmamDplyLambdaExecutionRole.Arn
Runtime: 'python3.8'
Timeout: 300
Code:
ZipFile: |
import boto3
def create_alarm(vpn_connection_id, tunnel, sns_topic_arn):
cloudwatch = boto3.client('cloudwatch')
alarm_name = f'umm-dply-VPN-{vpn_connection_id}-Tunnel{tunnel}-Status'
# Check if the alarm already exists
existing_alarms = cloudwatch.describe_alarms(
AlarmNames=[alarm_name]
)
if not existing_alarms['MetricAlarms']:
# Create alarm if it doesn't exist
cloudwatch.put_metric_alarm(
AlarmName=alarm_name,
AlarmDescription=f'Alarm for VPN {vpn_connection_id} Tunnel {tunnel} status',
ActionsEnabled=True,
AlarmActions=[sns_topic_arn],
MetricName='TunnelState',
Namespace='AWS/VPN',
Statistic='Average',
Dimensions=[
{
'Name': 'VpnId',
'Value': vpn_connection_id
},
{
'Name': 'TunnelIpAddress',
'Value': tunnel
}
],
Period=300,
EvaluationPeriods=1,
Threshold=1,
ComparisonOperator='LessThanThreshold',
TreatMissingData='breaching'
)
def handler(event, context):
ec2 = boto3.client('ec2')
sns_topic_arn = "arn:aws:sns:ap-southeast-1:003866745935:umam-alert-topic"
# Describe all VPN connections
response = ec2.describe_vpn_connections()
vpn_connections = response.get('VpnConnections', [])
for vpn_connection in vpn_connections:
vpn_connection_id = vpn_connection['VpnConnectionId']
for tunnel in vpn_connection['VgwTelemetry']:
create_alarm(vpn_connection_id, tunnel['OutsideIpAddress'], sns_topic_arn)
DeletionPolicy: Retain
# CloudWatch Event Rule to trigger Lambda on VPN state changes
UmamDplyVpnStateChangeRule:
Type: 'AWS::Events::Rule'
Properties:
Name: ummdplyVpnStateChangeRule
EventPattern:
source:
- "aws.ec2"
detail-type:
- "AWS API Call via CloudTrail"
detail:
eventSource:
- "ec2.amazonaws.com"
eventName:
- "CreateVpnConnection"
Targets:
- Arn: !GetAtt UmamDplyLambdaFunction.Arn
Id: TargetFunction
DeletionPolicy: Retain
DependsOn: UmamDplyLambdaFunction
# Lambda Permission to be invoked by CloudWatch Events
UmamDplyLambdaPermission:
Type: 'AWS::Lambda::Permission'
Properties:
FunctionName: !Ref UmamDplyLambdaFunction
Action: 'lambda:InvokeFunction'
Principal: 'events.amazonaws.com'
SourceArn: !GetAtt UmamDplyVpnStateChangeRule.Arn
DeletionPolicy: Retain
DependsOn: UmamDplyVpnStateChangeRule