Skip to content

Commit 63fd46f

Browse files
committed
Add lambda trigger
1 parent ffa2546 commit 63fd46f

File tree

4 files changed

+178
-0
lines changed

4 files changed

+178
-0
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

+39
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,45 @@ Resources:
1313
Properties:
1414
Location: cluster-observability.yaml
1515

16+
GrafanaLambdaRole:
17+
Type: AWS::IAM::Role
18+
Properties:
19+
AssumeRolePolicyDocument:
20+
Version: "2012-10-17"
21+
Statement:
22+
- Effect: Allow
23+
Principal:
24+
Service: lambda.amazonaws.com
25+
Action: "sts:AssumeRole"
26+
Policies:
27+
- PolicyName: GrafanaLambda
28+
PolicyDocument:
29+
Version: "2012-10-17"
30+
Statement:
31+
- Effect: Allow
32+
Action:
33+
- 'grafana:CreateWorkspaceApiKey'
34+
- 'grafana:DeleteWorkspaceApiKey'
35+
Resource: "*"
36+
37+
DashboardCreationLambda:
38+
Type: AWS::Serverless::Function
39+
Properties:
40+
CodeUri: dashboards
41+
Environment:
42+
Variables:
43+
REGION: !Ref AWS::Region
44+
PROMETHEUS_URL: !GetAtt GrafanaPrometheus.Outputs.AMPEndPointUrl
45+
GRAFANA_WORKSPACE_ID: !GetAtt GrafanaPrometheus.Outputs.GrafanWorkspaceId
46+
GRAFANA_WORKSPACE_URL: !GetAtt GrafanaPrometheus.Outputs.GrafanWorkspaceURL
47+
Handler: create_ml_dashboards.lambda_handler
48+
Runtime: python3.13
49+
Role: !GetAtt GrafanaLambdaRole.Arn
50+
Timeout: 10
51+
MemorySize: 128
52+
Tags:
53+
Application: MLDashboards
54+
1655
PrometheusCollector:
1756
Type: AWS::Serverless::Application
1857
DeletionPolicy: Delete

0 commit comments

Comments
 (0)