2026-07-27 19:26:07 -03:00
|
|
|
import * as cdk from 'aws-cdk-lib';
|
|
|
|
|
import * as iam from 'aws-cdk-lib/aws-iam';
|
|
|
|
|
import { Construct } from 'constructs';
|
|
|
|
|
|
|
|
|
|
const ACCOUNT_ID = '396287094661';
|
|
|
|
|
const REGION = 'us-east-1';
|
|
|
|
|
const APPLICATION_NAME = 'shoc-backend';
|
|
|
|
|
const ENVIRONMENT_NAME = 'shoc-backend-dev';
|
|
|
|
|
const REPO = 'Sea-Haven-Industries/shoc-backend';
|
|
|
|
|
const BUCKET_NAME = `elasticbeanstalk-${REGION}-${ACCOUNT_ID}`;
|
|
|
|
|
|
|
|
|
|
export class DeployDevStack extends cdk.Stack {
|
|
|
|
|
constructor(scope: Construct, id: string, props: cdk.StackProps = {}) {
|
|
|
|
|
super(scope, id, props);
|
|
|
|
|
|
|
|
|
|
const applicationArn = `arn:aws:elasticbeanstalk:${REGION}:${ACCOUNT_ID}:application/${APPLICATION_NAME}`;
|
|
|
|
|
const environmentArn = `arn:aws:elasticbeanstalk:${REGION}:${ACCOUNT_ID}:environment/${APPLICATION_NAME}/${ENVIRONMENT_NAME}`;
|
|
|
|
|
const bucketArn = `arn:aws:s3:::${BUCKET_NAME}`;
|
|
|
|
|
const oidcProviderArn = `arn:aws:iam::${ACCOUNT_ID}:oidc-provider/token.actions.githubusercontent.com`;
|
|
|
|
|
|
|
|
|
|
const deployRole = new iam.Role(this, 'GithubDeployRole', {
|
|
|
|
|
roleName: 'githubdeploy-shoc-backend-dev',
|
|
|
|
|
description:
|
|
|
|
|
'Least-privilege GitHub OIDC deploy role for shoc-backend dev. CDK-owned; application/environment/S3 are owned by Elastic Beanstalk.',
|
|
|
|
|
assumedBy: new iam.FederatedPrincipal(
|
|
|
|
|
oidcProviderArn,
|
|
|
|
|
{
|
|
|
|
|
StringEquals: {
|
|
|
|
|
'token.actions.githubusercontent.com:aud': 'sts.amazonaws.com',
|
|
|
|
|
'token.actions.githubusercontent.com:sub': `repo:${REPO}:environment:dev`,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
'sts:AssumeRoleWithWebIdentity',
|
|
|
|
|
),
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
deployRole.applyRemovalPolicy(cdk.RemovalPolicy.RETAIN);
|
|
|
|
|
const cfnRole = deployRole.node.defaultChild as iam.CfnRole;
|
|
|
|
|
cfnRole.cfnOptions.deletionPolicy = cdk.CfnDeletionPolicy.RETAIN;
|
|
|
|
|
cfnRole.cfnOptions.updateReplacePolicy = cdk.CfnDeletionPolicy.RETAIN;
|
|
|
|
|
|
|
|
|
|
deployRole.addToPolicy(
|
|
|
|
|
new iam.PolicyStatement({
|
|
|
|
|
effect: iam.Effect.ALLOW,
|
|
|
|
|
actions: [
|
|
|
|
|
'elasticbeanstalk:DescribeEnvironments',
|
|
|
|
|
'elasticbeanstalk:DescribeApplicationVersions',
|
|
|
|
|
'elasticbeanstalk:DescribeEvents',
|
|
|
|
|
],
|
|
|
|
|
resources: ['*'],
|
|
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
deployRole.addToPolicy(
|
|
|
|
|
new iam.PolicyStatement({
|
|
|
|
|
effect: iam.Effect.ALLOW,
|
|
|
|
|
actions: ['elasticbeanstalk:CreateApplicationVersion'],
|
2026-07-28 10:38:38 -03:00
|
|
|
resources: [
|
|
|
|
|
applicationArn,
|
|
|
|
|
`arn:aws:elasticbeanstalk:${REGION}:${ACCOUNT_ID}:applicationversion/${APPLICATION_NAME}/*`,
|
|
|
|
|
],
|
2026-07-27 19:26:07 -03:00
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
deployRole.addToPolicy(
|
|
|
|
|
new iam.PolicyStatement({
|
|
|
|
|
effect: iam.Effect.ALLOW,
|
|
|
|
|
actions: ['elasticbeanstalk:UpdateEnvironment'],
|
|
|
|
|
resources: [environmentArn],
|
|
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
deployRole.addToPolicy(
|
|
|
|
|
new iam.PolicyStatement({
|
|
|
|
|
effect: iam.Effect.ALLOW,
|
2026-07-28 12:51:20 -03:00
|
|
|
actions: ['s3:ListBucket', 's3:CreateBucket'],
|
2026-07-27 19:26:07 -03:00
|
|
|
resources: [bucketArn],
|
|
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
deployRole.addToPolicy(
|
|
|
|
|
new iam.PolicyStatement({
|
|
|
|
|
effect: iam.Effect.ALLOW,
|
2026-07-28 11:12:39 -03:00
|
|
|
actions: ['s3:GetObject', 's3:GetObjectVersion', 's3:PutObject'],
|
2026-07-27 19:26:07 -03:00
|
|
|
resources: [`${bucketArn}/${APPLICATION_NAME}/*`],
|
|
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
new cdk.CfnOutput(this, 'GithubDeployRoleArn', {
|
|
|
|
|
value: deployRole.roleArn,
|
|
|
|
|
description: 'ARN of the GitHub OIDC deploy role for shoc-backend dev.',
|
|
|
|
|
exportName: 'shoc-backend-deploy-dev-role-arn',
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|