Skip to content

Commit f801063

Browse files
committed
Add lambda trigger
1 parent ffa2546 commit f801063

File tree

4 files changed

+190
-3
lines changed

4 files changed

+190
-3
lines changed

4.validation_and_observability/4.prometheus-grafana/cluster-observability.yaml

+4
Original file line numberDiff line numberDiff line change
@@ -63,5 +63,9 @@ Outputs:
6363
Value: !Ref "AWS::Region"
6464
AMPRemoteWriteURL:
6565
Value: !Join ["" , [ !GetAtt APSWorkspace.PrometheusEndpoint , "api/v1/remote_write" ]]
66+
AMPEndPointUrl:
67+
Value: !GetAtt APSWorkspace.PrometheusEndpoint
6668
GrafanWorkspaceURL:
6769
Value: !Join ["" , [ "https://", !GetAtt AmazonGrafanaWorkspace.Endpoint ]]
70+
GrafanWorkspaceId:
71+
Value: !GetAtt AmazonGrafanaWorkspace.Id
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
#!/usr/bin/env python3
2+
3+
import boto3
4+
from grafana_client import GrafanaApi, HeaderAuth, TokenAuth
5+
from grafanalib._gen import DashboardEncoder
6+
from grafanalib.core import Dashboard
7+
import json
8+
from typing import Dict
9+
import urllib.request
10+
11+
from grafana_client.knowledge import datasource_factory
12+
from grafana_client.model import DatasourceModel
13+
14+
import os
15+
16+
PROM_DASHBOARDS_URL = [
17+
'https://grafana.com/api/dashboards/12239/revisions/latest/download',
18+
'https://grafana.com/api/dashboards/1860/revisions/latest/download',
19+
'https://grafana.com/api/dashboards/20579/revisions/latest/download'
20+
]
21+
22+
23+
def create_prometheus_datasource(grafana, url, aws_region):
24+
jsonData = {
25+
'sigV4Auth': True,
26+
'sigV4AuthType': 'ec2_iam_role',
27+
'sigV4Region': aws_region,
28+
'httpMethod': 'GET'
29+
}
30+
31+
datasource = DatasourceModel(name="Prometheus",
32+
type="prometheus",
33+
url=url,
34+
access="proxy",
35+
jsonData=jsonData)
36+
datasource = datasource_factory(datasource)
37+
datasource = datasource.asdict()
38+
datasource = grafana.datasource.create_datasource(datasource)["datasource"]
39+
r = grafana.datasource.health(datasource['uid'])
40+
return datasource
41+
42+
43+
def encode_dashboard(entity) -> Dict:
44+
"""
45+
Encode grafanalib `Dashboard` entity to dictionary.
46+
47+
TODO: Optimize without going through JSON marshalling.
48+
"""
49+
return json.loads(json.dumps(entity, sort_keys=True, cls=DashboardEncoder))
50+
51+
52+
def mk_dash(datasource_uid, url):
53+
url = urllib.request.urlopen(url)
54+
dashboard = json.load(url)
55+
for i in dashboard['panels']:
56+
i["datasource"] = {"type": "prometheus", "uid": datasource_uid}
57+
58+
for i in dashboard['templating']['list']:
59+
i["datasource"] = {"type": "prometheus", "uid": datasource_uid}
60+
61+
return {"dashboard": dashboard, "overwrite": True}
62+
63+
64+
def lambda_handler(event, context):
65+
aws_region = os.environ['REGION']
66+
grafana_key_name = "CreateDashboards"
67+
grafana_url = os.environ['GRAFANA_WORKSPACE_URL']
68+
workspace_id = os.environ['GRAFANA_WORKSPACE_ID']
69+
prometheus_url = os.environ['PROMETHEUS_URL']
70+
71+
client = boto3.client('grafana')
72+
response = client.create_workspace_api_key(keyName=grafana_key_name,
73+
keyRole='ADMIN',
74+
secondsToLive=60,
75+
workspaceId=workspace_id)
76+
77+
try:
78+
grafana = GrafanaApi.from_url(
79+
url=grafana_url,
80+
credential=TokenAuth(token=response['key']),
81+
)
82+
83+
prometheus_datasource = create_prometheus_datasource(
84+
grafana, prometheus_url, aws_region)
85+
86+
for i in PROM_DASHBOARDS_URL:
87+
dashboard_payload = mk_dash(prometheus_datasource['uid'], i)
88+
response = grafana.dashboard.update_dashboard(dashboard_payload)
89+
90+
except Exception as e:
91+
print(e)
92+
93+
response = client.delete_workspace_api_key(keyName=grafana_key_name,
94+
workspaceId=workspace_id)
95+
96+
97+
def main():
98+
aws_region = 'ap-southeast-2'
99+
grafana_key_name = "CreateDashpa01"
100+
grafana_url = 'https://g-182a00efff.grafana-workspace.ap-southeast-2.amazonaws.com'
101+
workspace_id = 'g-182a00efff'
102+
prometheus_url = 'https://aps-workspaces.ap-southeast-2.amazonaws.com/workspaces/ws-e4384558-d586-46ec-bd12-173d7019119e/'
103+
104+
client = boto3.client('grafana')
105+
response = client.create_workspace_api_key(keyName=grafana_key_name,
106+
keyRole='ADMIN',
107+
secondsToLive=60,
108+
workspaceId=workspace_id)
109+
110+
try:
111+
grafana = GrafanaApi.from_url(
112+
url=grafana_url,
113+
credential=TokenAuth(token=response['key']),
114+
)
115+
116+
prometheus_datasource = create_prometheus_datasource(
117+
grafana, prometheus_url, aws_region)
118+
119+
for i in PROM_DASHBOARDS_URL:
120+
dashboard_payload = mk_dash(prometheus_datasource['uid'], i)
121+
response = grafana.dashboard.update_dashboard(dashboard_payload)
122+
123+
except Exception as e:
124+
print(e)
125+
126+
response = client.delete_workspace_api_key(keyName=grafana_key_name,
127+
workspaceId=workspace_id)
128+
129+
130+
if __name__ == '__main__':
131+
main()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
boto3
2+
grafana-client
3+
grafanalib
4+
urllib3

4.validation_and_observability/4.prometheus-grafana/managed-cluster-observability-pc.yaml

+51-3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,15 @@ Description: >
44
Prometheus Agent Collector
55
66

7+
Parameters:
8+
PCClusterNAME:
9+
Type: String
10+
ManagedPrometheusUrl:
11+
Type: String
12+
SubnetId:
13+
Type: AWS::EC2::Subnet::Id
14+
VpcId:
15+
Type: AWS::EC2::VPC::Id
716

817
Resources:
918
GrafanaPrometheus:
@@ -13,14 +22,53 @@ Resources:
1322
Properties:
1423
Location: cluster-observability.yaml
1524

25+
GrafanaLambdaRole:
26+
Type: AWS::IAM::Role
27+
Properties:
28+
AssumeRolePolicyDocument:
29+
Version: "2012-10-17"
30+
Statement:
31+
- Effect: Allow
32+
Principal:
33+
Service: lambda.amazonaws.com
34+
Action: "sts:AssumeRole"
35+
Policies:
36+
- PolicyName: GrafanaLambda
37+
PolicyDocument:
38+
Version: "2012-10-17"
39+
Statement:
40+
- Effect: Allow
41+
Action:
42+
- 'grafana:CreateWorkspaceApiKey'
43+
- 'grafana:DeleteWorkspaceApiKey'
44+
Resource: "*"
45+
46+
DashboardCreationLambda:
47+
Type: AWS::Serverless::Function
48+
Properties:
49+
CodeUri: dashboards
50+
Environment:
51+
Variables:
52+
REGION: !Ref AWS::Region
53+
PROMETHEUS_URL: !GetAtt GrafanaPrometheus.Outputs.AMPEndPointUrl
54+
GRAFANA_WORKSPACE_ID: !GetAtt GrafanaPrometheus.Outputs.GrafanWorkspaceId
55+
GRAFANA_WORKSPACE_URL: !GetAtt GrafanaPrometheus.Outputs.GrafanWorkspaceURL
56+
Handler: create_ml_dashboards.lambda_handler
57+
Runtime: python3.13
58+
Role: !GetAtt GrafanaLambdaRole.Arn
59+
Timeout: 10
60+
MemorySize: 128
61+
Tags:
62+
Application: MLDashboards
63+
1664
PrometheusCollector:
1765
Type: AWS::Serverless::Application
1866
DeletionPolicy: Delete
1967
UpdateReplacePolicy: Delete
2068
Properties:
2169
Location: prometheus-agent-collector.yaml
2270
Parameters:
23-
PCClusterNAME: "shared-cluster-syd"
71+
PCClusterNAME: !Ref PCClusterName
2472
ManagedPrometheusUrl: !GetAtt GrafanaPrometheus.Outputs.AMPRemoteWriteURL
25-
SubnetId: subnet-081459dc8609a5542
26-
VpcId: vpc-0cab19e1e592d1cb3
73+
SubnetId: !Ref SubnetId
74+
VpcId: !Ref VpcId

0 commit comments

Comments
 (0)