Skip to content

Instantly share code, notes, and snippets.

@nkhine
Created November 14, 2024 20:04
Show Gist options
  • Save nkhine/2a8cc565b42b299e27652ba68e22cb13 to your computer and use it in GitHub Desktop.
Save nkhine/2a8cc565b42b299e27652ba68e22cb13 to your computer and use it in GitHub Desktop.
import { StackProps, CfnParameter } from "aws-cdk-lib";
import { IVpc } from "aws-cdk-lib/aws-ec2";
import {
CfnApplication,
CfnConfigurationTemplate,
} from "aws-cdk-lib/aws-elasticbeanstalk";
import {
CfnInstanceProfile,
ManagedPolicy,
Role,
ServicePrincipal,
} from "aws-cdk-lib/aws-iam";
import { Construct } from "constructs";
import { DeployApplicationStack } from "./environment/deploy/stack";
import { PermissionsStack } from "./environment/permissions/stack";
import TaggingStack from "../../tagging";
interface ApplicationStackProps extends StackProps {
certificateArn: string;
vpc: IVpc;
privateSubnetIds: string[];
loadBalancerDnsName: string;
buildAssetsBucketArn: string;
}
export class ApplicationStack extends TaggingStack {
constructor(scope: Construct, id: string, props: ApplicationStackProps) {
super(scope, id, props);
// Create an IAM role with necessary policies for the EC2 instances in the Elastic Beanstalk environment
const ebInstanceRole = new Role(this, "EBInstanceRole", {
assumedBy: new ServicePrincipal("ec2.amazonaws.com"), // EC2 service will assume this role
managedPolicies: [
ManagedPolicy.fromAwsManagedPolicyName("AWSElasticBeanstalkWebTier"), // Grant basic Elastic Beanstalk permissions
ManagedPolicy.fromAwsManagedPolicyName("AWSElasticBeanstalkWorkerTier"), // Add worker permissions if needed
ManagedPolicy.fromAwsManagedPolicyName("AmazonS3FullAccess"), // Add S3 full access, adjust based on requirements
ManagedPolicy.fromAwsManagedPolicyName("CloudWatchFullAccess"), // Add CloudWatch full access for logging
],
});
// Create the instance profile
const ebInstanceProfile = new CfnInstanceProfile(
this,
"EBInstanceProfile",
{
roles: [ebInstanceRole.roleName],
},
);
// Define a CloudFormation parameter for the instance type
const instanceTypeParam = new CfnParameter(this, "InstanceType", {
type: "String",
default: "t3.medium",
description: "EC2 instance type for the Elastic Beanstalk environment",
});
// Create the Elastic Beanstalk Application
const elasticBeanstalkApp = new CfnApplication(
this,
"ElasticBeanstalkApplication",
{
applicationName: "Sample",
},
);
// Explicitly use the application name string
const applicationName = elasticBeanstalkApp.applicationName as string;
// Create the Elastic Beanstalk Configuration Template
const savedConfig = new CfnConfigurationTemplate(
this,
"ElasticBeanstalkConfigTemplate",
{
applicationName: applicationName, // Link the template to the application
// https://docs.aws.amazon.com/elasticbeanstalk/latest/platforms/platform-history-dotnet.html
solutionStackName: "64bit Windows Server 2016 v2.15.6 running IIS 10.0", // Specify the Solution Stack
optionSettings: [
{
namespace: "aws:autoscaling:launchconfiguration",
optionName: "IamInstanceProfile",
value: ebInstanceProfile.ref, // Associate the instance profile
},
{
namespace: "aws:autoscaling:launchconfiguration",
optionName: "InstanceType",
value: instanceTypeParam.valueAsString, // Use the parameter value here
},
{
namespace: "aws:elasticbeanstalk:environment",
optionName: "EnvironmentType",
value: "LoadBalanced",
},
{
namespace: "aws:elasticbeanstalk:environment",
optionName: "ELBEndpointDNSName",
value: props.loadBalancerDnsName, // Use custom ALB DNS
},
{
namespace: "aws:ec2:vpc",
optionName: "VPCId",
value: props.vpc.vpcId, // Use the VPC ID
},
{
namespace: "aws:ec2:vpc",
optionName: "Subnets",
value: props.privateSubnetIds.join(","), // Use the Subnet IDs
},
{
namespace: "aws:cloudformation:template:parameter",
optionName: "EnvironmentVariables",
value:
// FIXME: Make it account specific and enable it from the config
"INSTALL_CROWDSTRIKE=false,CROWDSTRIKE_INSTALLER_BUCKET=heritage-crowdstrike-sensors",
},
// {
// namespace: "aws:cloudformation:template:parameter",
// optionName: "AppSource",
// value:
// "https://elasticbeanstalk-samples-eu-west-1.s3-eu-west-1.amazonaws.com/FirstSample-v3.zip",
// },
// {
// namespace: "aws:elasticbeanstalk:application",
// optionName: "Application Healthcheck URL",
// value: "/health.html", // FIXME
// },
],
},
);
// Ensure that the configuration template depends on the application being created first
savedConfig.node.addDependency(elasticBeanstalkApp);
const permissionsStack = new PermissionsStack(this, "PermissionsStack", {
buildAssetsBucketArn: props.buildAssetsBucketArn,
});
new DeployApplicationStack(this, "DeployApplicationStack", {
vpc: props.vpc,
privateSubnetIds: props.privateSubnetIds,
buildAssetsBucketArn: props.buildAssetsBucketArn,
heritageAccessRole: permissionsStack.heritageAccessRole,
elasticBeanstalkApp: elasticBeanstalkApp,
savedConfig: savedConfig,
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment