-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
added a java example for creating an ApplicationLoadBalancer with an …
…AutoScalingGroup (#1105) * added a java example for creating an ApplicationLoadBalancer with an AutoScalingGroup * Update pom.xml Change to supported release version --------- Co-authored-by: Michael Kaiser <[email protected]> Co-authored-by: Michael Kaiser <[email protected]>
- Loading branch information
1 parent
1e14ba1
commit 8a39ebd
Showing
7 changed files
with
435 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
.classpath.txt | ||
target | ||
.classpath | ||
.project | ||
.idea | ||
.settings | ||
.vscode | ||
*.iml | ||
|
||
# CDK asset staging directory | ||
.cdk.staging | ||
cdk.out | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
# Application Load Balancer | ||
|
||
|
||
<!--BEGIN STABILITY BANNER--> | ||
|
||
--- | ||
|
||
![Stability: Stable](https://img.shields.io/badge/stability-Stable-success.svg?style=for-the-badge) | ||
|
||
> **This is a stable example. It should successfully build out of the box** | ||
> | ||
> This example is built on Construct Libraries marked "Stable" and does not have any infrastructure prerequisites to build. | ||
--- | ||
<!--END STABILITY BANNER--> | ||
|
||
This example creates an AutoScalingGroup (containing 2 AWS Graviton2 Micro-T4G EC2 machines running the Amazon Linux 2023 AMI), and an ApplicationLoadBalancer inside a shared VPC. | ||
It hooks up an open listener from the Load Balancer to the Scaling Group to indicate how many targets to balance between. | ||
|
||
For more info on using Auto Scaling with Load Balancing see the AWS guide [here](https://docs.aws.amazon.com/autoscaling/ec2/userguide/autoscaling-load-balancer.html). | ||
|
||
## Build | ||
|
||
To build this example, you need to be in this example's root directory. | ||
Then, run the following: | ||
|
||
```bash | ||
npm install -g aws-cdk | ||
npm install | ||
cdk synth | ||
``` | ||
|
||
This will install the necessary CDK, then this example's dependencies, and then build the CloudFormation template. | ||
The resulting CloudFormation template will be in the `cdk.out` directory. | ||
|
||
## Deploy | ||
|
||
Run `cdk deploy`. | ||
This will deploy / redeploy the stack to AWS. | ||
After a successful deployment, the URL of the ALB created will be available in the output of the terminal console. | ||
At this point, the ALB URL can be used for testing. | ||
Copy the ALB URL and paste it in the address bar of a browser. | ||
The ALB will route the received requests between the 2 EC2 instances created initially by the ASG. | ||
You can observe that the requests made reach different EC2 instances. | ||
This can be observed based on the content of the web page displayed in the browser (the hello message on the web page contains the host which is different for each EC2 instance). | ||
|
||
## Useful commands | ||
|
||
* `mvn package` compile and run tests | ||
* `cdk ls` list all stacks in the app | ||
* `cdk synth` emits the synthesized CloudFormation template | ||
* `cdk deploy` deploy this stack to your default AWS account/region | ||
* `cdk diff` compare deployed stack with current state | ||
* `cdk docs` open CDK documentation |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
{ | ||
"app": "mvn -e -q compile exec:java", | ||
"watch": { | ||
"include": [ | ||
"**" | ||
], | ||
"exclude": [ | ||
"README.md", | ||
"cdk*.json", | ||
"target", | ||
"pom.xml", | ||
"src/test" | ||
] | ||
}, | ||
"context": { | ||
"@aws-cdk/aws-lambda:recognizeLayerVersion": true, | ||
"@aws-cdk/core:checkSecretUsage": true, | ||
"@aws-cdk/core:target-partitions": [ | ||
"aws", | ||
"aws-cn" | ||
], | ||
"@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true, | ||
"@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true, | ||
"@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true, | ||
"@aws-cdk/aws-iam:minimizePolicies": true, | ||
"@aws-cdk/core:validateSnapshotRemovalPolicy": true, | ||
"@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true, | ||
"@aws-cdk/aws-s3:createDefaultLoggingPolicy": true, | ||
"@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true, | ||
"@aws-cdk/aws-apigateway:disableCloudWatchRole": true, | ||
"@aws-cdk/core:enablePartitionLiterals": true, | ||
"@aws-cdk/aws-events:eventsTargetQueueSameAccount": true, | ||
"@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": true, | ||
"@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName": true, | ||
"@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true, | ||
"@aws-cdk/aws-route53-patters:useCertificate": true, | ||
"@aws-cdk/customresources:installLatestAwsSdkDefault": false, | ||
"@aws-cdk/aws-rds:databaseProxyUniqueResourceName": true, | ||
"@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup": true, | ||
"@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId": true, | ||
"@aws-cdk/aws-ec2:launchTemplateDefaultUserData": true, | ||
"@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments": true, | ||
"@aws-cdk/aws-redshift:columnId": true, | ||
"@aws-cdk/aws-stepfunctions-tasks:enableEmrServicePolicyV2": true, | ||
"@aws-cdk/aws-ec2:restrictDefaultSecurityGroup": true, | ||
"@aws-cdk/aws-apigateway:requestValidatorUniqueId": true, | ||
"@aws-cdk/aws-kms:aliasNameRef": true, | ||
"@aws-cdk/aws-autoscaling:generateLaunchTemplateInsteadOfLaunchConfig": true, | ||
"@aws-cdk/core:includePrefixInUniqueNameGeneration": true, | ||
"@aws-cdk/aws-efs:denyAnonymousAccess": true, | ||
"@aws-cdk/aws-opensearchservice:enableOpensearchMultiAzWithStandby": true, | ||
"@aws-cdk/aws-lambda-nodejs:useLatestRuntimeVersion": true, | ||
"@aws-cdk/aws-efs:mountTargetOrderInsensitiveLogicalId": true, | ||
"@aws-cdk/aws-rds:auroraClusterChangeScopeOfInstanceParameterGroupWithEachParameters": true, | ||
"@aws-cdk/aws-appsync:useArnForSourceApiAssociationIdentifier": true, | ||
"@aws-cdk/aws-rds:preventRenderingDeprecatedCredentials": true, | ||
"@aws-cdk/aws-codepipeline-actions:useNewDefaultBranchForCodeCommitSource": true, | ||
"@aws-cdk/aws-cloudwatch-actions:changeLambdaPermissionLogicalIdForLambdaAction": true, | ||
"@aws-cdk/aws-codepipeline:crossAccountKeysDefaultValueToFalse": true, | ||
"@aws-cdk/aws-codepipeline:defaultPipelineTypeToV2": true, | ||
"@aws-cdk/aws-kms:reduceCrossAccountRegionPolicyScope": true, | ||
"@aws-cdk/aws-eks:nodegroupNameAttribute": true, | ||
"@aws-cdk/aws-ec2:ebsDefaultGp3Volume": true, | ||
"@aws-cdk/aws-ecs:removeDefaultDeploymentAlarm": true, | ||
"@aws-cdk/custom-resources:logApiResponseDataPropertyTrueDefault": false, | ||
"@aws-cdk/aws-s3:keepNotificationInImportedBucket": false, | ||
"@aws-cdk/aws-ecs:reduceEc2FargateCloudWatchPermissions": true, | ||
"@aws-cdk/aws-dynamodb:resourcePolicyPerReplica": true, | ||
"@aws-cdk/aws-ec2:ec2SumTimeoutEnabled": true, | ||
"@aws-cdk/aws-appsync:appSyncGraphQLAPIScopeLambdaPermission": true, | ||
"@aws-cdk/aws-rds:setCorrectValueForDatabaseInstanceReadReplicaInstanceResourceId": true, | ||
"@aws-cdk/core:cfnIncludeRejectComplexResourceUpdateCreatePolicyIntrinsics": true, | ||
"@aws-cdk/aws-lambda-nodejs:sdkV3ExcludeSmithyPackages": true, | ||
"@aws-cdk/aws-stepfunctions-tasks:fixRunEcsTaskPolicy": true | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" | ||
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<groupId>com.myorg</groupId> | ||
<artifactId>application-load-balancer</artifactId> | ||
<version>0.1</version> | ||
|
||
<properties> | ||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||
<cdk.version>2.171.1</cdk.version> | ||
<constructs.version>[10.0.0,11.0.0)</constructs.version> | ||
<junit.version>5.7.1</junit.version> | ||
<maven.compiler.target>22</maven.compiler.target> | ||
<maven.compiler.source>22</maven.compiler.source> | ||
</properties> | ||
|
||
<build> | ||
<plugins> | ||
<plugin> | ||
<groupId>org.apache.maven.plugins</groupId> | ||
<artifactId>maven-compiler-plugin</artifactId> | ||
<version>3.11.0</version> | ||
<configuration> | ||
<release>17</release> | ||
</configuration> | ||
</plugin> | ||
<plugin> | ||
<groupId>org.codehaus.mojo</groupId> | ||
<artifactId>exec-maven-plugin</artifactId> | ||
<version>3.1.0</version> | ||
<configuration> | ||
<mainClass>com.myorg.ApplicationLoadBalancerApp</mainClass> | ||
</configuration> | ||
</plugin> | ||
</plugins> | ||
</build> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>software.amazon.awscdk</groupId> | ||
<artifactId>aws-cdk-lib</artifactId> | ||
<version>${cdk.version}</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>software.constructs</groupId> | ||
<artifactId>constructs</artifactId> | ||
<version>${constructs.version}</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.junit.jupiter</groupId> | ||
<artifactId>junit-jupiter</artifactId> | ||
<version>${junit.version}</version> | ||
<scope>test</scope> | ||
</dependency> | ||
</dependencies> | ||
</project> |
13 changes: 13 additions & 0 deletions
13
java/application-load-balancer/src/main/java/com/myorg/ApplicationLoadBalancerApp.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package com.myorg; | ||
|
||
import software.amazon.awscdk.App; | ||
import software.amazon.awscdk.StackProps; | ||
|
||
public class ApplicationLoadBalancerApp { | ||
public static void main(final String[] args) { | ||
var app = new App(); | ||
var stackProps = StackProps.builder().build(); | ||
new ApplicationLoadBalancerStack(app, "ApplicationLoadBalancerStack", stackProps); | ||
app.synth(); | ||
} | ||
} |
79 changes: 79 additions & 0 deletions
79
java/application-load-balancer/src/main/java/com/myorg/ApplicationLoadBalancerStack.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
package com.myorg; | ||
|
||
import software.amazon.awscdk.CfnOutput; | ||
import software.amazon.awscdk.Stack; | ||
import software.amazon.awscdk.StackProps; | ||
import software.amazon.awscdk.services.autoscaling.AutoScalingGroup; | ||
import software.amazon.awscdk.services.autoscaling.RequestCountScalingProps; | ||
import software.amazon.awscdk.services.ec2.*; | ||
import software.amazon.awscdk.services.elasticloadbalancingv2.AddApplicationTargetsProps; | ||
import software.amazon.awscdk.services.elasticloadbalancingv2.ApplicationListenerProps; | ||
import software.amazon.awscdk.services.elasticloadbalancingv2.ApplicationLoadBalancer; | ||
import software.constructs.Construct; | ||
|
||
import java.util.List; | ||
|
||
public class ApplicationLoadBalancerStack extends Stack { | ||
|
||
// This user data string is required to deploy a nginx web server to each EC2 instance created. | ||
// A simple web page that displays the host name of the EC2 instance is also deployed to nginx. | ||
// This is useful to check if the ALB created sends requests to different EC2 instances by observing the hostname displayed. | ||
private static final String USER_DATA_CONTENT_NGINX = """ | ||
#!/bin/bash | ||
dnf -y upgrade | ||
dnf -y install nginx | ||
systemctl start nginx | ||
systemctl enable nginx | ||
rm -rfv /usr/share/nginx/html/ && mkdir /usr/share/nginx/html/ | ||
echo "<h1>Hello world from $(hostname -f)</h1>" > /usr/share/nginx/html/index.html | ||
"""; | ||
|
||
public ApplicationLoadBalancerStack(final Construct scope, final String id, final StackProps props) { | ||
super(scope, id, props); | ||
var vpc = Vpc.Builder.create(this, "VPC") | ||
.restrictDefaultSecurityGroup(false) | ||
.build(); | ||
var amazonLinuxImage = AmazonLinuxImage.Builder.create() | ||
.generation(AmazonLinuxGeneration.AMAZON_LINUX_2023) | ||
.cpuType(AmazonLinuxCpuType.ARM_64) | ||
.userData(UserData.custom(USER_DATA_CONTENT_NGINX)) | ||
.build(); | ||
var autoScalingGroup = AutoScalingGroup.Builder.create(this, "ASG") | ||
.vpc(vpc) | ||
.instanceType(InstanceType.of(InstanceClass.BURSTABLE4_GRAVITON, InstanceSize.MICRO)) | ||
.machineImage(amazonLinuxImage) | ||
// Change the desired capacity (default value of 1) so that 2 EC2 instances are created initially instead of one. | ||
// This way the ALB will route requests between both instances right away making it easier to test load balancing functionality. | ||
.desiredCapacity(2) | ||
.maxCapacity(3) | ||
.minCapacity(1) | ||
.build(); | ||
var applicationLoadBalancer = ApplicationLoadBalancer.Builder.create(this, "LB") | ||
.vpc(vpc) | ||
.loadBalancerName("LB") | ||
.internetFacing(Boolean.TRUE) | ||
.build(); | ||
var applicationListenerProps = ApplicationListenerProps.builder() | ||
.port(80) | ||
.loadBalancer(applicationLoadBalancer) | ||
.build(); | ||
var applicationListener = applicationLoadBalancer.addListener("Listener", applicationListenerProps); | ||
var addApplicationTargetsProps = AddApplicationTargetsProps.builder() | ||
.port(80) | ||
.targets(List.of(autoScalingGroup)) | ||
.build(); | ||
applicationListener.addTargets("Target", addApplicationTargetsProps); | ||
applicationListener.getConnections().allowDefaultPortFromAnyIpv4("Open to the world"); | ||
var requestCountScalingProps = RequestCountScalingProps.builder() | ||
.targetRequestsPerMinute(60) | ||
.build(); | ||
// This is an example on how to create a dynamic target tracking scaling policy. | ||
// This is based on the ALB request count per target, but it is more difficult to test. | ||
// The dynamic scaling policy should show up though in the AWS Management Console for the ASG created. | ||
autoScalingGroup.scaleOnRequestCount("AModestLoad", requestCountScalingProps); | ||
CfnOutput.Builder.create(this, "ApplicationLoadBalancerURL") | ||
.value(applicationListener.getLoadBalancer().getLoadBalancerDnsName()) | ||
.description("The DNS of the application load balancer.") | ||
.build(); | ||
} | ||
} |
Oops, something went wrong.