Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into bump-cdk
Browse files Browse the repository at this point in the history
* origin/main: (22 commits)
  Add use case files
  Bumped version CDK due python deprecation in EKS modules (#267)
  Bumped version CDK due python deprecation in EKS modules
  Replace banner text
  Removed CDK Nag dependencies
  update deps
  revert dependencies
  dotnet7
  Update services.ts to include a specific addonVersion
  update deps
  revert dependencies
  dotnet7
  Removed Fluentbit dashboard after oteladdon
  Enabling AWS Observbility Enhanced monitoring for EKS and removed manifests
  update deps
  revert dependencies
  dotnet7
  Added Application insights module code
  Bump staging to main (#254)
  update deps
  ...
  • Loading branch information
bonclay7 committed Mar 6, 2024
2 parents e8a2d03 + 84b1eb8 commit a155912
Show file tree
Hide file tree
Showing 7 changed files with 618 additions and 55 deletions.
2 changes: 1 addition & 1 deletion PetAdoptions/cdk/pet_stack/app/pet_stack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Services } from '../lib/services';
import { Applications } from '../lib/applications';
//import { EKSPetsite } from '../lib/ekspetsite'
import { App, Tags, Aspects } from 'aws-cdk-lib';
import { AwsSolutionsChecks } from 'cdk-nag';
//import { AwsSolutionsChecks } from 'cdk-nag';


const stackName = "Services";
Expand Down
9 changes: 9 additions & 0 deletions PetAdoptions/cdk/pet_stack/lib/applications.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as iam from 'aws-cdk-lib/aws-iam';
import * as ssm from 'aws-cdk-lib/aws-ssm';
import * as eks from 'aws-cdk-lib/aws-eks';
import * as resourcegroups from 'aws-cdk-lib/aws-resourcegroups';
import { DockerImageAsset } from 'aws-cdk-lib/aws-ecr-assets';
import * as yaml from 'js-yaml';
import { Stack, StackProps, CfnJson, Fn, CfnOutput } from 'aws-cdk-lib';
Expand Down Expand Up @@ -119,6 +120,14 @@ export class Applications extends Stack {
'PetSiteECRImageURL': petsiteAsset.imageUri,
'PetStoreServiceAccountArn': petstoreserviceaccount.roleArn,
})));
// Creating AWS Resource Group for all the resources of stack.
const applicationsCfnGroup = new resourcegroups.CfnGroup(this, 'ApplicationsCfnGroup', {
name: stackName,
description: 'Contains all the resources deployed by Cloudformation Stack ' + stackName,
resourceQuery: {
type: 'CLOUDFORMATION_STACK_1_0',
}
});
}

