Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add cloudflare example #260

Closed
wants to merge 2 commits into from
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Add cloudflare example
corymhall committed Nov 26, 2024
commit 5c07ba694a31b8f76ac32de63f6ac9b684c04112
3 changes: 3 additions & 0 deletions examples/cloudflare-example/Pulumi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
name: pulumi-aws-cdk-fargate
runtime: nodejs
description: Fargate example for CDK
14 changes: 14 additions & 0 deletions examples/cloudflare-example/app/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
FROM node:lts AS builder

WORKDIR /app

COPY package.json yarn.lock ./
COPY app ./

RUN yarn install --frozen-lockfile
RUN npx esbuild --bundle index.ts --target="node18" --platform="node" --outfile="index.js"

FROM node:18-alpine
COPY --from=builder /app/index.js /app/index.js
EXPOSE 80
CMD ["node", "/app/index.js"]
14 changes: 14 additions & 0 deletions examples/cloudflare-example/app/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import express, { Request, Response } from 'express';
const app = express();

app.get('/', async (_req: Request, res: Response) => {
res.status(200).send('Hello, world!');
});

app.get('/health', (_req: Request, res: Response) => {
res.status(200).send(JSON.stringify({ message: 'OK' }));
});

app.listen(80, () => {
console.log('Listening on port 8080');
});
111 changes: 111 additions & 0 deletions examples/cloudflare-example/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import * as path from 'path';
import * as acm from 'aws-cdk-lib/aws-certificatemanager';
import * as aws from '@pulumi/aws';
import * as pulumi from '@pulumi/pulumi';
import * as pulumicdk from '@pulumi/cdk';
import * as tls from '@pulumi/tls';
import * as cloudflare from '@pulumi/cloudflare';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
import * as ecs from 'aws-cdk-lib/aws-ecs';
import * as elbv2 from 'aws-cdk-lib/aws-elasticloadbalancingv2';
import { Platform } from 'aws-cdk-lib/aws-ecr-assets';

const accountId = pulumi.secret(process.env['CLOUDFLARE_ACCOUNT_ID']!);
class CloudFlareStack extends pulumicdk.Stack {
constructor(app: pulumicdk.App, id: string) {
super(app, id);

// Create VPC and Fargate Cluster
// NOTE: Limit AZs to avoid reaching resource quotas
const vpc = new ec2.Vpc(this, 'MyVpc', { maxAzs: 2 });
const cluster = new ecs.Cluster(this, 'fargate-service-autoscaling', { vpc });

const taskDef = new ecs.TaskDefinition(this, 'taskdef', {
compatibility: ecs.Compatibility.FARGATE,
cpu: '256',
memoryMiB: '512',
});

taskDef.addContainer('app', {
portMappings: [
{
containerPort: 80,
},
],
image: ecs.ContainerImage.fromAsset(path.join(__dirname, './'), {
file: 'app/Dockerfile',
exclude: ['cdk.out', 'node_modules'],
// assetName is now required and is used in the name of the ecr repository that is created
assetName: 'cdk-cloudflare-example',
platform: Platform.LINUX_AMD64,
}),
});

const service = new ecs.FargateService(this, 'service', {
cluster,
taskDefinition: taskDef,
});

const alb = new elbv2.ApplicationLoadBalancer(this, 'alb', {
vpc,
internetFacing: true,
});

const zone = cloudflare.getZoneOutput({
accountId,
name: 'pulumi-cloudflare-demo.com',
});

// create a Certificate in CloudFlare
const privateKey = new tls.PrivateKey('key', { algorithm: 'RSA' });
const certRequest = new tls.CertRequest('request', {
privateKeyPem: privateKey.privateKeyPem,
});
const exampleOriginCaCertificate = new cloudflare.OriginCaCertificate('example', {
csr: certRequest.certRequestPem,
hostnames: [pulumi.interpolate`*.${zone.name}`],
requestType: 'origin-rsa',
requestedValidity: 7,
});

// Import the certificate in ACM
const cert = new aws.acm.Certificate('import', {
privateKey: privateKey.privateKeyPem,
certificateBody: exampleOriginCaCertificate.certificate,
});

// Create a L2 reference from the cert arn
const acmCert = acm.Certificate.fromCertificateArn(this, 'cert', pulumicdk.asString(cert.arn));

const listener = alb.addListener('https', {
open: true,
protocol: elbv2.ApplicationProtocol.HTTPS,
certificates: [acmCert],
});

listener.addTargets('service', {
targets: [service],
port: 80,
protocol: elbv2.ApplicationProtocol.HTTP,
});

new cloudflare.Record('alb', {
name: 'cdk-alb',
type: 'CNAME',
zoneId: zone.zoneId,
content: this.asOutput(alb.loadBalancerDnsName),
proxied: true,
});
}
}

class MyApp extends pulumicdk.App {
constructor() {
super('app', (scope: pulumicdk.App) => {
new CloudFlareStack(scope, 'cloudflare');
});
}
}

new MyApp();
export const dns = 'https://cdk-alb.pulumi-cloudflare-demo.com';
20 changes: 20 additions & 0 deletions examples/cloudflare-example/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "pulumi-aws-cdk",
"devDependencies": {
"@types/node": "^10.0.0"
},
"dependencies": {
"@pulumi/aws": "^6.0.0",
"@pulumi/aws-native": "^1.9.0",
"@pulumi/cdk": "^0.5.0",
"@pulumi/cloudflare": "^5.43.1",
"@pulumi/docker-build": "^0.0.7",
"@pulumi/pulumi": "^3.0.0",
"@pulumi/tls": "^5.0.9",
"@types/express": "^5.0.0",
"aws-cdk-lib": "2.156.0",
"constructs": "10.3.0",
"esbuild": "^0.24.0",
"express": "^4.21.1"
}
}
18 changes: 18 additions & 0 deletions examples/cloudflare-example/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"compilerOptions": {
"strict": true,
"outDir": "bin",
"target": "es2016",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"experimentalDecorators": true,
"pretty": true,
"noFallthroughCasesInSwitch": true,
"noImplicitReturns": true,
"forceConsistentCasingInFileNames": true
},
"files": [
"index.ts"
]
}