Created
April 28, 2026 14:16
-
-
Save simonespa/277cdbf0d79976772fb939675c2aaa37 to your computer and use it in GitHub Desktop.
CDK code to spawn an EC2 instance
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import * as cdk from 'aws-cdk-lib'; | |
| import * as ec2 from 'aws-cdk-lib/aws-ec2'; | |
| import * as iam from 'aws-cdk-lib/aws-iam'; | |
| import { Construct } from 'constructs'; | |
| export class Ec2Stack extends cdk.Stack { | |
| constructor(scope: Construct, id: string, props?: cdk.StackProps) { | |
| super(scope, id, props); | |
| const keyPair = new ec2.KeyPair(this, 'KeyPair', { | |
| keyPairName: 'ec2-key-pair', | |
| type: ec2.KeyPairType.RSA, | |
| format: ec2.KeyPairFormat.PEM, | |
| }); | |
| const allowedSshCidr = new cdk.CfnParameter(this, 'AllowedSshCidr', { | |
| type: 'String', | |
| default: '0.0.0.0/0', | |
| description: 'CIDR range allowed to SSH to the EC2 instance (recommend locking this down).', | |
| allowedPattern: '^([0-9]{1,3}\\.){3}[0-9]{1,3}/[0-9]{1,2}$', | |
| constraintDescription: 'Must be a valid IPv4 CIDR block (for example 203.0.113.10/32).', | |
| }); | |
| const vpc = new ec2.Vpc(this, 'Vpc', { | |
| availabilityZones: ['eu-west-1a'], | |
| natGateways: 0, | |
| subnetConfiguration: [ | |
| { | |
| name: 'public', | |
| subnetType: ec2.SubnetType.PUBLIC, | |
| cidrMask: 24, | |
| }, | |
| ], | |
| }); | |
| const securityGroup = new ec2.SecurityGroup(this, 'InstanceSecurityGroup', { | |
| vpc, | |
| description: 'Allow SSH access to the EC2 instance.', | |
| allowAllOutbound: true, | |
| }); | |
| securityGroup.addIngressRule( | |
| ec2.Peer.ipv4(allowedSshCidr.valueAsString), | |
| ec2.Port.tcp(22), | |
| 'Allow inbound SSH', | |
| ); | |
| const instanceRole = new iam.Role(this, 'InstanceRole', { | |
| assumedBy: new iam.ServicePrincipal('ec2.amazonaws.com'), | |
| managedPolicies: [ | |
| iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonSSMManagedInstanceCore'), | |
| ], | |
| }); | |
| const instanceProfile = new iam.CfnInstanceProfile(this, 'InstanceProfile', { | |
| roles: [instanceRole.roleName], | |
| }); | |
| const amiId = '{{resolve:ssm:/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-arm64}}'; | |
| const userDataScript = [ | |
| '#!/bin/bash', | |
| 'set -euxo pipefail', | |
| 'dnf update -y', | |
| 'dnf install -y git nodejs24', | |
| 'npm install --global corepack@latest', | |
| 'corepack prepare pnpm@latest --activate', | |
| 'corepack prepare yarn@stable --activate' | |
| ].join('\n'); | |
| const ec2Instance = new ec2.CfnInstance(this, 'Ec2Instance', { | |
| imageId: amiId, | |
| instanceType: 'm8g.medium', | |
| keyName: keyPair.keyPairName, | |
| iamInstanceProfile: instanceProfile.ref, | |
| userData: cdk.Fn.base64(userDataScript), | |
| networkInterfaces: [ | |
| { | |
| associatePublicIpAddress: true, | |
| deviceIndex: '0', | |
| subnetId: vpc.publicSubnets[0].subnetId, | |
| groupSet: [securityGroup.securityGroupId], | |
| }, | |
| ], | |
| tags: [ | |
| { | |
| key: 'Name', | |
| value: 'ec2-instance', | |
| }, | |
| ], | |
| }); | |
| const eip = new ec2.CfnEIP(this, 'ElasticIp', { | |
| domain: 'vpc', | |
| }); | |
| new ec2.CfnEIPAssociation(this, 'Ec2ElasticIpAssociation', { | |
| allocationId: eip.attrAllocationId, | |
| instanceId: ec2Instance.ref, | |
| }); | |
| new cdk.CfnOutput(this, 'Ec2InstancePublicIp', { | |
| value: eip.ref, | |
| description: 'Elastic IP for the Linux EC2 instance.', | |
| }); | |
| new cdk.CfnOutput(this, 'SshPrivateKeyCommand', { | |
| value: `aws ssm get-parameter --name /ec2/keypair/${keyPair.keyPairId} --with-decryption --query Parameter.Value --output text > ec2-key.pem && chmod 400 ec2-key.pem`, | |
| description: 'AWS CLI command to download the private key from SSM Parameter Store.', | |
| }); | |
| new cdk.CfnOutput(this, 'SshCommand', { | |
| value: cdk.Fn.join('', ['ssh -i ec2-key.pem ec2-user@', eip.ref]), | |
| description: 'Example SSH command to connect to the EC2 instance.', | |
| }); | |
| new cdk.CfnOutput(this, 'ScpCommandExample', { | |
| value: cdk.Fn.join('', [ | |
| 'scp -i ec2-key.pem <local-file> ec2-user@', | |
| eip.ref, | |
| ':/home/ec2-user/', | |
| ]), | |
| description: 'Example SCP command to copy files to the EC2 instance.', | |
| }); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment