Skip to content

Commit 271b8b5

Browse files
author
Yuriy Bezsonov
committed
update infra
1 parent b1567ef commit 271b8b5

File tree

5 files changed

+429
-140
lines changed

5 files changed

+429
-140
lines changed

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

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,7 @@
2222
import software.amazon.awscdk.services.ec2.IMachineImage;
2323
import software.amazon.awscdk.services.ec2.ISecurityGroup;
2424
import software.amazon.awscdk.services.ec2.IVpc;
25-
import software.amazon.awscdk.services.ec2.InstanceClass;
26-
import software.amazon.awscdk.services.ec2.InstanceSize;
27-
import software.amazon.awscdk.services.ec2.InstanceType;
25+
2826
import software.amazon.awscdk.services.ec2.MachineImage;
2927
import software.amazon.awscdk.services.ec2.Peer;
3028
import software.amazon.awscdk.services.ec2.Port;
@@ -41,8 +39,7 @@
4139
import software.amazon.awscdk.services.lambda.Code;
4240
import software.amazon.awscdk.services.lambda.Function;
4341
import software.amazon.awscdk.services.lambda.Runtime;
44-
import software.amazon.awscdk.services.logs.LogGroup;
45-
import software.amazon.awscdk.services.logs.RetentionDays;
42+
4643
import software.amazon.awscdk.services.secretsmanager.Secret;
4744
import software.amazon.awscdk.services.secretsmanager.SecretStringGenerator;
4845
import software.amazon.awscdk.services.ssm.CfnDocument;
@@ -54,8 +51,7 @@
5451
import java.io.IOException;
5552
import java.nio.file.Files;
5653
import java.nio.file.Path;
57-
import java.time.LocalDateTime;
58-
import java.time.format.DateTimeFormatter;
54+
5955
import java.util.ArrayList;
6056
import java.util.Arrays;
6157
import java.util.HashMap;
@@ -180,6 +176,7 @@ public VSCodeIde(final Construct scope, final String id, final VSCodeIdeProps pr
180176
// props.getRole().addManagedPolicy(ManagedPolicy.fromAwsManagedPolicyName("AdministratorAccess"));
181177
props.getRole().addManagedPolicy(ManagedPolicy.fromAwsManagedPolicyName("ReadOnlyAccess"));
182178
props.getRole().addManagedPolicy(ManagedPolicy.fromAwsManagedPolicyName("AmazonSSMManagedInstanceCore"));
179+
props.getRole().addManagedPolicy(ManagedPolicy.fromAwsManagedPolicyName("CloudWatchAgentServerPolicy"));
183180

184181
var filePath = props.getAdditionalIamPolicyPath();
185182
if (Files.exists(Path.of(getClass().getResource(filePath).getPath()))) {
@@ -191,15 +188,8 @@ public VSCodeIde(final Construct scope, final String id, final VSCodeIdeProps pr
191188
props.getRole().addManagedPolicy(policy);
192189
}
193190

194-
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd-HHmmss");
195-
String timestamp = LocalDateTime.now().format(formatter);
196-
197-
// Set up logging
198-
LogGroup logGroup = LogGroup.Builder.create(this, "IdeLogGroup")
199-
.retention(RetentionDays.ONE_WEEK)
200-
.logGroupName(props.getInstanceName() + "-bootstrap-log-" + timestamp)
201-
.build();
202-
logGroup.grantWrite(props.getRole());
191+
// Log group will be created dynamically by CloudWatch agent at runtime
192+
// No pre-created log group needed - avoids hardcoded timestamp issues
203193

204194
// Create prefix List of CloudFront IP for EC2 instance segurity Group
205195
Function prefixListFunction = Function.Builder.create(this, "IdePrefixListFunction")
@@ -448,7 +438,8 @@ public VSCodeIde(final Construct scope, final String id, final VSCodeIdeProps pr
448438
Map.entry("readmeUrl", props.getReadmeUrl()),
449439
Map.entry("environmentContentsZip", props.getEnvironmentContentsZip()),
450440
Map.entry("extensions", String.join(",", props.getExtensions())),
451-
Map.entry("terminalOnStartup", String.valueOf(props.isTerminalOnStartup()))
441+
Map.entry("terminalOnStartup", String.valueOf(props.isTerminalOnStartup())),
442+
Map.entry("logGroupPrefix", props.getInstanceName() + "-bootstrap")
452443
))
453444
));
454445

@@ -502,8 +493,8 @@ public VSCodeIde(final Construct scope, final String id, final VSCodeIdeProps pr
502493
.serviceToken(bootstrapFunction.getFunctionArn())
503494
.properties(Map.of(
504495
"InstanceId", instanceId,
505-
"SsmDocument", ssmDocument.getRef(),
506-
"LogGroupName", logGroup.getLogGroupName()
496+
"SsmDocument", ssmDocument.getRef()
497+
// LogGroupName removed - will be created dynamically by CloudWatch agent
507498
))
508499
.build();
509500
}

infrastructure/cdk/src/main/resources/bootstrapDocument.sh

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,43 @@
11
bash << 'HEREDOC'
22
set -e
33
4+
# Generate unique log group name with runtime timestamp
5+
LOG_GROUP_NAME="${logGroupPrefix}-$(date +%Y%m%d-%H%M%S)"
6+
echo "Bootstrap logs will be written to CloudWatch log group: $LOG_GROUP_NAME"
7+
8+
# Install and configure CloudWatch agent for logging
9+
echo "Installing CloudWatch agent..."
10+
yum install -y amazon-cloudwatch-agent
11+
12+
# Create CloudWatch agent configuration
13+
cat > /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json << EOF
14+
{
15+
"logs": {
16+
"logs_collected": {
17+
"files": {
18+
"collect_list": [
19+
{
20+
"file_path": "/var/log/bootstrap.log",
21+
"log_group_name": "$LOG_GROUP_NAME",
22+
"log_stream_name": "{instance_id}",
23+
"retention_in_days": 7
24+
}
25+
]
26+
}
27+
}
28+
}
29+
}
30+
EOF
31+
32+
# Start CloudWatch agent
33+
/opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl \
34+
-a fetch-config -m ec2 -c file:/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json -s
35+
36+
# Redirect all bootstrap output to log file and console
37+
exec > >(tee -a /var/log/bootstrap.log)
38+
exec 2>&1
39+
40+
echo "Bootstrap started at $(date) - Logging to $LOG_GROUP_NAME"
441
echo "Retrieving IDE password..."
542
643
PASSWORD_SECRET_VALUE=$(aws secretsmanager get-secret-value --secret-id "${passwordName}" --query 'SecretString' --output text)

infrastructure/cdk/src/main/resources/lambda.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,7 @@ def lambda_handler(event, context):
5353

5454
ssm.send_command(
5555
InstanceIds=[instance_id],
56-
DocumentName=ssm_document,
57-
CloudWatchOutputConfig={
58-
'CloudWatchLogGroupName': event['ResourceProperties']['LogGroupName'],
59-
'CloudWatchOutputEnabled': True
60-
})
56+
DocumentName=ssm_document)
6157

6258
responseData = {'Success': 'Started bootstrapping for instance: '+instance_id}
6359
except Exception as e:

0 commit comments

Comments
 (0)