Skip to content

Commit 788c9c9

Browse files
author
Yuriy Bezsonov
committed
Thread dump analysis lab - cleanup
1 parent 82207b7 commit 788c9c9

13 files changed

Lines changed: 505 additions & 694 deletions

infrastructure/cdk/src/main/java/com/unicorn/IdeStack.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public class IdeStack extends Stack {
2222
private final String bootstrapScript = """
2323
date
2424
25-
echo '=== Clone Git repository ==='bash
25+
echo '=== Clone Git repository ==='
2626
sudo -H -u ec2-user bash -c "git clone https://github.com/aws-samples/java-on-aws ~/java-on-aws/"
2727
# sudo -H -u ec2-user bash -c "cd ~/java-on-aws && git checkout refactoring"
2828

infrastructure/cdk/src/main/java/com/unicorn/UnicornStoreStack.java

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,28 +8,37 @@
88
import com.unicorn.constructs.CodeBuildResource;
99
import com.unicorn.constructs.CodeBuildResource.CodeBuildResourceProps;
1010
import com.unicorn.constructs.EksCluster;
11-
import com.unicorn.core.*;
12-
13-
import software.amazon.awscdk.*;
11+
import com.unicorn.core.InfrastructureCore;
12+
import com.unicorn.core.InfrastructureContainers;
13+
import com.unicorn.core.InfrastructureEks;
14+
import com.unicorn.core.InfrastructureMonitoringJVM;
15+
import com.unicorn.core.DatabaseSetup;
16+
import com.unicorn.core.UnicornStoreSpringLambda;
17+
18+
import software.amazon.awscdk.Stack;
19+
import software.amazon.awscdk.StackProps;
1420
import software.amazon.awscdk.services.ec2.InstanceClass;
1521
import software.amazon.awscdk.services.ec2.InstanceSize;
1622
import software.amazon.awscdk.services.ec2.InstanceType;
1723
import software.amazon.awscdk.services.iam.ManagedPolicy;
1824
import software.constructs.Construct;
1925

26+
import software.amazon.awscdk.DefaultStackSynthesizer;
27+
import software.amazon.awscdk.DefaultStackSynthesizerProps;
28+
2029
public class UnicornStoreStack extends Stack {
2130

2231
private final String bootstrapScript = """
2332
date
2433
25-
echo '=== Clone Git repository ===\n'
34+
echo '=== Clone Git repository ==='
2635
sudo -H -u ec2-user bash -c "git clone https://github.com/aws-samples/java-on-aws ~/java-on-aws/"
27-
sudo -H -u ec2-user bash -c "cd ~/java-on-aws && git checkout bedrock-tda"
36+
# sudo -H -u ec2-user bash -c "cd ~/java-on-aws && git checkout refactoring"
2837
29-
echo '=== Setup IDE ===\n'
38+
echo '=== Setup IDE ==='
3039
sudo -H -i -u ec2-user bash -c "~/java-on-aws/infrastructure/scripts/setup/ide.sh"
3140
32-
echo '=== Additional Setup ===\n'
41+
echo '=== Additional Setup ==='
3342
sudo -H -i -u ec2-user bash -c "~/java-on-aws/infrastructure/scripts/setup/app.sh"
3443
sudo -H -i -u ec2-user bash -c "~/java-on-aws/infrastructure/scripts/setup/eks.sh"
3544
@@ -66,7 +75,7 @@ public UnicornStoreStack(final Construct scope, final String id) {
6675
// Create VPC
6776
var vpc = new WorkshopVpc(this, "UnicornStoreVpc", "unicornstore-vpc").getVpc();
6877

69-
// Create VSCode IDE
78+
// Create Workshop IDE
7079
var ideProps = new VSCodeIdeProps();
7180
ideProps.setBootstrapScript(bootstrapScript);
7281
ideProps.setVpc(vpc);
@@ -83,11 +92,6 @@ public UnicornStoreStack(final Construct scope, final String id) {
8392
var ideRole = ideProps.getRole();
8493
var ideInternalSecurityGroup = ide.getIdeInternalSecurityGroup();
8594

86-
// Create EKS cluster for the workshop
87-
var eksCluster = new EksCluster(this, "UnicornStoreEksCluster", "unicorn-store", "1.33",
88-
vpc, ideInternalSecurityGroup);
89-
eksCluster.createAccessEntry(ideRole.getRoleArn(), "unicorn-store", "unicornstore-ide-user");
90-
9195
// Create Core infrastructure
9296
var infrastructureCore = new InfrastructureCore(this, "InfrastructureCore", vpc);
9397
// var accountId = Stack.of(this).getAccount();
@@ -96,6 +100,11 @@ public UnicornStoreStack(final Construct scope, final String id) {
96100
new InfrastructureContainers(this, "InfrastructureContainers", infrastructureCore);
97101
new InfrastructureEks(this, "InfrastructureEks", infrastructureCore);
98102

103+
// Create EKS cluster for the workshop
104+
var eksCluster = new EksCluster(this, "UnicornStoreEksCluster", "unicorn-store", "1.33",
105+
vpc, ideInternalSecurityGroup);
106+
eksCluster.createAccessEntry(ideRole.getRoleArn(), "unicorn-store", "unicornstore-ide-user");
107+
99108
// Create JVM monitoring infrastructure with Lambda thread dump
100109
new InfrastructureMonitoringJVM(this, "InfrastructureMonitoringJVM", infrastructureCore.getWorkshopBucket(), eksCluster, vpc);
101110

infrastructure/cdk/src/main/java/com/unicorn/constructs/EksCluster.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.unicorn.constructs;
22

3-
import software.amazon.awscdk.services.ec2.*;
3+
import software.amazon.awscdk.services.ec2.IVpc;
4+
import software.amazon.awscdk.services.ec2.SecurityGroup;
45
import software.amazon.awscdk.services.eks.CfnCluster;
56
import software.amazon.awscdk.services.eks.CfnCluster.LoggingProperty;
67
import software.amazon.awscdk.services.eks.CfnCluster.ClusterLoggingProperty;
@@ -17,6 +18,12 @@
1718
import software.amazon.awscdk.services.eks.CfnAccessEntry.AccessScopeProperty;
1819
import software.amazon.awscdk.services.eks.CfnAccessEntry.AccessPolicyProperty;
1920
import software.amazon.awscdk.services.eks.CfnPodIdentityAssociation;
21+
// import software.amazon.awscdk.services.eks.OpenIdConnectProvider;
22+
// import software.amazon.awscdk.ResolutionTypeHint;
23+
import software.amazon.awscdk.services.ec2.SubnetType;
24+
import software.amazon.awscdk.services.ec2.SubnetSelection;
25+
import software.amazon.awscdk.services.ec2.ISubnet;
26+
import software.amazon.awscdk.services.ec2.ISecurityGroup;
2027
import software.amazon.awscdk.services.iam.ManagedPolicy;
2128
import software.amazon.awscdk.services.iam.Role;
2229
import software.amazon.awscdk.services.iam.ServicePrincipal;
@@ -185,11 +192,6 @@ public void createPodIdentity(final String principalArn, final String clusterNam
185192
podIdentityAssociation.getNode().addDependency(cluster);
186193
}
187194

188-
// Get the default cluster security group
189-
public String getClusterSecurityGroupId() {
190-
return cluster.getAttrClusterSecurityGroupId();
191-
}
192-
193195
// Get the default cluster security group as ISecurityGroup
194196
public ISecurityGroup getClusterSecurityGroup() {
195197
return SecurityGroup.fromSecurityGroupId(

infrastructure/cdk/src/main/java/com/unicorn/constructs/VSCodeIde.java

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
package com.unicorn.constructs;
22

3-
import software.amazon.awscdk.*;
3+
import software.amazon.awscdk.CfnWaitCondition;
4+
import software.amazon.awscdk.CfnWaitConditionHandle;
5+
import software.amazon.awscdk.CustomResource;
6+
import software.amazon.awscdk.Duration;
7+
import software.amazon.awscdk.Fn;
8+
import software.amazon.awscdk.RemovalPolicy;
49
// import software.amazon.awscdk.services.cloudfront.AddBehaviorOptions;
510
import software.amazon.awscdk.services.cloudfront.AllowedMethods;
611
import software.amazon.awscdk.services.cloudfront.BehaviorOptions;
@@ -31,7 +36,13 @@
3136
import software.amazon.awscdk.services.ec2.SecurityGroup;
3237
import software.amazon.awscdk.services.ec2.SubnetSelection;
3338
import software.amazon.awscdk.services.ec2.SubnetType;
34-
import software.amazon.awscdk.services.iam.*;
39+
import software.amazon.awscdk.services.iam.IManagedPolicy;
40+
import software.amazon.awscdk.services.iam.InstanceProfile;
41+
import software.amazon.awscdk.services.iam.ManagedPolicy;
42+
import software.amazon.awscdk.services.iam.PolicyDocument;
43+
import software.amazon.awscdk.services.iam.PolicyStatement;
44+
import software.amazon.awscdk.services.iam.Role;
45+
import software.amazon.awscdk.services.iam.ServicePrincipal;
3546
import software.amazon.awscdk.services.lambda.Code;
3647
import software.amazon.awscdk.services.lambda.Function;
3748
import software.amazon.awscdk.services.lambda.Runtime;
@@ -40,6 +51,7 @@
4051
import software.amazon.awscdk.services.secretsmanager.Secret;
4152
import software.amazon.awscdk.services.secretsmanager.SecretStringGenerator;
4253
import software.amazon.awscdk.services.ssm.CfnDocument;
54+
import software.amazon.awscdk.CfnOutput;
4355

4456
import software.constructs.Construct;
4557
import org.json.JSONObject;
@@ -169,23 +181,13 @@ public VSCodeIde(final Construct scope, final String id, final VSCodeIdeProps pr
169181
props.getRole().addManagedPolicy(ManagedPolicy.fromAwsManagedPolicyName("AmazonSSMManagedInstanceCore"));
170182

171183
var filePath = props.getAdditionalIamPolicyPath();
172-
try {
173-
var policyPath = Path.of(getClass().getResource(filePath).toURI());
174-
if (Files.exists(policyPath)) {
175-
var jsonPolicy = loadFile(filePath);
176-
// AccountId dynamisch einsetzen
177-
String accountId = Stack.of(this).getAccount();
178-
String replaced = jsonPolicy.replace("{{.AccountId}}", accountId);
179-
var policyDoc = new JSONObject(replaced).toMap();
180-
181-
CfnManagedPolicy.Builder.create(this, "WorkshopIdeUserPolicy")
182-
.policyDocument(policyDoc)
183-
.managedPolicyName("WorkshopIdeUserPolicy")
184-
.roles(List.of(props.getRole().getRoleName()))
185-
.build();
186-
}
187-
} catch (Exception e) {
188-
throw new RuntimeException("Failed to read or parse IAM policy file: " + filePath, e);
184+
if (Files.exists(Path.of(getClass().getResource(filePath).getPath()))) {
185+
var policyDocumentJson = loadFile(filePath);
186+
var policyDocument = PolicyDocument.fromJson(new JSONObject(policyDocumentJson).toMap());
187+
var policy = ManagedPolicy.Builder.create(this, "WorkshopIdeUserPolicy")
188+
.document(policyDocument)
189+
.build();
190+
props.getRole().addManagedPolicy(policy);
189191
}
190192

191193
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd-HHmmss");

infrastructure/cdk/src/main/java/com/unicorn/core/InfrastructureContainers.java

Lines changed: 58 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public class InfrastructureContainers extends Construct {
2020
private final InfrastructureCore infrastructureCore;
2121

2222
public InfrastructureContainers(final Construct scope, final String id,
23-
final InfrastructureCore infrastructureCore) {
23+
final InfrastructureCore infrastructureCore) {
2424
super(scope, id);
2525

2626
// Get previously created infrastructure construct
@@ -34,68 +34,77 @@ public InfrastructureContainers(final Construct scope, final String id,
3434

3535
private Repository createUnicornStoreSpringEcr() {
3636
return Repository.Builder.create(this, "UnicornStoreSpringEcr")
37-
.repositoryName("unicorn-store-spring")
38-
.imageScanOnPush(false)
39-
.removalPolicy(RemovalPolicy.DESTROY)
40-
.emptyOnDelete(true) // This will force delete all images when repository is deleted
41-
.build();
37+
.repositoryName("unicorn-store-spring")
38+
.imageScanOnPush(false)
39+
.removalPolicy(RemovalPolicy.DESTROY)
40+
.emptyOnDelete(true) // This will force delete all images when repository is deleted
41+
.build();
4242
}
4343

4444
private void createVpcConnector() {
4545
VpcConnector.Builder.create(this, "UnicornStoreVpcConnector")
46-
.vpc(infrastructureCore.getVpc())
47-
.vpcSubnets(SubnetSelection.builder()
48-
.subnetType(SubnetType.PRIVATE_WITH_EGRESS)
49-
.build())
50-
.vpcConnectorName("unicornstore-vpc-connector")
51-
.build();
46+
.vpc(infrastructureCore.getVpc())
47+
.vpcSubnets(SubnetSelection.builder()
48+
.subnetType(SubnetType.PRIVATE_WITH_EGRESS)
49+
.build())
50+
.vpcConnectorName("unicornstore-vpc-connector")
51+
.build();
5252
}
5353

5454
private void createRolesAppRunner() {
5555
var unicornStoreApprunnerRole = Role.Builder.create(this, "UnicornStoreApprunnerRole")
56-
.roleName("unicornstore-apprunner-role")
57-
.assumedBy(new ServicePrincipal("tasks.apprunner.amazonaws.com")).build();
56+
.roleName("unicornstore-apprunner-role")
57+
.assumedBy(new ServicePrincipal("tasks.apprunner.amazonaws.com")).build();
5858
unicornStoreApprunnerRole.addToPolicy(PolicyStatement.Builder.create()
59-
.actions(List.of("xray:PutTraceSegments"))
60-
.resources(List.of("*"))
61-
.build());
59+
.actions(List.of("xray:PutTraceSegments"))
60+
.resources(List.of("*"))
61+
.build());
6262
infrastructureCore.getEventBridge().grantPutEventsTo(unicornStoreApprunnerRole);
6363
infrastructureCore.getDatabaseSecret().grantRead(unicornStoreApprunnerRole);
6464
infrastructureCore.getSecretPassword().grantRead(unicornStoreApprunnerRole);
6565
infrastructureCore.getParamDBConnectionString().grantRead(unicornStoreApprunnerRole);
6666

6767
var appRunnerECRAccessRole = Role.Builder.create(this, "UnicornStoreApprunnerEcrAccessRole")
68-
.roleName("unicornstore-apprunner-ecr-access-role")
69-
.assumedBy(new ServicePrincipal("build.apprunner.amazonaws.com")).build();
68+
.roleName("unicornstore-apprunner-ecr-access-role")
69+
.assumedBy(new ServicePrincipal("build.apprunner.amazonaws.com")).build();
7070
appRunnerECRAccessRole.addManagedPolicy(ManagedPolicy.fromManagedPolicyArn(this,
71-
"UnicornStoreApprunnerEcrAccessRole-" + "AWSAppRunnerServicePolicyForECRAccess",
72-
"arn:aws:iam::aws:policy/service-role/AWSAppRunnerServicePolicyForECRAccess"));
71+
"UnicornStoreApprunnerEcrAccessRole-" + "AWSAppRunnerServicePolicyForECRAccess",
72+
"arn:aws:iam::aws:policy/service-role/AWSAppRunnerServicePolicyForECRAccess"));
73+
74+
// // Create the App Runner service-linked role
75+
// Long tsLong = System.currentTimeMillis()/1000;
76+
// String timestamp = tsLong.toString();
77+
// CfnServiceLinkedRole appRunnerServiceLinkedRole = CfnServiceLinkedRole.Builder.create(this, "AppRunnerServiceLinkedRole")
78+
// .awsServiceName("apprunner.amazonaws.com")
79+
// .description("Service-linked role for AWS App Runner service")
80+
// .customSuffix(timestamp)
81+
// .build();
7382
}
7483

7584
private void createRolesEcs() {
7685
var AWSOpenTelemetryPolicy = PolicyStatement.Builder.create()
77-
.effect(Effect.ALLOW)
78-
.actions(List.of("logs:PutLogEvents", "logs:CreateLogGroup", "logs:CreateLogStream",
79-
"logs:DescribeLogStreams", "logs:DescribeLogGroups",
80-
"logs:PutRetentionPolicy", "xray:PutTraceSegments",
81-
"xray:PutTelemetryRecords", "xray:GetSamplingRules",
82-
"xray:GetSamplingTargets", "xray:GetSamplingStatisticSummaries",
83-
"cloudwatch:PutMetricData", "ssm:GetParameters"))
84-
.resources(List.of("*")).build();
86+
.effect(Effect.ALLOW)
87+
.actions(List.of("logs:PutLogEvents", "logs:CreateLogGroup", "logs:CreateLogStream",
88+
"logs:DescribeLogStreams", "logs:DescribeLogGroups",
89+
"logs:PutRetentionPolicy", "xray:PutTraceSegments",
90+
"xray:PutTelemetryRecords", "xray:GetSamplingRules",
91+
"xray:GetSamplingTargets", "xray:GetSamplingStatisticSummaries",
92+
"cloudwatch:PutMetricData", "ssm:GetParameters"))
93+
.resources(List.of("*")).build();
8594

8695
var unicornStoreEscTaskRole = Role.Builder.create(this, "UnicornStoreEcsTaskRole")
87-
.roleName("unicornstore-ecs-task-role")
88-
.assumedBy(new ServicePrincipal("ecs-tasks.amazonaws.com")).build();
96+
.roleName("unicornstore-ecs-task-role")
97+
.assumedBy(new ServicePrincipal("ecs-tasks.amazonaws.com")).build();
8998
unicornStoreEscTaskRole.addToPolicy(PolicyStatement.Builder.create()
90-
.actions(List.of("xray:PutTraceSegments"))
91-
.resources(List.of("*"))
92-
.build());
99+
.actions(List.of("xray:PutTraceSegments"))
100+
.resources(List.of("*"))
101+
.build());
93102
unicornStoreEscTaskRole.addManagedPolicy(ManagedPolicy.fromManagedPolicyArn(this,
94-
"UnicornStoreEcsTaskRole-" + "CloudWatchLogsFullAccess",
95-
"arn:aws:iam::aws:policy/CloudWatchLogsFullAccess"));
103+
"UnicornStoreEcsTaskRole-" + "CloudWatchLogsFullAccess",
104+
"arn:aws:iam::aws:policy/CloudWatchLogsFullAccess"));
96105
unicornStoreEscTaskRole.addManagedPolicy(ManagedPolicy.fromManagedPolicyArn(this,
97-
"UnicornStoreEcsTaskRole-" + "AmazonSSMReadOnlyAccess",
98-
"arn:aws:iam::aws:policy/AmazonSSMReadOnlyAccess"));
106+
"UnicornStoreEcsTaskRole-" + "AmazonSSMReadOnlyAccess",
107+
"arn:aws:iam::aws:policy/AmazonSSMReadOnlyAccess"));
99108
unicornStoreEscTaskRole.addToPolicy(AWSOpenTelemetryPolicy);
100109

101110
infrastructureCore.getEventBridge().grantPutEventsTo(unicornStoreEscTaskRole);
@@ -104,21 +113,21 @@ private void createRolesEcs() {
104113
infrastructureCore.getParamDBConnectionString().grantRead(unicornStoreEscTaskRole);
105114

106115
Role unicornStoreEscTaskExecutionRole = Role.Builder.create(this, "UnicornStoreEcsTaskExecutionRole")
107-
.roleName("unicornstore-ecs-task-execution-role")
108-
.assumedBy(new ServicePrincipal("ecs-tasks.amazonaws.com")).build();
116+
.roleName("unicornstore-ecs-task-execution-role")
117+
.assumedBy(new ServicePrincipal("ecs-tasks.amazonaws.com")).build();
109118
unicornStoreEscTaskExecutionRole.addToPolicy(PolicyStatement.Builder.create()
110-
.actions(List.of("logs:CreateLogGroup"))
111-
.resources(List.of("*"))
112-
.build());
119+
.actions(List.of("logs:CreateLogGroup"))
120+
.resources(List.of("*"))
121+
.build());
113122
unicornStoreEscTaskExecutionRole.addManagedPolicy(ManagedPolicy.fromManagedPolicyArn(this,
114-
"UnicornStoreEcsTaskExecutionRole-" + "AmazonECSTaskExecutionRolePolicy",
115-
"arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"));
123+
"UnicornStoreEcsTaskExecutionRole-" + "AmazonECSTaskExecutionRolePolicy",
124+
"arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"));
116125
unicornStoreEscTaskExecutionRole.addManagedPolicy(ManagedPolicy.fromManagedPolicyArn(this,
117-
"UnicornStoreEcsTaskExecutionRole-" + "CloudWatchLogsFullAccess",
118-
"arn:aws:iam::aws:policy/CloudWatchLogsFullAccess"));
126+
"UnicornStoreEcsTaskExecutionRole-" + "CloudWatchLogsFullAccess",
127+
"arn:aws:iam::aws:policy/CloudWatchLogsFullAccess"));
119128
unicornStoreEscTaskExecutionRole.addManagedPolicy(ManagedPolicy.fromManagedPolicyArn(this,
120-
"UnicornStoreEcsTaskExecutionRole-" + "AmazonSSMReadOnlyAccess",
121-
"arn:aws:iam::aws:policy/AmazonSSMReadOnlyAccess"));
129+
"UnicornStoreEcsTaskExecutionRole-" + "AmazonSSMReadOnlyAccess",
130+
"arn:aws:iam::aws:policy/AmazonSSMReadOnlyAccess"));
122131
unicornStoreEscTaskExecutionRole.addToPolicy(AWSOpenTelemetryPolicy);
123132

