plain-eye-2667
02/25/2024, 9:34 AMjolly-manchester-8306
02/25/2024, 9:26 PMplain-eye-2667
02/26/2024, 6:05 AMimport * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
// Create an S3 bucket
const bucket = new aws.s3.Bucket("myBucket");
// IAM role for the Lambda function
const iamRole = new aws.iam.Role("lambdaEdgeRole", {
assumeRolePolicy: JSON.stringify({
Version: "2012-10-17",
Statement: [{
Action: "sts:AssumeRole",
Principal: {"Service": "<http://lambda.amazonaws.com|lambda.amazonaws.com>"},
Effect: "Allow",
Sid: "",
}, {
Action: "sts:AssumeRole",
Principal: {"Service": "<http://edgelambda.amazonaws.com|edgelambda.amazonaws.com>"},
Effect: "Allow",
Sid: "",
}],
}),
});
// Attach the AWSLambdaBasicExecutionRole policy
new aws.iam.RolePolicyAttachment("lambdaExecutionPolicy", {
role: iamRole,
policyArn: "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole",
});
// Lambda@Edge function
const lambdaCode = bucket.id.apply(bucketId => `
const AWS = require("aws-sdk");
exports.handler = (event, context, callback) => {
const s3 = new AWS.S3();
const request = event.Records[0].cf.request;
const uri = request.uri;
const key = uri.substring(1);
const bucketName = "${bucketId}";
s3.headObject({
Bucket: bucketName,
Key: key,
}, (err, data) => {
if (err) {
request.uri = '/index.html';
}
callback(null, request);
});
};
`);
const lambdaAtEdge = new aws.lambda.Function("myLambdaAtEdge", {
code: new pulumi.asset.AssetArchive({
"index.js": new pulumi.asset.StringAsset(lambdaCode),
}),
handler: "index.handler",
role: iamRole.arn,
runtime: aws.lambda.Runtime.NodeJS12dX, // Make sure to use a current supported runtime
functionName: "myLambdaAtEdgeFunction",
publish: true,
});
// Associate the Lambda function with CloudFront
const cloudFrontDistribution = new aws.cloudfront.Distribution("myDistribution", {
origins: [{
domainName: bucket.bucketRegionalDomainName,
originId: bucket.arn,
}],
enabled: true,
isIpv6Enabled: true,
defaultRootObject: "index.html",
defaultCacheBehavior: {
targetOriginId: bucket.arn,
viewerProtocolPolicy: "redirect-to-https",
lambdaFunctionAssociations: [{
eventType: "origin-request",
lambdaArn: lambdaAtEdge.qualifiedArn,
}],
},
restrictions: {
geoRestriction: {
restrictionType: "none",
},
},
viewerCertificate: {
cloudfrontDefaultCertificate: true,
},
});
// Outputs
export const bucketName = bucket.id;
export const distributionId = cloudFrontDistribution.id;
If you need more assistance you can take help from here: https://www.pulumi.com/ai
I haven't tested this but let me explain to you:
1. You should run it only in pulumi
not as simple TS code
2. CloudFront is needed before you can have a lambda@edge that's why u see a CloudFront distribution
3. I am a bit doubtful in the code provided by ai in context of cache behavior but I hope it worksjolly-manchester-8306
02/27/2024, 2:06 AMplain-eye-2667
02/27/2024, 4:55 AMpulumi input
sorry my bad I didn't tested the code. I still can't test, the reason is I have mostly company workspaces/aws accounts so can't give it a try
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
// Create an S3 bucket
const bucket = new aws.s3.Bucket("myBucket");
// IAM role for the Lambda function
const iamRole = new aws.iam.Role("lambdaEdgeRole", {
assumeRolePolicy: JSON.stringify({
Version: "2012-10-17",
Statement: [{
Action: "sts:AssumeRole",
Principal: {"Service": "lambda.amazonaws.com"},
Effect: "Allow",
Sid: "",
}, {
Action: "sts:AssumeRole",
Principal: {"Service": "edgelambda.amazonaws.com"},
Effect: "Allow",
Sid: "",
}],
}),
});
// Attach the AWSLambdaBasicExecutionRole policy
new aws.iam.RolePolicyAttachment("lambdaExecutionPolicy", {
role: iamRole,
policyArn: "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole",
});
bucket.id.apply(bucketId => {
const lambdaCode = `
const AWS = require("aws-sdk");
exports.handler = (event, context, callback) => {
const s3 = new AWS.S3();
const request = event.Records[0].cf.request;
const uri = request.uri;
const key = uri.substring(1);
const bucketName = "${bucketId}";
s3.headObject({
Bucket: bucketName,
Key: key,
}, (err, data) => {
if (err) {
request.uri = '/index.html';
}
callback(null, request);
});
};
`;
const lambdaAtEdge = new aws.lambda.Function("myLambdaAtEdge", {
code: new pulumi.asset.AssetArchive({
"index.js": new pulumi.asset.StringAsset(lambdaCode),
}),
handler: "index.handler",
role: iamRole.arn,
runtime: aws.lambda.Runtime.NodeJS12dX, // Make sure to use a current supported runtime
publish: true,
});
// Associate the Lambda function with CloudFront
const cloudFrontDistribution = new aws.cloudfront.Distribution("myDistribution", {
origins: [{
domainName: bucket.bucketRegionalDomainName,
originId: bucket.arn,
}],
enabled: true,
isIpv6Enabled: true,
defaultRootObject: "index.html",
defaultCacheBehavior: {
targetOriginId: bucket.arn,
viewerProtocolPolicy: "redirect-to-https",
lambdaFunctionAssociations: [{
eventType: "origin-request",
lambdaArn: lambdaAtEdge.qualifiedArn,
}],
allowedMethods: ["GET", "HEAD"],
cachedMethods: ["GET", "HEAD"],
},
restrictions: {
geoRestriction: {
restrictionType: "none",
},
},
viewerCertificate: {
cloudfrontDefaultCertificate: true,
},
});
});
// Outputs
export const bucketName = bucket.id;
plain-eye-2667
02/27/2024, 5:01 AMjolly-manchester-8306
02/27/2024, 4:23 PMbucket = aws.s3.Bucket("myS3Bucket1")
def create_lambda(bucket_id):
lambda_code = f'bucketName = "{bucket_id}";'
lambda_at_edge = aws.lambda_.Function("myLambdaAtEdge2",
code=pulumi.AssetArchive({
"index.js": pulumi.StringAsset(lambda_code),
}),
handler="index.handler",
role="arn:.........",
runtime="python3.12",
publish=True,
)
return lambda_at_edge.arn
my_lambda = bucket.id.apply(create_lambda)
pulumi.export("bucket_name", bucket.id)
pulumi.export("lambda_arn", my_lambda)