private createSsmParameters(params: Map<string, string>) {
Expand Down
104 changes: 50 additions & 54 deletions PetAdoptions/cdk/pet_stack/lib/services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import * as cloud9 from 'aws-cdk-lib/aws-cloud9';
import * as cloudwatch from 'aws-cdk-lib/aws-cloudwatch';
import * as ecr from 'aws-cdk-lib/aws-ecr';
import * as ecrassets from 'aws-cdk-lib/aws-ecr-assets';
import * as applicationinsights from 'aws-cdk-lib/aws-applicationinsights';
import * as resourcegroups from 'aws-cdk-lib/aws-resourcegroups';

import { Construct } from 'constructs'
import { PayForAdoptionService } from './services/pay-for-adoption-service'
Expand Down Expand Up @@ -547,60 +549,17 @@ export class Services extends Stack {
awsLoadBalancerManifest.node.addDependency(loadBalancerServiceAccount);
awsLoadBalancerManifest.node.addDependency(waitForLBServiceAccount);

// NOTE: amazon-cloudwatch namespace is created here!!
var fluentbitYaml = yaml.loadAll(readFileSync("./resources/cwagent-fluent-bit-quickstart.yaml","utf8")) as Record<string,any>[];
fluentbitYaml[1].metadata.annotations["eks.amazonaws.com/role-arn"] = new CfnJson(this, "fluentbit_Role", { value : `${cwserviceaccount.roleArn}` });

fluentbitYaml[4].data["cwagentconfig.json"] = JSON.stringify({
agent: {
region: region },
logs: {
metrics_collected: {
kubernetes: {
cluster_name: "PetSite",
metrics_collection_interval: 60
}
},
force_flush_interval: 5

}

});

fluentbitYaml[6].data["cluster.name"] = "PetSite";
fluentbitYaml[6].data["logs.region"] = region;
fluentbitYaml[7].metadata.annotations["eks.amazonaws.com/role-arn"] = new CfnJson(this, "cloudwatch_Role", { value : `${cwserviceaccount.roleArn}` });

// The `cluster-info` configmap is used by the current Python implementation for the `AwsEksResourceDetector`
fluentbitYaml[12].data["cluster.name"] = "PetSite";
fluentbitYaml[12].data["logs.region"] = region;

const fluentbitManifest = new eks.KubernetesManifest(this,"cloudwatcheployment",{
cluster: cluster,
manifest: fluentbitYaml
});

// CloudWatch agent for prometheus metrics
var prometheusYaml = yaml.loadAll(readFileSync("./resources/prometheus-eks.yaml","utf8")) as Record<string,any>[];

prometheusYaml[0].metadata.annotations["eks.amazonaws.com/role-arn"] = new CfnJson(this, "prometheus_Role", { value : `${cwserviceaccount.roleArn}` });

const prometheusManifest = new eks.KubernetesManifest(this,"prometheusdeployment",{
cluster: cluster,
manifest: prometheusYaml
});

prometheusManifest.node.addDependency(fluentbitManifest); // Namespace creation dependency


var dashboardBody = readFileSync("./resources/cw_dashboard_fluent_bit.json","utf-8");
dashboardBody = dashboardBody.replaceAll("{{YOUR_CLUSTER_NAME}}","PetSite");
dashboardBody = dashboardBody.replaceAll("{{YOUR_AWS_REGION}}",region);

const fluentBitDashboard = new cloudwatch.CfnDashboard(this, "FluentBitDashboard", {
dashboardName: "EKS_FluentBit_Dashboard",
dashboardBody: dashboardBody
});
// NOTE: Amazon CloudWatch Observability Addon for CloudWatch Agent and Fluentbit
const otelAddon = new eks.CfnAddon(this, 'otelObservabilityAddon', {
addonName: 'amazon-cloudwatch-observability',
addonVersion: 'v1.2.0-eksbuild.1',
clusterName: cluster.clusterName,
// the properties below are optional
resolveConflicts: 'OVERWRITE',
preserveOnDelete: false,
serviceAccountRoleArn: cwserviceaccount.roleArn,
});

const customWidgetResourceControllerPolicy = new iam.PolicyStatement({
effect: iam.Effect.ALLOW,
Expand Down Expand Up @@ -656,13 +615,50 @@ var dashboardBody = readFileSync("./resources/cw_dashboard_fluent_bit.json","utf
dashboardBody: costControlDashboardBody
});

// Creating AWS Resource Group for all the resources of stack.
const servicesCfnGroup = new resourcegroups.CfnGroup(this, 'ServicesCfnGroup', {
name: stackName,
description: 'Contains all the resources deployed by Cloudformation Stack ' + stackName,
resourceQuery: {
type: 'CLOUDFORMATION_STACK_1_0',
}
});
// Enabling CloudWatch Application Insights for Resource Group
const servicesCfnApplication = new applicationinsights.CfnApplication(this, 'ServicesApplicationInsights', {
resourceGroupName: servicesCfnGroup.name,
autoConfigurationEnabled: true,
cweMonitorEnabled: true,
opsCenterEnabled: true,
});
// Adding dependency to create these resources at last
servicesCfnGroup.node.addDependency(petSiteCostControlDashboard);
servicesCfnApplication.node.addDependency(servicesCfnGroup);
// Adding a Lambda function to produce the errors - manually executed
var dynamodbQueryLambdaRole = new iam.Role(this, 'dynamodbQueryLambdaRole', {
assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
managedPolicies: [
iam.ManagedPolicy.fromManagedPolicyArn(this, 'manageddynamodbread', 'arn:aws:iam::aws:policy/AmazonDynamoDBReadOnlyAccess'),
iam.ManagedPolicy.fromManagedPolicyArn(this, 'lambdaBasicExecRoletoddb', 'arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole')
]
});

var dynamodbQueryFunction = new lambda.Function(this, 'dynamodb-query-function', {
code: lambda.Code.fromAsset(path.join(__dirname, '/../resources/application-insights')),
handler: 'dynamodb-query-function.lambda_handler',
memorySize: 128,
runtime: lambda.Runtime.PYTHON_3_9,
role: dynamodbQueryLambdaRole,
timeout: Duration.seconds(900)
});
dynamodbQueryFunction.addEnvironment("DYNAMODB_TABLE_NAME", dynamodb_petadoption.tableName);

this.createOuputs(new Map(Object.entries({
'CWServiceAccountArn': cwserviceaccount.roleArn,
'XRayServiceAccountArn': xrayserviceaccount.roleArn,
'OIDCProviderUrl': cluster.clusterOpenIdConnectIssuerUrl,
'OIDCProviderArn': cluster.openIdConnectProvider.openIdConnectProviderArn,
'PetSiteUrl': `http://${alb.loadBalancerDnsName}`
'PetSiteUrl': `http://${alb.loadBalancerDnsName}`,
'DynamoDBQueryFunction': dynamodbQueryFunction.functionName
})));


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import os
import time
import boto3
from boto3.dynamodb.conditions import Key

dynamodb = boto3.resource('dynamodb')
DYNAMODB_TABLE_NAME = os.environ['DYNAMODB_TABLE_NAME']

def lambda_handler(event, context):
table = dynamodb.Table(DYNAMODB_TABLE_NAME)
error_mode = event.get('error_mode')
if error_mode == 'true':
query_key = 'wrongKey'
else:
query_key = 'pettype'
t_end = time.time() + 60 * 13
while time.time() < t_end:
try:
response = table.query(
KeyConditionExpression=Key(query_key).eq('puppy')
)
items = response['Items']
except Exception as e:
print("An exception occurred, but still continuing. The error is: ",e)
items = "FunctionError"
time.sleep(30)
return {
'statusCode': 200,
'body': items
}
Loading

0 comments on commit a155912

Please sign in to comment.