124133
infrastructureCore.getEventBridge().grantPutEventsTo(unicornStoreEscTaskExecutionRole);

infrastructure/cdk/src/main/java/com/unicorn/core/InfrastructureEks.java

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -44,21 +44,6 @@ private void createRolesEks() {
4444
"UnicornStoreEksPodRole-" + "AmazonBedrockLimitedAccess",
4545
"arn:aws:iam::aws:policy/AmazonBedrockLimitedAccess"));
4646

47-
// unicornStoreEksPodRole.addToPolicy(PolicyStatement.Builder.create()
48-
// .effect(Effect.ALLOW)
49-
// .actions(List.of(
50-
// "ecs:ListTasks",
51-
// "ecs:DescribeTasks",
52-
// "ecs:ListServices",
53-
// "ecs:DescribeServices",
54-
// "ecs:ListClusters",
55-
// "ecs:DescribeClusters",
56-
// "ecs:ListContainerInstances",
57-
// "ecs:DescribeContainerInstances"
58-
// ))
59-
// .resources(List.of("*"))
60-
// .build());
61-
6247
infrastructureCore.getEventBridge().grantPutEventsTo(unicornStoreEksPodRole);
6348
infrastructureCore.getDatabaseSecret().grantRead(unicornStoreEksPodRole);
6449
infrastructureCore.getParamDBConnectionString().grantRead(unicornStoreEksPodRole);

0 commit comments

Comments
 (0)