Skip to content

Instantly share code, notes, and snippets.

@logemann
Last active April 8, 2022 18:43
Show Gist options
  • Save logemann/621ce5649ef7e91cac802d5ad1d9a858 to your computer and use it in GitHub Desktop.
Save logemann/621ce5649ef7e91cac802d5ad1d9a858 to your computer and use it in GitHub Desktop.
VpnStack example for AWS CDK
import { Construct, Stack, Tag, ConcreteDependable} from '@aws-cdk/core';
import { CfnClientVpnTargetNetworkAssociation, CfnClientVpnEndpoint, CfnClientVpnAuthorizationRule, CfnClientVpnRoute, Vpc } from '@aws-cdk/aws-ec2'
import { ISecret } from '@aws-cdk/aws-secretsmanager';
import { ExtendedStackProps } from '../model/ExtendedStackProps';
import * as certManager from '@aws-cdk/aws-certificatemanager';
import * as logs from '@aws-cdk/aws-logs';
export class VpnStack extends Stack {
readonly secret: ISecret;
// creating server and clients certs is best done by following the AWS page on:
// https://docs.aws.amazon.com/de_de/vpn/latest/clientvpn-admin/authentication-authorization.html#mutual
certArn = "arn:aws:XXXXXXXXXXXXXX";
clientArn = "arn:aws:YYYYYYYYYYYYYY";
constructor(scope: Construct, id: string, props?: ExtendedStackProps) {
super(scope, id, props);
const clientCert = certManager.Certificate.fromCertificateArn(
this,
'ClientCertificate',
this.clientArn
);
const serverCert = certManager.Certificate.fromCertificateArn(
this,
'ServerCertificate',
this.certArn
);
const logGroup = new logs.LogGroup(this, 'ClientVpnLogGroup', {
retention: logs.RetentionDays.ONE_MONTH
});
const logStream = logGroup.addStream('ClientVpnLogStream');
const endpoint = new CfnClientVpnEndpoint(this, 'ClientVpnEndpoint2', {
description: "VPN",
authenticationOptions: [{
type: "certificate-authentication",
mutualAuthentication: {
clientRootCertificateChainArn: clientCert.certificateArn
}
}],
tagSpecifications: [{
resourceType: "client-vpn-endpoint",
tags: [{
key: "Name",
value: "Swyp VPN CDK created"
}]
}],
clientCidrBlock: "10.1.132.0/22",
connectionLogOptions: {
enabled: true,
cloudwatchLogGroup: logGroup.logGroupName,
cloudwatchLogStream: logStream.logStreamName
},
serverCertificateArn: serverCert.certificateArn,
// If you need to route all the traffic through the VPN (not only for the resources inside, turn this off)
splitTunnel: false,
dnsServers: ["8.8.8.8", "8.8.4.4"],
});
let i = 0;
const dependables = new ConcreteDependable();
props?.vpc.privateSubnets.map(subnet => {
let networkAsc = new CfnClientVpnTargetNetworkAssociation(this, 'ClientVpnNetworkAssociation-' + i, {
clientVpnEndpointId: endpoint.ref,
subnetId: subnet.subnetId
});
dependables.add(networkAsc);
i++;
});
new CfnClientVpnAuthorizationRule(this, 'ClientVpnAuthRule', {
clientVpnEndpointId: endpoint.ref,
targetNetworkCidr: "0.0.0.0/0",
authorizeAllGroups: true,
description: "Allow all"
});
// add routs for two subnets so that i can surf the internet while in VPN (useful when splitTunnel is off)
let x = 0;
props?.vpc.privateSubnets.map(subnet => {
new CfnClientVpnRoute(this, `CfnClientVpnRoute${x}` , {
clientVpnEndpointId: endpoint.ref,
destinationCidrBlock: "0.0.0.0/0",
description: "Route to all",
targetVpcSubnetId: props?.vpc.privateSubnets[x].subnetId!,
}).node.addDependency(dependables);
x++;
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment