diff --git a/README.md b/README.md index 2e1566d49..3f25be906 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,7 @@ $ cdk destroy | Example | Description | |---------|-------------| +| [fargate-load-balanced-service](https://github.com/aws-samples/aws-cdk-examples/tree/master/java/ecs/fargate-load-balanced-service/) | Starting a container fronted by a load balancer on Fargate | | [hello-world](https://github.com/aws-samples/aws-cdk-examples/tree/master/java/hello-world/) | A demo application that uses the CDK in Java | | [lambda-cron](https://github.com/aws-samples/aws-cdk-examples/tree/master/java/lambda-cron/) | Running a Lambda on a schedule | | [resource-overrides](https://github.com/aws-samples/aws-cdk-examples/tree/master/java/resource-overrides/) | Use of the resource overrides (aka ["escape hatch"](https://docs.aws.amazon.com/cdk/latest/guide/cfn_layer.html)) mechanism. | diff --git a/java/ecs/fargate-load-balanced-service/.gitignore b/java/ecs/fargate-load-balanced-service/.gitignore new file mode 100644 index 000000000..c3d640426 --- /dev/null +++ b/java/ecs/fargate-load-balanced-service/.gitignore @@ -0,0 +1,14 @@ +.classpath.txt +target +.classpath +.project +.idea +.settings +.vscode +*.iml +cdk.context.json + +# CDK asset staging directory +.cdk.staging +cdk.out + diff --git a/java/ecs/fargate-load-balanced-service/README.md b/java/ecs/fargate-load-balanced-service/README.md new file mode 100644 index 000000000..22be125d7 --- /dev/null +++ b/java/ecs/fargate-load-balanced-service/README.md @@ -0,0 +1,22 @@ + +Welcome to your CDK Java project! + +It is a Maven-based project, so you can open this directory with any Maven-compatible Java IDE, +and you should be able to build and run tests from your IDE. + +You should explore the contents of this template. It demonstrates a CDK app with two instances of +a stack (`HelloStack`) which also uses a user-defined construct (`HelloConstruct`). + +The `cdk.json` file tells the CDK Toolkit how to execute your app. This example relies on maven +to do that. + +# 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 + +Enjoy! diff --git a/java/ecs/fargate-load-balanced-service/cdk.json b/java/ecs/fargate-load-balanced-service/cdk.json new file mode 100644 index 000000000..2561eae00 --- /dev/null +++ b/java/ecs/fargate-load-balanced-service/cdk.json @@ -0,0 +1,3 @@ +{ + "app": "mvn -q exec:java" +} diff --git a/java/ecs/fargate-load-balanced-service/pom.xml b/java/ecs/fargate-load-balanced-service/pom.xml new file mode 100644 index 000000000..478e90263 --- /dev/null +++ b/java/ecs/fargate-load-balanced-service/pom.xml @@ -0,0 +1,64 @@ + + + 4.0.0 + + com.amazonaws.cdk + fargate-load-balanced-service + 0.1 + + + UTF-8 + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.7.0 + + 1.8 + 1.8 + + + + + org.codehaus.mojo + exec-maven-plugin + 1.6.0 + + com.amazonaws.cdk.examples.ECSFargateLoadBalancedApp + + + + + + + + + software.amazon.awscdk + core + 1.16.0.DEVPREVIEW + + + + + software.amazon.awscdk + ecs + 1.16.0.DEVPREVIEW + + + software.amazon.awscdk + ecs-patterns + 1.16.0.DEVPREVIEW + + + + junit + junit + 4.12 + test + + + diff --git a/java/ecs/fargate-load-balanced-service/src/main/java/com/amazonaws/cdk/examples/ECSFargateLoadBalancedApp.java b/java/ecs/fargate-load-balanced-service/src/main/java/com/amazonaws/cdk/examples/ECSFargateLoadBalancedApp.java new file mode 100644 index 000000000..3cda379c2 --- /dev/null +++ b/java/ecs/fargate-load-balanced-service/src/main/java/com/amazonaws/cdk/examples/ECSFargateLoadBalancedApp.java @@ -0,0 +1,14 @@ +package com.amazonaws.cdk.examples; + +import software.amazon.awscdk.core.App; + +public class ECSFargateLoadBalancedApp { + public static void main(final String argv[]) { + App app = new App(); + + new ECSFargateLoadBalancedStack(app, "fargate-load-balanced-service"); + + // required until https://github.com/aws/jsii/issues/456 is resolved + app.synth(); + } +} diff --git a/java/ecs/fargate-load-balanced-service/src/main/java/com/amazonaws/cdk/examples/ECSFargateLoadBalancedStack.java b/java/ecs/fargate-load-balanced-service/src/main/java/com/amazonaws/cdk/examples/ECSFargateLoadBalancedStack.java new file mode 100644 index 000000000..5d50b59fe --- /dev/null +++ b/java/ecs/fargate-load-balanced-service/src/main/java/com/amazonaws/cdk/examples/ECSFargateLoadBalancedStack.java @@ -0,0 +1,39 @@ +package com.amazonaws.cdk.examples; + +import software.amazon.awscdk.core.*; +import software.amazon.awscdk.services.ec2.Vpc; +import software.amazon.awscdk.services.ec2.VpcProps; +import software.amazon.awscdk.services.ecs.Cluster; +import software.amazon.awscdk.services.ecs.ClusterProps; +import software.amazon.awscdk.services.ecs.ContainerImage; +import software.amazon.awscdk.services.ecs.patterns.NetworkLoadBalancedFargateService; +import software.amazon.awscdk.services.ecs.patterns.NetworkLoadBalancedFargateServiceProps; +import software.amazon.awscdk.services.ecs.patterns.NetworkLoadBalancedTaskImageOptions; + +public class ECSFargateLoadBalancedStack extends Stack { + + public ECSFargateLoadBalancedStack(final Construct parent, final String id) { + this(parent, id, null); + } + + public ECSFargateLoadBalancedStack(final Construct parent, final String id, final StackProps props) { + super(parent, id, props); + + // Create VPC with a AZ limit of two. + Vpc vpc = new Vpc(this, "MyVpc", VpcProps.builder().maxAzs(2).build()); + + // Create the ECS Service + Cluster cluster = new Cluster(this, "Ec2Cluster", ClusterProps.builder().vpc(vpc).build()); + + // Use the ECS Network Load Balanced Fargate Service construct to create a ECS service + NetworkLoadBalancedFargateService fargateService = new NetworkLoadBalancedFargateService( + this, + "FargateService", + NetworkLoadBalancedFargateServiceProps.builder() + .cluster(cluster) + .taskImageOptions(NetworkLoadBalancedTaskImageOptions.builder() + .image(ContainerImage.fromRegistry("amazon/amazon-ecs-sample")) + .build()) + .build()); + } +} diff --git a/java/ecs/fargate-load-balanced-service/src/test/java/com/amazonaws/cdk/examples/ECSFargateLoadBalancedStackTest.java b/java/ecs/fargate-load-balanced-service/src/test/java/com/amazonaws/cdk/examples/ECSFargateLoadBalancedStackTest.java new file mode 100644 index 000000000..79770ffb8 --- /dev/null +++ b/java/ecs/fargate-load-balanced-service/src/test/java/com/amazonaws/cdk/examples/ECSFargateLoadBalancedStackTest.java @@ -0,0 +1,28 @@ +package com.amazonaws.cdk.examples; + +import software.amazon.awscdk.core.App; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import org.junit.Test; + +import java.io.IOException; + +import static junit.framework.TestCase.assertEquals; + +public class ECSFargateLoadBalancedStackTest { + private final static ObjectMapper JSON = + new ObjectMapper().configure(SerializationFeature.INDENT_OUTPUT, true); + + @Test + public void testStack() throws IOException { + App app = new App(); + ECSFargateLoadBalancedStack stack = new ECSFargateLoadBalancedStack(app, "test"); + + // synthesize the stack to a CloudFormation template and compare against + // a checked-in JSON file. + JsonNode actual = JSON.valueToTree(app.synth().getStackArtifact(stack.getArtifactId()).getTemplate()); + JsonNode expected = JSON.readTree(getClass().getResource("expected.cfn.json")); + assertEquals(expected, actual); + } +} diff --git a/java/ecs/fargate-load-balanced-service/src/test/resources/com/amazonaws/cdk/examples/expected.cfn.json b/java/ecs/fargate-load-balanced-service/src/test/resources/com/amazonaws/cdk/examples/expected.cfn.json new file mode 100644 index 000000000..e529f3037 --- /dev/null +++ b/java/ecs/fargate-load-balanced-service/src/test/resources/com/amazonaws/cdk/examples/expected.cfn.json @@ -0,0 +1,622 @@ +{ + "Resources": { + "MyVpcF9F0CA6F": { + "Type": "AWS::EC2::VPC", + "Properties": { + "CidrBlock": "10.0.0.0/16", + "EnableDnsHostnames": true, + "EnableDnsSupport": true, + "InstanceTenancy": "default", + "Tags": [ + { + "Key": "Name", + "Value": "test/MyVpc" + } + ] + } + }, + "MyVpcPublicSubnet1SubnetF6608456": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "CidrBlock": "10.0.0.0/18", + "VpcId": { + "Ref": "MyVpcF9F0CA6F" + }, + "AvailabilityZone": { + "Fn::Select": [ + 0, + { + "Fn::GetAZs": "" + } + ] + }, + "MapPublicIpOnLaunch": true, + "Tags": [ + { + "Key": "Name", + "Value": "test/MyVpc/PublicSubnet1" + }, + { + "Key": "aws-cdk:subnet-name", + "Value": "Public" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Public" + } + ] + } + }, + "MyVpcPublicSubnet1RouteTableC46AB2F4": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "MyVpcF9F0CA6F" + }, + "Tags": [ + { + "Key": "Name", + "Value": "test/MyVpc/PublicSubnet1" + } + ] + } + }, + "MyVpcPublicSubnet1RouteTableAssociation2ECEE1CB": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "MyVpcPublicSubnet1RouteTableC46AB2F4" + }, + "SubnetId": { + "Ref": "MyVpcPublicSubnet1SubnetF6608456" + } + } + }, + "MyVpcPublicSubnet1DefaultRoute95FDF9EB": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "MyVpcPublicSubnet1RouteTableC46AB2F4" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "GatewayId": { + "Ref": "MyVpcIGW5C4A4F63" + } + }, + "DependsOn": [ + "MyVpcVPCGW488ACE0D" + ] + }, + "MyVpcPublicSubnet1EIP096967CB": { + "Type": "AWS::EC2::EIP", + "Properties": { + "Domain": "vpc" + } + }, + "MyVpcPublicSubnet1NATGatewayAD3400C1": { + "Type": "AWS::EC2::NatGateway", + "Properties": { + "AllocationId": { + "Fn::GetAtt": [ + "MyVpcPublicSubnet1EIP096967CB", + "AllocationId" + ] + }, + "SubnetId": { + "Ref": "MyVpcPublicSubnet1SubnetF6608456" + }, + "Tags": [ + { + "Key": "Name", + "Value": "test/MyVpc/PublicSubnet1" + } + ] + } + }, + "MyVpcPublicSubnet2Subnet492B6BFB": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "CidrBlock": "10.0.64.0/18", + "VpcId": { + "Ref": "MyVpcF9F0CA6F" + }, + "AvailabilityZone": { + "Fn::Select": [ + 1, + { + "Fn::GetAZs": "" + } + ] + }, + "MapPublicIpOnLaunch": true, + "Tags": [ + { + "Key": "Name", + "Value": "test/MyVpc/PublicSubnet2" + }, + { + "Key": "aws-cdk:subnet-name", + "Value": "Public" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Public" + } + ] + } + }, + "MyVpcPublicSubnet2RouteTable1DF17386": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "MyVpcF9F0CA6F" + }, + "Tags": [ + { + "Key": "Name", + "Value": "test/MyVpc/PublicSubnet2" + } + ] + } + }, + "MyVpcPublicSubnet2RouteTableAssociation227DE78D": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "MyVpcPublicSubnet2RouteTable1DF17386" + }, + "SubnetId": { + "Ref": "MyVpcPublicSubnet2Subnet492B6BFB" + } + } + }, + "MyVpcPublicSubnet2DefaultRoute052936F6": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "MyVpcPublicSubnet2RouteTable1DF17386" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "GatewayId": { + "Ref": "MyVpcIGW5C4A4F63" + } + }, + "DependsOn": [ + "MyVpcVPCGW488ACE0D" + ] + }, + "MyVpcPublicSubnet2EIP8CCBA239": { + "Type": "AWS::EC2::EIP", + "Properties": { + "Domain": "vpc" + } + }, + "MyVpcPublicSubnet2NATGateway91BFBEC9": { + "Type": "AWS::EC2::NatGateway", + "Properties": { + "AllocationId": { + "Fn::GetAtt": [ + "MyVpcPublicSubnet2EIP8CCBA239", + "AllocationId" + ] + }, + "SubnetId": { + "Ref": "MyVpcPublicSubnet2Subnet492B6BFB" + }, + "Tags": [ + { + "Key": "Name", + "Value": "test/MyVpc/PublicSubnet2" + } + ] + } + }, + "MyVpcPrivateSubnet1Subnet5057CF7E": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "CidrBlock": "10.0.128.0/18", + "VpcId": { + "Ref": "MyVpcF9F0CA6F" + }, + "AvailabilityZone": { + "Fn::Select": [ + 0, + { + "Fn::GetAZs": "" + } + ] + }, + "MapPublicIpOnLaunch": false, + "Tags": [ + { + "Key": "Name", + "Value": "test/MyVpc/PrivateSubnet1" + }, + { + "Key": "aws-cdk:subnet-name", + "Value": "Private" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Private" + } + ] + } + }, + "MyVpcPrivateSubnet1RouteTable8819E6E2": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "MyVpcF9F0CA6F" + }, + "Tags": [ + { + "Key": "Name", + "Value": "test/MyVpc/PrivateSubnet1" + } + ] + } + }, + "MyVpcPrivateSubnet1RouteTableAssociation56D38C7E": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "MyVpcPrivateSubnet1RouteTable8819E6E2" + }, + "SubnetId": { + "Ref": "MyVpcPrivateSubnet1Subnet5057CF7E" + } + } + }, + "MyVpcPrivateSubnet1DefaultRouteA8CDE2FA": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "MyVpcPrivateSubnet1RouteTable8819E6E2" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "NatGatewayId": { + "Ref": "MyVpcPublicSubnet1NATGatewayAD3400C1" + } + } + }, + "MyVpcPrivateSubnet2Subnet0040C983": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "CidrBlock": "10.0.192.0/18", + "VpcId": { + "Ref": "MyVpcF9F0CA6F" + }, + "AvailabilityZone": { + "Fn::Select": [ + 1, + { + "Fn::GetAZs": "" + } + ] + }, + "MapPublicIpOnLaunch": false, + "Tags": [ + { + "Key": "Name", + "Value": "test/MyVpc/PrivateSubnet2" + }, + { + "Key": "aws-cdk:subnet-name", + "Value": "Private" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Private" + } + ] + } + }, + "MyVpcPrivateSubnet2RouteTableCEDCEECE": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "MyVpcF9F0CA6F" + }, + "Tags": [ + { + "Key": "Name", + "Value": "test/MyVpc/PrivateSubnet2" + } + ] + } + }, + "MyVpcPrivateSubnet2RouteTableAssociation86A610DA": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "MyVpcPrivateSubnet2RouteTableCEDCEECE" + }, + "SubnetId": { + "Ref": "MyVpcPrivateSubnet2Subnet0040C983" + } + } + }, + "MyVpcPrivateSubnet2DefaultRoute9CE96294": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "MyVpcPrivateSubnet2RouteTableCEDCEECE" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "NatGatewayId": { + "Ref": "MyVpcPublicSubnet2NATGateway91BFBEC9" + } + } + }, + "MyVpcIGW5C4A4F63": { + "Type": "AWS::EC2::InternetGateway", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "test/MyVpc" + } + ] + } + }, + "MyVpcVPCGW488ACE0D": { + "Type": "AWS::EC2::VPCGatewayAttachment", + "Properties": { + "VpcId": { + "Ref": "MyVpcF9F0CA6F" + }, + "InternetGatewayId": { + "Ref": "MyVpcIGW5C4A4F63" + } + } + }, + "Ec2ClusterEE43E89D": { + "Type": "AWS::ECS::Cluster" + }, + "FargateServiceLBB353E155": { + "Type": "AWS::ElasticLoadBalancingV2::LoadBalancer", + "Properties": { + "Scheme": "internet-facing", + "Subnets": [ + { + "Ref": "MyVpcPublicSubnet1SubnetF6608456" + }, + { + "Ref": "MyVpcPublicSubnet2Subnet492B6BFB" + } + ], + "Type": "network" + }, + "DependsOn": [ + "MyVpcPublicSubnet1DefaultRoute95FDF9EB", + "MyVpcPublicSubnet2DefaultRoute052936F6" + ] + }, + "FargateServiceLBPublicListener4B4929CA": { + "Type": "AWS::ElasticLoadBalancingV2::Listener", + "Properties": { + "DefaultActions": [ + { + "TargetGroupArn": { + "Ref": "FargateServiceLBPublicListenerECSGroupBE57E081" + }, + "Type": "forward" + } + ], + "LoadBalancerArn": { + "Ref": "FargateServiceLBB353E155" + }, + "Port": 80, + "Protocol": "TCP" + } + }, + "FargateServiceLBPublicListenerECSGroupBE57E081": { + "Type": "AWS::ElasticLoadBalancingV2::TargetGroup", + "Properties": { + "Port": 80, + "Protocol": "TCP", + "TargetType": "ip", + "VpcId": { + "Ref": "MyVpcF9F0CA6F" + } + } + }, + "FargateServiceTaskDefTaskRole8CDCF85E": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "ecs-tasks.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "FargateServiceTaskDef940E3A80": { + "Type": "AWS::ECS::TaskDefinition", + "Properties": { + "ContainerDefinitions": [ + { + "Essential": true, + "Image": "amazon/amazon-ecs-sample", + "LogConfiguration": { + "LogDriver": "awslogs", + "Options": { + "awslogs-group": { + "Ref": "FargateServiceTaskDefwebLogGroup71FAF541" + }, + "awslogs-stream-prefix": "FargateService", + "awslogs-region": { + "Ref": "AWS::Region" + } + } + }, + "Name": "web", + "PortMappings": [ + { + "ContainerPort": 80, + "Protocol": "tcp" + } + ] + } + ], + "Cpu": "256", + "ExecutionRoleArn": { + "Fn::GetAtt": [ + "FargateServiceTaskDefExecutionRole9194820E", + "Arn" + ] + }, + "Family": "testFargateServiceTaskDef1F7483D2", + "Memory": "512", + "NetworkMode": "awsvpc", + "RequiresCompatibilities": [ + "FARGATE" + ], + "TaskRoleArn": { + "Fn::GetAtt": [ + "FargateServiceTaskDefTaskRole8CDCF85E", + "Arn" + ] + } + } + }, + "FargateServiceTaskDefwebLogGroup71FAF541": { + "Type": "AWS::Logs::LogGroup", + "UpdateReplacePolicy": "Retain", + "DeletionPolicy": "Retain" + }, + "FargateServiceTaskDefExecutionRole9194820E": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "ecs-tasks.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "FargateServiceTaskDefExecutionRoleDefaultPolicy827E7CA2": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "logs:CreateLogStream", + "logs:PutLogEvents" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "FargateServiceTaskDefwebLogGroup71FAF541", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "FargateServiceTaskDefExecutionRoleDefaultPolicy827E7CA2", + "Roles": [ + { + "Ref": "FargateServiceTaskDefExecutionRole9194820E" + } + ] + } + }, + "FargateServiceECC8084D": { + "Type": "AWS::ECS::Service", + "Properties": { + "TaskDefinition": { + "Ref": "FargateServiceTaskDef940E3A80" + }, + "Cluster": { + "Ref": "Ec2ClusterEE43E89D" + }, + "DeploymentConfiguration": { + "MaximumPercent": 200, + "MinimumHealthyPercent": 50 + }, + "DesiredCount": 1, + "EnableECSManagedTags": false, + "HealthCheckGracePeriodSeconds": 60, + "LaunchType": "FARGATE", + "LoadBalancers": [ + { + "ContainerName": "web", + "ContainerPort": 80, + "TargetGroupArn": { + "Ref": "FargateServiceLBPublicListenerECSGroupBE57E081" + } + } + ], + "NetworkConfiguration": { + "AwsvpcConfiguration": { + "AssignPublicIp": "DISABLED", + "SecurityGroups": [ + { + "Fn::GetAtt": [ + "FargateServiceSecurityGroup262B61DD", + "GroupId" + ] + } + ], + "Subnets": [ + { + "Ref": "MyVpcPrivateSubnet1Subnet5057CF7E" + }, + { + "Ref": "MyVpcPrivateSubnet2Subnet0040C983" + } + ] + } + } + }, + "DependsOn": [ + "FargateServiceLBPublicListenerECSGroupBE57E081", + "FargateServiceLBPublicListener4B4929CA" + ] + }, + "FargateServiceSecurityGroup262B61DD": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "test/FargateService/Service/SecurityGroup", + "SecurityGroupEgress": [ + { + "CidrIp": "0.0.0.0/0", + "Description": "Allow all outbound traffic by default", + "IpProtocol": "-1" + } + ], + "VpcId": { + "Ref": "MyVpcF9F0CA6F" + } + } + } + }, + "Outputs": { + "FargateServiceLoadBalancerDNS9433D5F6": { + "Value": { + "Fn::GetAtt": [ + "FargateServiceLBB353E155", + "DNSName" + ] + } + } + } +} \ No newline at end of file