Files
mold_cost_online_tool/infra/bin/apiStack.ts
T
2025-06-25 14:51:37 +02:00

108 lines
4.0 KiB
TypeScript

import {
Stack,
StackProps,
aws_apigateway as apigateway,
aws_lambda,
aws_ec2,
Duration,
} from 'aws-cdk-lib';
import * as aws_lambda_python_alpha from '@aws-cdk/aws-lambda-python-alpha';
import { Construct } from 'constructs';
import { NodejsFunction } from 'aws-cdk-lib/aws-lambda-nodejs';
import { join } from 'path';
import { Runtime } from 'aws-cdk-lib/aws-lambda';
import { BuildConfig } from '../utils/build-config';
import { Period } from 'aws-cdk-lib/aws-apigateway';
import { RetentionDays } from 'aws-cdk-lib/aws-logs';
import { VpcEndpoint, VpcEndpointService } from 'aws-cdk-lib/aws-ec2';
import { PolicyStatement, PolicyDocument, Effect, AnyPrincipal } from 'aws-cdk-lib/aws-iam';
export class MccAPIInfraStack extends Stack {
public readonly api: apigateway.RestApi;
constructor(
scope: Construct,
id: string,
buildConfig: BuildConfig,
props: StackProps,
) {
super(scope, id, props);
const stackName = `${buildConfig.Environment}${buildConfig.ApplicationShortName}`;
const vpc = aws_ec2.Vpc.fromLookup(this, `${stackName}Vpc`, {
vpcId: buildConfig.Parameters.VPC,
});
const executeApiVpcEndpointSecurityGroup = new aws_ec2.SecurityGroup(this, `${stackName}ExecuteApiVPCEsg`, {
vpc,
description: 'Security group for API Gateway VPC Endpoint',
allowAllOutbound: true,
});
executeApiVpcEndpointSecurityGroup.addIngressRule(
aws_ec2.Peer.ipv4('10.0.0.0/8'),
aws_ec2.Port.tcp(443),
'Allow inbound HTTPS traffic from 10.0.0.0/8'
);
const executeApiVpcEndpoint = new aws_ec2.InterfaceVpcEndpoint(this, `${stackName}ExecuteApiVPCE`, {
vpc,
service: aws_ec2.InterfaceVpcEndpointAwsService.APIGATEWAY,
privateDnsEnabled: true,
subnets: { subnetType: aws_ec2.SubnetType.PRIVATE_WITH_EGRESS },
securityGroups: [executeApiVpcEndpointSecurityGroup]
});
const lambdaFunction = new aws_lambda_python_alpha.PythonFunction(this, `${stackName}MCCApp`, {
runtime: Runtime.PYTHON_3_11,
handler: 'lambda_handler',
timeout: Duration.seconds(30),
entry: join(__dirname, '../../src'),
index: 'run.py',
memorySize: 256,
vpc,
logRetention: RetentionDays.ONE_WEEK,
environment: {
POSTGRES_USER: process.env.POSTGRES_USER!,
POSTGRES_PASSWORD: process.env.POSTGRES_PASSWORD!,
POSTGRES_DB: 'mccdb',
FLASK_APP: process.env.FLASK_APP!,
FLASK_ENV: process.env.FLASK_ENV!,
DATABASE_URL: process.env.DATABASE_URL!,
HOST_ENV: process.env.HOST_ENV!,
},
});
const api = new apigateway.LambdaRestApi(this, `${stackName}MCCAPI`, {
handler: lambdaFunction,
proxy: true,
deployOptions: {
stageName: buildConfig.Environment,
},
restApiName: `${buildConfig.ApplicationName} API`,
description: `API for ${buildConfig.ApplicationName} in ${buildConfig.Environment}`,
endpointConfiguration: {
types: [apigateway.EndpointType.PRIVATE],
vpcEndpoints: [executeApiVpcEndpoint],
},
policy: new PolicyDocument({
statements: [
new PolicyStatement({
effect: Effect.ALLOW,
principals: [new AnyPrincipal()],
actions: ['execute-api:Invoke'],
resources: ['execute-api:/*'],
// Optionally, restrict by source VPC or VPC endpoint
conditions: {
StringEquals: { 'aws:SourceVpce': executeApiVpcEndpoint.vpcEndpointId }
}
}),
],
}),
});
this.api = api;
}
}