- ENG
- Services
- Unser Serviceportfolio
Wir erwecken Ihre digitale Produktvision zum Leben: Vom testbaren Prototypen bis zur fertigen Softwarelösung.
- Kooperationsmodelle
Kooperationsmodelle passend zu Ihren Bedürfnissen: Komplette Nearshoring Teams, deutschsprachige Experten vor Ort mit Nearshoring-Teams oder gemischte Teams mit unseren Partnern.
- Arbeitsweise
Durch enge Zusammenarbeit mit Ihrem Unternehmen schaffen wir maßgeschneiderte Lösungen, die auf Ihre Anforderungen abgestimmt sind und zu nachhaltigen Ergebnissen führen.
- Unser Serviceportfolio
- Über uns
- Wer wir sind
Wir sind ein Full-Service Nearshoring-Anbieter für digitale Softwareprodukte, ein perfekter Partner mit deutschsprachigen Experten vor Ort, Ihre Business-Anforderungen stets im Blick
- Unser Team
Das ProductDock Team ist mit modernen Technologien und Tools vertraut und setzt seit 15 Jahren zusammen mit namhaften Firmen erfolgreiche Projekte um.
- Unsere Standorte
Wir sind ProductDock, ein Full-Service Nearshoring-Anbieter für Softwareprodukte mit Hauptsitz in Berlin und Entwicklungs-Hubs in Lissabon, Novi Sad, Banja Luka und Doboj.
- Wozu Nearshoring
Wir kombinieren Nearshore- und Fachwissen vor Ort, um Sie während Ihrer gesamten digitalen Produktreise optimal zu unterstützen. Lassen Sie uns Ihr Business gemeinsam auf das nächste digitale Level anheben.
- Wer wir sind
- Unser Leistungen
- Karriere
- Arbeiten bei ProductDock
Unser Fokus liegt auf der Förderung von Teamarbeit, Kreativität und Empowerment innerhalb unseres Teams von über 120 talentierten Tech-Experten.
- Offene Stellen
Begeistert es dich, an spannenden Projekten mitzuwirken und zu sehen, wie dein Einsatz zu erfolgreichen Ergebnissen führt? Dann bist du bei uns richtig.
- Info Guide für Kandidaten
Wie suchen wir unsere Crew-Mitglieder aus? Wir sehen dich als Teil unserer Crew und erklären gerne unseren Auswahlprozess.
- Arbeiten bei ProductDock
- Newsroom
- News
Folgen Sie unseren neuesten Updates und Veröffentlichungen, damit Sie stets über die aktuellsten Entwicklungen von ProductDock informiert sind.
- Events
Vertiefen Sie Ihr Wissen, indem Sie sich mit Gleichgesinnten vernetzen und an unseren nächsten Veranstaltungen Erfahrungen mit Experten austauschen.
- News
- Blog
- Kontakt
12. Dez. 2024 •4 minutes read
Nagging can be good: Improving your AWS IaC with cdk-nag
Jovica Zorić
Chief Technology Officer
The AWS Cloud Development Kit (CDK) allows engineers to define and deploy cloud resources using code, enabling fast, repeatable, and consistent infrastructure setups. But while CDK simplifies resource creation, it doesn’t automatically enforce security, compliance, or best practices.
Enter cdk-nag, your infrastructure reviewer. It identifies security gaps, compliance violations, and deviations from best practices before they become problems. cdk-nag can check your code against predefined rule sets—such as AWS Solutions, HIPAA, NIST, or PCI—helping you build smarter and safer cloud environments. It is a part of the AWS CDK ecosystem and maintained by AWS itself.
Let’s see it in action by working on a common use case: setting up a simple workshop environment with a VPC, EC2 instance, and security groups. Here’s the starting AWS CDK code in TypeScript (a Golang version is also available (4)).
// ####### START VPC #######
const vpc = new Vpc(this, 'workshop-vpc', {
natGateways: 0,
maxAzs: 1,
subnetConfiguration: [
{
cidrMask: 24,
name: 'workshop-public',
subnetType: SubnetType.PUBLIC,
mapPublicIpOnLaunch: true,
}
],
});
// ####### END VPC #######
// ####### START SSH SG #######
const sshSecurityGroup = new SecurityGroup(this, 'workshop-ssh-sg', {
vpc: vpc,
description: 'Workshop ssh security group',
allowAllOutbound: true,
})
sshSecurityGroup.addIngressRule(
Peer.anyIpv4(),
Port.tcp(22),
'SSH from everywhere'
)
// ####### END SSH SG #######
// ####### START EC2 ROLE #######
// This role will allow the instance to put log events to CloudWatch Logs
const ec2Role = new Role(this, 'workshop-ec2-role', {
assumedBy: new ServicePrincipal('ec2.amazonaws.com'),
inlinePolicies: {
['RetentionPolicy']: new PolicyDocument({
statements: [
new PolicyStatement({
resources: ['*'],
actions: ['logs:PutRetentionPolicy'],
}),
],
}),
},
managedPolicies: [
ManagedPolicy.fromAwsManagedPolicyName('CloudWatchAgentServerPolicy'),
],
});
// ####### END EC2 ROLE #######
// ####### START APP SG #######
const appSecurityGroup = new SecurityGroup(this, 'workshop-app-sg', {
vpc: vpc,
description: "Workshop app security group",
allowAllOutbound: true,
}
)
appSecurityGroup.addIngressRule(
Peer.anyIpv4(),
Port.tcp(8085),
"Our APP will be running on this port"
);
// ####### END APP SG #######
// ####### START EC2 INSTANCE ######
const ec2Instance = new Instance(this, 'workshop-ec2-instance', {
vpc: vpc,
instanceType: InstanceType.of(InstanceClass.BURSTABLE3, InstanceSize.MEDIUM),
machineImage: MachineImage.genericLinux({
"eu-central-1": 'ami-0cee4a3eca5195216',
}, {}),
securityGroup: appSecurityGroup,
role: ec2Role,
userData: UserData.forLinux(),
blockDevices: [{
deviceName: "/dev/xvdh",
volume: BlockDeviceVolume.ebs(8, {
encrypted: true
})
}],
})
ec2Instance.userData.addCommands(
`echo "${props.sshPubKey}" >> /home/ubuntu/.ssh/authorized_keys`,
);
ec2Instance.addSecurityGroup(sshSecurityGroup);
new CfnOutput(this, 'ssh-command', {
value: `ssh -i live ubuntu@${ec2Instance.instancePublicDnsName}`
});
// ####### END EC2 INSTANCE ######
This is fairly standard code you’ll encounter in many examples. We’ve been discussing best practices and how to implement them effectively, so we decided to integrate cdk-nag to analyze our infrastructure code and understand its recommendations.
First things first, adding cdk-nag to our project.
Adding cdk-nag to our project
The first step is to install the cdk-nag package in your project.
npm install cdk-nag
To start, we added cdk-nag to the whole stack by modifying bin/nagging-can-be-good.ts (1):
Aspects.of(app).add(new AwsSolutionsChecks());
We want to check our IaC against best practices based on the AWS Solutions Security Matrix. Check out other rules here: https://github.com/cdklabs/cdk-nag?tab=readme-ov-file#available-rules-and-packs
Now that the setup is complete we can run `cdk synth` and review each issue and its resolution.
Issue #1: VPC
Error:
[Error at /NaggingCanBeGoodStack/workshop-vpc/Resource] AwsSolutions-VPC7: The VPC does not have an associated Flow Log.
Solution:
To fix this error, we can enable VPC Flow logs and direct all logs to CloudWatch. While this will increase network traffic visibility, CloudWatch integration is fine, but S3 is often a better destination for the following reasons:
- lower storage costs,
- flexible lifecycle management,
- native integration with Athena for log analysis.
For more details, check the documentation here and pricing here.
Let’s update our code:
// after subnet configuration
flowLogs: {
'cw': {
destination: FlowLogDestination.toCloudWatchLogs()
}
}
});
Issue #2: Security Group (SSH)
Error:
[Error at /NaggingCanBeGoodStack/workshop-ssh-sg/Resource] AwsSolutions-EC23: The Security Group allows for 0.0.0.0/0 or ::/0 inbound access.
Solution:
To resolve this issue, we should allow SSH connection from known IPs, such as our home or work IPs.
Peer.ipv4("80.81.82.83/32")
For the workshop, we will acknowledge the risk and suppress the error by adding a `NagSuppressions:`
NagSuppressions.addResourceSuppressions(sshSecurityGroup, [
{id: 'AwsSolutions-EC23', reason: 'Can be open as workshop will be done in 1h.'}
]);
Issue #3: EC2 Role
Error 1:
[Error at /NaggingCanBeGoodStack/workshop-ec2-role/Resource] AwsSolutions-IAM4[Policy::arn:<:partition>:iam::aws:policy/CloudWatchAgentServerPolicy]: The IAM user, role, or group uses AWS managed policies.
Solution:
An AWS managed policy is a standalone policy that is created and administered by AWS. Currently, many AWS managed policies do not restrict resource scope. We can replace AWS managed policies with our custom managed ones, but for the workshop we will suppress this error by adding NagSuppressions.
Error 2:
[Error at /NaggingCanBeGoodStack/workshop-ec2-role/Resource] AwsSolutions-IAM5[Resource::*]: The IAM entity contains wildcard permissions and does not have a cdk-nag rule suppression with evidence for those permission.
Solution:
We should keep in mind that overly permissive IAM policies using wildcards (*) are not recommended and should be avoided. For this workshop, it’s fine, we can suppress it.
To group everything together:
NagSuppressions.addResourceSuppressions(ec2Role, [
{
id: 'AwsSolutions-IAM4',
reason: 'It is ok for our workshop'
},
{
id: 'AwsSolutions-IAM5',
reason: 'It is ok for our workshop',
appliesTo: ['Resource::*']
}
])
Issue #4: Security Group (APP)
The APP Security Group flagged the same issue as the SSH group (0.0.0.0/0 access). We will use the same solution as in Issue #2.
Issue #5: EC2 Instance
Error 1:
[Error at /NaggingCanBeGoodStack/workshop-ec2-instance/Resource] AwsSolutions-EC26: The resource creates one or more EBS volumes that have encryption disabled.
Solution:
That’s a good point. Let’s turn on encryption for our EBS volume, which will help protect data at rest.
blockDevices: [{
deviceName: "/dev/xvdh",
volume: BlockDeviceVolume.ebs(8, {
encrypted: true
})
}]
Error 2:
[Error at /NaggingCanBeGoodStack/workshop-ec2-instance/Resource] AwsSolutions-EC28: The EC2 instance/AutoScaling launch configuration does not have detailed monitoring enabled.
Solution:
Our instance is configured with default monitoring, and for our workshop, we don’t need detailed monitoring. https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/manage-detailed-monitoring.html
Let’s suppress it:
NagSuppressions.addResourceSuppressions(ec2Instance, [
{id: 'AwsSolutions-EC28', reason: 'Basic monitoring is enough for this workshop'}
]);
Error 3:
[Error at /NaggingCanBeGoodStack/workshop-ec2-instance/Resource] AwsSolutions-EC29: The EC2 instance is not part of an ASG and has Termination Protection disabled.
Solution:
For this workshop, we don’t need to think about Termination Protection, as the environment will be destroyed in 1 hour.
Let’s suppress it:
NagSuppressions.addResourceSuppressions(ec2Instance, [
{id: 'AwsSolutions-EC29', reason: 'No termination protection needed for this workshop'},
]);
In the end
Integrating cdk-nag into your AWS CDK projects is more than just checking boxes—it’s about building a robust foundation for your cloud infrastructure. While the initial warnings might seem overwhelming, each resolution strengthens your architecture and helps prevent potential security incidents. Suppressing rules is sometimes necessary, and that’s ok, but ensure each override is thoroughly documented to maintain transparency and accountability.
You can also create your own NagPack, which is outside the scope of this blog post, but be sure to check out the docs: https://github.com/cdklabs/cdk-nag/blob/main/docs/NagPack.md
Check out the cdk-nag documentation, and let me finish by saying It’s better to be nagged than being alerted!
Resources
- Typescript workshop repository: https://github.com/ProductDock/nagging-can-be-good
- cdk-nag repository: https://github.com/cdklabs/cdk-nag
- Aws solutions rules: https://github.com/cdklabs/cdk-nag/blob/main/RULES.md#awssolutions
- Golang workshop repository: https://github.com/ProductDock/nagging-can-be-good/tree/golang
Tags:
Jovica Zorić
Chief Technology OfficerJovica is a techie with more than ten years of experience. His job has evolved throughout the years, leading to his present position as the CTO at ProductDock. He will help you to choose the right technology for your business ideas and focus on the outcomes.