Skip to content

Commit 944bc4d

Browse files
authored
feat: update packages (#1168)
* feat: update packages * Fix: update pipeline for verbose errors * Fix: update pipeline for verbose errors * Fix: update pipeline for verbose errors
1 parent d1ef593 commit 944bc4d

File tree

13 files changed

+395
-32
lines changed

13 files changed

+395
-32
lines changed

.github/workflows/build-pull-request.yml

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -128,18 +128,52 @@ jobs:
128128
# Change to language directory
129129
cd ./${{ matrix.language }}
130130
131-
# Run the build_file function in parallel for each project to be built
132-
# Halt the execution if any of the build_file invocations fail
131+
# Run the build_file function for each project to be built
133132
echo "::group::Build Output"
134133
echo "Starting builds for all projects..."
135-
parallel --keep-order --halt-on-error 2 build_file ::: "${apps_to_build[@]}"
134+
135+
# Track failed builds
136+
failed_builds=()
137+
138+
# Process each project one by one with clear grouping
139+
for app in "${apps_to_build[@]}"; do
140+
echo "::group::Building $app"
141+
142+
# Run the build directly
143+
set +e # Don't exit on error
144+
../scripts/build-${language}.sh "$app"
145+
build_exit=$?
146+
set -e # Re-enable exit on error
147+
148+
if [ $build_exit -ne 0 ]; then
149+
echo "❌ BUILD FAILED: $app (exit code $build_exit)"
150+
failed_builds+=("$app")
151+
else
152+
echo "✅ BUILD SUCCEEDED: $app"
153+
fi
154+
echo "::endgroup::"
155+
done
136156
echo "::endgroup::"
137-
138-
# Check the exit status of parallel
139-
parallel_exit=$?
157+
158+
# Print summary outside of any group
159+
echo ""
160+
echo "====== BUILD SUMMARY ======"
161+
if [ ${#failed_builds[@]} -gt 0 ]; then
162+
echo "❌ FAILED BUILDS:"
163+
for failed in "${failed_builds[@]}"; do
164+
echo " - $failed"
165+
done
166+
parallel_exit=1
167+
else
168+
echo "✅ ALL BUILDS SUCCEEDED"
169+
parallel_exit=0
170+
fi
171+
echo "=========================="
172+
echo ""
173+
140174
# If parallel failed, make sure the workflow fails too
141175
if [ $parallel_exit -ne 0 ]; then
142-
echo "::error::One or more builds failed. See build output above for details."
176+
echo "::error::One or more builds failed. See build summary above for details."
143177
exit $parallel_exit
144178
else
145179
echo "✅ All builds completed successfully!"

typescript/ec2-instance-connect-endpoint/package.json

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,13 @@
2020
"@typescript-eslint/eslint-plugin": "^5",
2121
"@typescript-eslint/parser": "^5",
2222
"aws-cdk": "2.1010.0",
23-
"aws-cdk-lib": "2.85.0",
2423
"constructs": "10.0.5",
2524
"eslint": "^8",
2625
"jest": "^29.7.0",
2726
"ts-jest": "^29.2.5",
2827
"ts-node": "^10.9.2",
2928
"typescript": "~5.6.3"
3029
},
31-
"peerDependencies": {
32-
"aws-cdk-lib": "^2.85.0",
33-
"constructs": "^10.0.5"
34-
},
3530
"dependencies": {
3631
"aws-cdk-lib": "2.190.0",
3732
"constructs": "^10.0.0"

typescript/ec2-instance/.gitignore

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,3 @@ cdk.out
1111
# Parcel default cache directory
1212
.parcel-cache
1313

14-
# Build output
15-
lib
16-
coverage
17-
.nyc_output
18-
dist
19-
.DS_Store
Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
import { RemovalPolicy, Duration, Stack } from 'aws-cdk-lib';
2+
import {
3+
Vpc,
4+
SecurityGroup,
5+
Instance,
6+
InstanceType,
7+
InstanceClass,
8+
InstanceSize,
9+
CloudFormationInit,
10+
InitConfig,
11+
InitFile,
12+
InitCommand,
13+
UserData,
14+
MachineImage,
15+
AmazonLinuxCpuType,
16+
} from 'aws-cdk-lib/aws-ec2';
17+
import {
18+
Role,
19+
ServicePrincipal,
20+
ManagedPolicy,
21+
PolicyDocument,
22+
PolicyStatement,
23+
} from 'aws-cdk-lib/aws-iam';
24+
import { Bucket, ObjectOwnership } from 'aws-cdk-lib/aws-s3';
25+
import { Source, BucketDeployment } from 'aws-cdk-lib/aws-s3-deployment';
26+
import { Construct } from 'constructs';
27+
28+
interface ServerProps {
29+
vpc: Vpc;
30+
sshSecurityGroup: SecurityGroup;
31+
logLevel: string;
32+
sshPubKey: string;
33+
cpuType: string;
34+
instanceSize: string;
35+
}
36+
37+
let cpuType: AmazonLinuxCpuType;
38+
let instanceClass: InstanceClass;
39+
let instanceSize: InstanceSize;
40+
41+
export class ServerResources extends Construct {
42+
public instance: Instance;
43+
44+
constructor(scope: Construct, id: string, props: ServerProps) {
45+
super(scope, id);
46+
47+
// Create an Asset Bucket for the Instance. Assets in this bucket will be downloaded to the EC2 during deployment
48+
const assetBucket = new Bucket(this, 'assetBucket', {
49+
publicReadAccess: false,
50+
removalPolicy: RemovalPolicy.DESTROY,
51+
objectOwnership: ObjectOwnership.BUCKET_OWNER_PREFERRED,
52+
autoDeleteObjects: true,
53+
});
54+
55+
// Deploy the local assets to the Asset Bucket during the CDK deployment
56+
new BucketDeployment(this, 'assetBucketDeployment', {
57+
sources: [Source.asset('lib/resources/server/assets')],
58+
destinationBucket: assetBucket,
59+
retainOnDelete: false,
60+
exclude: ['**/node_modules/**', '**/dist/**'],
61+
memoryLimit: 512,
62+
});
63+
64+
// Create a role for the EC2 instance to assume. This role will allow the instance to put log events to CloudWatch Logs
65+
const serverRole = new Role(this, 'serverEc2Role', {
66+
assumedBy: new ServicePrincipal('ec2.amazonaws.com'),
67+
inlinePolicies: {
68+
['RetentionPolicy']: new PolicyDocument({
69+
statements: [
70+
new PolicyStatement({
71+
resources: ['*'],
72+
actions: ['logs:PutRetentionPolicy'],
73+
}),
74+
],
75+
}),
76+
},
77+
managedPolicies: [
78+
ManagedPolicy.fromAwsManagedPolicyName('AmazonSSMManagedInstanceCore'),
79+
ManagedPolicy.fromAwsManagedPolicyName('CloudWatchAgentServerPolicy'),
80+
],
81+
});
82+
83+
// Grant the EC2 role access to the bucket
84+
assetBucket.grantReadWrite(serverRole);
85+
86+
const userData = UserData.forLinux();
87+
88+
// Add user data that is used to configure the EC2 instance
89+
userData.addCommands(
90+
'yum update -y',
91+
'curl -sL https://dl.yarnpkg.com/rpm/yarn.repo | sudo tee /etc/yum.repos.d/yarn.repo',
92+
'curl -sL https://rpm.nodesource.com/setup_18.x | sudo -E bash - ',
93+
'yum install -y amazon-cloudwatch-agent nodejs python3-pip zip unzip docker yarn',
94+
'sudo systemctl enable docker',
95+
'sudo systemctl start docker',
96+
'mkdir -p /home/ec2-user/sample',
97+
'aws s3 cp s3://' +
98+
assetBucket.bucketName +
99+
'/sample /home/ec2-user/sample --recursive',
100+
);
101+
102+
// Create a Security Group for the EC2 instance. This group will allow SSH access to the EC2 instance
103+
const ec2InstanceSecurityGroup = new SecurityGroup(
104+
this,
105+
'ec2InstanceSecurityGroup',
106+
{ vpc: props.vpc, allowAllOutbound: true },
107+
);
108+
109+
// Determine the correct CPUType and Instance Class based on the props passed in
110+
if (props.cpuType == 'ARM64') {
111+
cpuType = AmazonLinuxCpuType.ARM_64;
112+
instanceClass = InstanceClass.M7G;
113+
} else {
114+
cpuType = AmazonLinuxCpuType.X86_64;
115+
instanceClass = InstanceClass.M5;
116+
}
117+
118+
// Determine the correct InstanceSize based on the props passed in
119+
switch (props.instanceSize) {
120+
case 'large':
121+
instanceSize = InstanceSize.LARGE;
122+
break;
123+
case 'xlarge':
124+
instanceSize = InstanceSize.XLARGE;
125+
break;
126+
case 'xlarge2':
127+
instanceSize = InstanceSize.XLARGE2;
128+
break;
129+
case 'xlarge4':
130+
instanceSize = InstanceSize.XLARGE4;
131+
break;
132+
default:
133+
instanceSize = InstanceSize.LARGE;
134+
}
135+
136+
// Create the EC2 instance
137+
this.instance = new Instance(this, 'Instance', {
138+
vpc: props.vpc,
139+
instanceType: InstanceType.of(instanceClass, instanceSize),
140+
machineImage: MachineImage.latestAmazonLinux2023({
141+
cachedInContext: false,
142+
cpuType: cpuType,
143+
}),
144+
userData: userData,
145+
securityGroup: ec2InstanceSecurityGroup,
146+
init: CloudFormationInit.fromConfigSets({
147+
configSets: {
148+
default: ['config'],
149+
},
150+
configs: {
151+
config: new InitConfig([
152+
InitFile.fromObject('/etc/config.json', {
153+
// Use CloudformationInit to create an object on the EC2 instance
154+
STACK_ID: Stack.of(this).artifactId,
155+
}),
156+
InitFile.fromFileInline(
157+
// Use CloudformationInit to copy a file to the EC2 instance
158+
'/tmp/amazon-cloudwatch-agent.json',
159+
'./lib/resources/server/config/amazon-cloudwatch-agent.json',
160+
),
161+
InitFile.fromFileInline(
162+
'/etc/config.sh',
163+
'lib/resources/server/config/config.sh',
164+
),
165+
InitFile.fromString(
166+
// Use CloudformationInit to write a string to the EC2 instance
167+
'/home/ec2-user/.ssh/authorized_keys',
168+
props.sshPubKey + '\n',
169+
),
170+
InitCommand.shellCommand('chmod +x /etc/config.sh'), // Use CloudformationInit to run a shell command on the EC2 instance
171+
InitCommand.shellCommand('/etc/config.sh'),
172+
]),
173+
},
174+
}),
175+
176+
initOptions: {
177+
timeout: Duration.minutes(10),
178+
includeUrl: true,
179+
includeRole: true,
180+
printLog: true,
181+
},
182+
role: serverRole,
183+
});
184+
185+
// Add the SSH Security Group to the EC2 instance
186+
this.instance.addSecurityGroup(props.sshSecurityGroup);
187+
}
188+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import {
2+
SecurityGroup,
3+
Peer,
4+
Port,
5+
SubnetType,
6+
Vpc,
7+
} from 'aws-cdk-lib/aws-ec2';
8+
import { Construct } from 'constructs';
9+
10+
export class VPCResources extends Construct {
11+
public sshSecurityGroup: SecurityGroup;
12+
public vpc: Vpc;
13+
14+
constructor(scope: Construct, id: string) {
15+
super(scope, id);
16+
17+
// Create a VPC with public subnets in 2 AZs
18+
this.vpc = new Vpc(this, 'VPC', {
19+
natGateways: 0,
20+
subnetConfiguration: [
21+
{
22+
cidrMask: 24,
23+
name: 'ServerPublic',
24+
subnetType: SubnetType.PUBLIC,
25+
mapPublicIpOnLaunch: true,
26+
},
27+
],
28+
maxAzs: 2,
29+
});
30+
31+
// Create a security group for SSH
32+
this.sshSecurityGroup = new SecurityGroup(this, 'SSHSecurityGroup', {
33+
vpc: this.vpc,
34+
description: 'Security Group for SSH',
35+
allowAllOutbound: true,
36+
});
37+
38+
// Allow SSH inbound traffic on TCP port 22
39+
this.sshSecurityGroup.addIngressRule(Peer.anyIpv4(), Port.tcp(22));
40+
}
41+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { Stack, StackProps, CfnOutput } from 'aws-cdk-lib';
2+
import { Construct } from 'constructs';
3+
import { VPCResources } from './constructs/vpc';
4+
import { ServerResources } from './constructs/server';
5+
import { EC2ExampleProps, envValidator } from './utils/env-validator';
6+
7+
export interface EC2StackProps extends StackProps, EC2ExampleProps {}
8+
9+
export class EC2Stack extends Stack {
10+
constructor(scope: Construct, id: string, props: EC2StackProps) {
11+
super(scope, id, props);
12+
13+
const { logLevel, sshPubKey, cpuType, instanceSize } = props;
14+
15+
// Validate environment variables
16+
envValidator(props);
17+
18+
// Create VPC and Security Group
19+
const vpcResources = new VPCResources(this, 'VPC');
20+
21+
// Create EC2 Instance
22+
const serverResources = new ServerResources(this, 'EC2', {
23+
vpc: vpcResources.vpc,
24+
sshSecurityGroup: vpcResources.sshSecurityGroup,
25+
logLevel: logLevel,
26+
sshPubKey: sshPubKey,
27+
cpuType: cpuType,
28+
instanceSize: instanceSize.toLowerCase(),
29+
});
30+
31+
// SSM Command to start a session
32+
new CfnOutput(this, 'ssmCommand', {
33+
value: `aws ssm start-session --target ${serverResources.instance.instanceId}`,
34+
});
35+
36+
// SSH Command to connect to the EC2 Instance
37+
new CfnOutput(this, 'sshCommand', {
38+
value: `ssh ec2-user@${serverResources.instance.instancePublicDnsName}`,
39+
});
40+
}
41+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Sample file that can be downloaded during deploy.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"agent": {
3+
"run_as_user": "root"
4+
},
5+
"logs": {
6+
"logs_collected": {
7+
"files": {
8+
"collect_list": [
9+
{
10+
"file_path": "/var/log/cloud-init-output.log",
11+
"log_group_name": "/ec2/log/ec2-example/",
12+
"log_stream_name": "{instance_id}-cloud-init-output",
13+
"retention_in_days": 7
14+
},
15+
{
16+
"file_path": "/var/log/cloud-init.log",
17+
"log_group_name": "/ec2/log/ec2-example/",
18+
"log_stream_name": "{instance_id}-cloud-init",
19+
"retention_in_days": 7
20+
}
21+
]
22+
}
23+
}
24+
}
25+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#!/bin/bash -xe
2+
/opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file:/tmp/amazon-cloudwatch-agent.json

0 commit comments

Comments
 (0)