Skip to content

Commit

Permalink
initial changes
Browse files Browse the repository at this point in the history
  • Loading branch information
estohlmann committed Sep 27, 2024
1 parent 100030e commit 6408712
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 17 deletions.
4 changes: 2 additions & 2 deletions lib/api-base/ecsCluster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,14 @@ export class ECSCluster extends Construct {
const { config, vpc, securityGroup, ecsConfig } = props;

// Create ECS cluster
const cluster = new Cluster(this, createCdkId([ecsConfig.identifier, 'Cl']), {
const cluster = new Cluster(this, createCdkId(['Cl']), {
clusterName: createCdkId([config.deploymentName, ecsConfig.identifier], 32, 2),
vpc: vpc,
containerInsights: !config.region.includes('iso'),
});

// Create auto scaling group
const autoScalingGroup = cluster.addCapacity(createCdkId([ecsConfig.identifier, 'ASG']), {
const autoScalingGroup = cluster.addCapacity(createCdkId(['ASG']), {
instanceType: new InstanceType(ecsConfig.instanceType),
machineImage: EcsOptimizedImage.amazonLinux2(ecsConfig.amiHardwareType),
minCapacity: ecsConfig.autoScalingConfig.minCapacity,
Expand Down
11 changes: 7 additions & 4 deletions lib/chat/api/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,14 @@
import { IAuthorizer, RestApi } from 'aws-cdk-lib/aws-apigateway';
import * as dynamodb from 'aws-cdk-lib/aws-dynamodb';
import { ISecurityGroup, IVpc } from 'aws-cdk-lib/aws-ec2';
import { IRole } from 'aws-cdk-lib/aws-iam';
import { Role } from 'aws-cdk-lib/aws-iam';
import { LayerVersion } from 'aws-cdk-lib/aws-lambda';
import { StringParameter } from 'aws-cdk-lib/aws-ssm';
import { Construct } from 'constructs';

import { PythonLambdaFunction, registerAPIEndpoint } from '../../api-base/utils';
import { BaseProps } from '../../schema';
import { createLambdaRole } from '../../core/utils';

/**
* Properties for SessionApi Construct.
Expand All @@ -37,7 +38,6 @@ import { BaseProps } from '../../schema';
*/
type SessionApiProps = {
authorizer: IAuthorizer;
lambdaExecutionRole?: IRole;
restApiId: string;
rootResourceId: string;
securityGroups?: ISecurityGroup[];
Expand All @@ -51,7 +51,7 @@ export class SessionApi extends Construct {
constructor (scope: Construct, id: string, props: SessionApiProps) {
super(scope, id);

const { authorizer, config, lambdaExecutionRole, restApiId, rootResourceId, securityGroups, vpc } = props;
const { authorizer, config, restApiId, rootResourceId, securityGroups, vpc } = props;

// Get common layer based on arn from SSM due to issues with cross stack references
const commonLambdaLayer = LayerVersion.fromLayerVersionArn(
Expand Down Expand Up @@ -143,6 +143,9 @@ export class SessionApi extends Construct {
},
},
];

const lambdaRole: Role = createLambdaRole(this, config.deploymentName, 'SessionApi', sessionTable.tableArn);

apis.forEach((f) => {
const lambdaFunction = registerAPIEndpoint(
this,
Expand All @@ -152,7 +155,7 @@ export class SessionApi extends Construct {
[commonLambdaLayer],
f,
config.lambdaConfig.pythonRuntime,
lambdaExecutionRole,
lambdaRole,
vpc,
securityGroups,
);
Expand Down
47 changes: 43 additions & 4 deletions lib/core/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import * as cdk from 'aws-cdk-lib';
import * as iam from 'aws-cdk-lib/aws-iam';

import { Config } from '../schema';
import { Effect, ManagedPolicy, PolicyDocument, PolicyStatement, Role, ServicePrincipal } from 'aws-cdk-lib/aws-iam';
import { Construct } from 'constructs';

const IAM_DIR = path.join(__dirname, 'iam');

Expand All @@ -39,7 +41,7 @@ type JSONPolicyStatement = {
* @param {string} serviceName - AWS service name.
* @returns {iam.PolicyStatement[]} - Extracted IAM policy statements.
*/
const extractPolicyStatementsFromJson = (config: Config, serviceName: string): iam.PolicyStatement[] => {
const extractPolicyStatementsFromJson = (config: Config, serviceName: string, tableName: string = ''): iam.PolicyStatement[] => {
const statementData = fs.readFileSync(path.join(IAM_DIR, `${serviceName.toLowerCase()}.json`), 'utf8');
const statements = JSON.parse(statementData).Statement;

Expand All @@ -50,7 +52,8 @@ const extractPolicyStatementsFromJson = (config: Config, serviceName: string): i
return resource
.replace(/\${AWS::AccountId}/gi, cdk.Aws.ACCOUNT_ID)
.replace(/\${AWS::Partition}/gi, cdk.Aws.PARTITION)
.replace(/\${AWS::Region}/gi, cdk.Aws.REGION);
.replace(/\${AWS::Region}/gi, cdk.Aws.REGION)
.replace(/\${LAMBDA::Table}/gi, tableName);
});
}
});
Expand All @@ -62,10 +65,46 @@ const extractPolicyStatementsFromJson = (config: Config, serviceName: string): i
* Wrapper to get IAM policy statements.
* @param {Config} config - The application configuration.
* @param {string} serviceName - AWS service name.
* @param {string} tableName - DynamoDB table name.
* @returns {iam.PolicyStatement[]} - Extracted IAM policy statements.
*/
export const getIamPolicyStatements = (config: Config, serviceName: string): iam.PolicyStatement[] => {
return extractPolicyStatementsFromJson(config, serviceName);
export const getIamPolicyStatements = (config: Config, serviceName: string, tableName: string = ''): iam.PolicyStatement[] => {
return extractPolicyStatementsFromJson(config, serviceName, tableName);
};

export const createLambdaRole = (construct: Construct, deploymentName: string, lambdaName: string, tableArn: string = '') => {
return new Role(construct, `Lisa${lambdaName}LambdaExecutionRole`, {
assumedBy: new ServicePrincipal('lambda.amazonaws.com'),
roleName: createCdkId([deploymentName, `Lisa${lambdaName}LambdaExecutionRole`]),
description: `Role used by LISA ${lambdaName} lambdas to access AWS resources`,
managedPolicies: [
ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSLambdaVPCAccessExecutionRole'),
],
inlinePolicies: {
lambdaPermissions: new PolicyDocument({
statements: [...(tableArn ? [
new PolicyStatement({
effect: Effect.ALLOW,
actions: [
'dynamodb:BatchGetItem',
'dynamodb:ConditionCheckItem',
'dynamodb:DescribeTable',
'dynamodb:GetItem',
'dynamodb:GetRecords',
'dynamodb:GetShardIterator',
'dynamodb:Query',
'dynamodb:Scan'
],
resources: [
tableArn,
`${tableArn}/*`,
]
})
] : []),
]
}),
}
});
};

/**
Expand Down
2 changes: 2 additions & 0 deletions lib/models/docker-image-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export class DockerImageBuilder extends Construct {
const stackName = Stack.of(scope).stackName;

const ec2InstanceProfileRole = new Role(this, createCdkId([stackName, 'docker-image-builder-ec2-role']), {
roleName: createCdkId([stackName, 'docker-image-builder-ec2-role']),
assumedBy: new ServicePrincipal('ec2.amazonaws.com')
});

Expand Down Expand Up @@ -77,6 +78,7 @@ export class DockerImageBuilder extends Construct {
ec2InstanceProfileRole.attachInlinePolicy(ec2InstanceProfilePolicy);

const role = new Role(this, createCdkId([stackName, 'docker_image_builder_role']), {
roleName: createCdkId([stackName, 'docker_image_builder_role']),
assumedBy: new ServicePrincipal('lambda.amazonaws.com')
});

Expand Down
10 changes: 5 additions & 5 deletions lib/models/model-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import { ISecurityGroup } from 'aws-cdk-lib/aws-ec2';
import { Repository } from 'aws-cdk-lib/aws-ecr';
import {
Effect,
IRole,
ManagedPolicy,
Policy,
PolicyDocument,
Expand All @@ -44,6 +43,7 @@ import { AttributeType, BillingMode, Table, TableEncryption } from 'aws-cdk-lib/
import { CreateModelStateMachine } from './state-machine/create-model';
import { UpdateModelStateMachine } from './state-machine/update-model';
import { Secret } from 'aws-cdk-lib/aws-secretsmanager';
import { createLambdaRole } from '../core/utils';

/**
* Properties for ModelsApi Construct.
Expand All @@ -57,7 +57,6 @@ import { Secret } from 'aws-cdk-lib/aws-secretsmanager';
*/
type ModelsApiProps = BaseProps & {
authorizer: IAuthorizer;
lambdaExecutionRole?: IRole;
lisaServeEndpointUrlPs: StringParameter;
restApiId: string;
rootResourceId: string;
Expand All @@ -72,7 +71,7 @@ export class ModelsApi extends Construct {
constructor (scope: Construct, id: string, props: ModelsApiProps) {
super(scope, id);

const { authorizer, config, lambdaExecutionRole, lisaServeEndpointUrlPs, restApiId, rootResourceId, securityGroups, vpc } = props;
const { authorizer, config, lisaServeEndpointUrlPs, restApiId, rootResourceId, securityGroups, vpc } = props;

// Get common layer based on arn from SSM due to issues with cross stack references
const commonLambdaLayer = LayerVersion.fromLayerVersionArn(
Expand Down Expand Up @@ -252,6 +251,7 @@ export class ModelsApi extends Construct {
MODEL_TABLE_NAME: modelTable.tableName,
};

const lambdaRole: Role = createLambdaRole(this, config.deploymentName, 'ModelApi', modelTable.tableArn);
// create proxy handler
const lambdaFunction = registerAPIEndpoint(
this,
Expand All @@ -268,7 +268,7 @@ export class ModelsApi extends Construct {
environment
},
config.lambdaConfig.pythonRuntime,
lambdaExecutionRole,
lambdaRole,
vpc.vpc,
securityGroups,
);
Expand Down Expand Up @@ -340,7 +340,7 @@ export class ModelsApi extends Construct {
[commonLambdaLayer],
f,
config.lambdaConfig.pythonRuntime,
lambdaExecutionRole,
lambdaRole,
vpc.vpc,
securityGroups,
);
Expand Down
4 changes: 2 additions & 2 deletions lib/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -893,8 +893,8 @@ const RawConfigSchema = z
permissionsBoundaryAspect: z
.object({
permissionsBoundaryPolicyName: z.string(),
rolePrefix: z.string().optional(),
policyPrefix: z.string().optional(),
rolePrefix: z.string().max(20).optional(),
policyPrefix: z.string().max(20).optional(),
instanceProfilePrefix: z.string().optional(),
})
.optional(),
Expand Down

0 comments on commit 6408712

Please sign in to comment.