private void ConfigureTaskDefinition(IRecipeProps <Configuration> props) { var settings = props.Settings; AppTaskDefinition = new FargateTaskDefinition(this, nameof(AppTaskDefinition), InvokeCustomizeCDKPropsEvent(nameof(AppTaskDefinition), this, new FargateTaskDefinitionProps { TaskRole = AppIAMTaskRole, Cpu = settings.TaskCpu, MemoryLimitMiB = settings.TaskMemory })); AppLogging = new AwsLogDriver(InvokeCustomizeCDKPropsEvent(nameof(AppLogging), this, new AwsLogDriverProps { StreamPrefix = props.StackName })); if (string.IsNullOrEmpty(props.ECRRepositoryName)) { throw new InvalidOrMissingConfigurationException("The provided ECR Repository Name is null or empty."); } var ecrRepository = Repository.FromRepositoryName(this, "ECRRepository", props.ECRRepositoryName); AppContainerDefinition = new ContainerDefinitionOptions { Image = ContainerImage.FromEcrRepository(ecrRepository, props.ECRImageTag), Logging = AppLogging }; AppTaskDefinition.AddContainer(nameof(AppContainerDefinition), InvokeCustomizeCDKPropsEvent(nameof(AppContainerDefinition), this, AppContainerDefinition)); }
public FargateStack(Construct scope, string id, FargateStackProps props = null) : base(scope, id, props) { var cluster = new Cluster(this, "WhatDayOfWeekCluster", new ClusterProps { Vpc = props.Vpc }); var logging = new AwsLogDriver(new AwsLogDriverProps() { StreamPrefix = "WhatDayOfWeek", LogRetention = Amazon.CDK.AWS.Logs.RetentionDays.ONE_DAY }); //container /* * var repo = Repository.FromRepositoryName(this, "myrepo","MyRepositoryName"); * * var containerOptions = new ContainerDefinitionOptions * { * Image = ContainerImage.FromEcrRepository(repo) * }; */ // to build the container image from the app in the local folder, replace lines 29-35 with //var rootDirectory = Directory.GetCurrentDirectory(); //var path = Path.GetFullPath(Path.Combine(rootDirectory, @"App/WhatDayOfWeek")); var containerOptions = new ContainerDefinitionOptions { Image = ContainerImage.FromAsset(@"App/WhatDayOfWeek"), Logging = logging }; var portMapping = new PortMapping() { ContainerPort = 80, HostPort = 80 }; var taskDef = new FargateTaskDefinition(this, "WhatDayOfWeekTaskDefinition"); taskDef.AddContainer("WhatDayOfWeekContainer", containerOptions).AddPortMappings(portMapping); var serviceProps = new ApplicationLoadBalancedFargateServiceProps() { ServiceName = "WhatDayOfWeekService", MemoryLimitMiB = 512, Cpu = 256, TaskDefinition = taskDef, Cluster = cluster }; ApplicationLoadBalancedFargateService service = new ApplicationLoadBalancedFargateService(this, "WhatDayOfWeekService", serviceProps); }
internal CreditoWebApiStack(Construct scope, string id, CustomStackProps props = null) : base(scope, id, props) { var vpc = props.Vpc; var creditoWebApiTargetGroup = new ApplicationTargetGroup(this, "CreditoWebApiTargetGroup", new ApplicationTargetGroupProps { Protocol = ApplicationProtocol.HTTP, Port = 80, Vpc = vpc, TargetType = TargetType.IP, DeregistrationDelay = Duration.Seconds(60), HealthCheck = new Amazon.CDK.AWS.ElasticLoadBalancingV2.HealthCheck { Enabled = true, Path = "/api/credito/_monitor/shallow", Protocol = Amazon.CDK.AWS.ElasticLoadBalancingV2.Protocol.HTTP, Port = "traffic-port", UnhealthyThresholdCount = 2, Interval = Duration.Seconds(60), HealthyThresholdCount = 5, Timeout = Duration.Seconds(5), HealthyHttpCodes = "200" } }); var webApiServiceSecurityGroup = SecurityGroup.FromSecurityGroupId(this, "WebApiServiceSecurityGroup", Fn.ImportValue(Globals.GetDeployEnvironment(this).PutEnvNamePrefixWithDash("WebApiServiceSecurityGroupId"))); var appListener = ApplicationListener.FromApplicationListenerAttributes(this, "AppListener", new ApplicationListenerAttributes { ListenerArn = Fn.ImportValue(Globals.GetDeployEnvironment(this).PutEnvNamePrefixWithDash("AppListenerArn")), SecurityGroup = webApiServiceSecurityGroup }); appListener.AddTargetGroups("CreditoWebApiTargetGroup", new AddApplicationTargetGroupsProps { Conditions = new ListenerCondition[] { ListenerCondition.PathPatterns(new string[] { "/api/credito*" }) }, Priority = 100, TargetGroups = new ApplicationTargetGroup[] { creditoWebApiTargetGroup } }); var creditoWebApiLogGroup = new LogGroup(this, "CreditoWebApiContainerLogGroup", new LogGroupProps { LogGroupName = $"/ecs/{Globals.GetDeployEnvironment(this).EnvName}/credito/web-api", Retention = RetentionDays.FIVE_DAYS, RemovalPolicy = RemovalPolicy.SNAPSHOT }); var creditoWebApiTaskDefinition = new FargateTaskDefinition(this, "CreditoWebApiTaskDefinition", new FargateTaskDefinitionProps { MemoryLimitMiB = 512, Cpu = 256 }); var creditoWebApiLogging = new AwsLogDriver( new AwsLogDriverProps { StreamPrefix = "ecs", LogGroup = creditoWebApiLogGroup }); var creditoWebApiContainer = creditoWebApiTaskDefinition.AddContainer("CreditoWebApiContainer", new ContainerDefinitionOptions { Image = ContainerImage.FromAsset( Directory.GetCurrentDirectory(), new AssetImageProps { File = "src/Credito.WebApi/Dockerfile" }), Logging = creditoWebApiLogging, Environment = new Dictionary <string, string>() { ["CreditoDatabase__ConnectionString"] = StringParameter.ValueFromLookup( this, $"/{Globals.GetDeployEnvironment(this).EnvName}/credito/web-api/db/connection-string"), ["CreditoDatabase__DatabaseName"] = StringParameter.ValueFromLookup( this, $"/{Globals.GetDeployEnvironment(this).EnvName}/credito/web-api/db/database-name") } }); creditoWebApiContainer.AddPortMappings( new PortMapping { ContainerPort = 80, HostPort = 80, Protocol = Amazon.CDK.AWS.ECS.Protocol.TCP }); var cluster = Cluster.FromClusterAttributes(this, "Cluster", new ClusterAttributes { ClusterName = Fn.ImportValue(Globals.GetDeployEnvironment(this).PutEnvNamePrefixWithDash("ClusterName")), Vpc = vpc, SecurityGroups = new SecurityGroup[] { } }); var creditoWebApiService = new FargateService(this, "CreditoWebApiService", new FargateServiceProps { Cluster = cluster, TaskDefinition = creditoWebApiTaskDefinition, DesiredCount = 1, CircuitBreaker = new DeploymentCircuitBreaker { Rollback = true }, AssignPublicIp = false, HealthCheckGracePeriod = Duration.Seconds(60), SecurityGroups = new ISecurityGroup[] { webApiServiceSecurityGroup }, VpcSubnets = new SubnetSelection { SubnetType = SubnetType.PRIVATE } }); creditoWebApiService.AttachToApplicationTargetGroup(creditoWebApiTargetGroup); }
internal AppStack(Construct scope, RecipeConfiguration <Configuration> recipeConfiguration, IStackProps props = null) : base(scope, recipeConfiguration.StackName, props) { var settings = recipeConfiguration.Settings; IVpc vpc; if (settings.Vpc.IsDefault) { vpc = Vpc.FromLookup(this, "Vpc", new VpcLookupOptions { IsDefault = true }); } else if (settings.Vpc.CreateNew) { vpc = new Vpc(this, "Vpc", new VpcProps { MaxAzs = 2 }); } else { vpc = Vpc.FromLookup(this, "Vpc", new VpcLookupOptions { VpcId = settings.Vpc.VpcId }); } ICluster cluster; if (settings.ECSCluster.CreateNew) { cluster = new Cluster(this, "Cluster", new ClusterProps { Vpc = vpc, ClusterName = settings.ECSCluster.NewClusterName }); } else { cluster = Cluster.FromClusterAttributes(this, "Cluster", new ClusterAttributes { ClusterArn = settings.ECSCluster.ClusterArn, ClusterName = ECSFargateUtilities.GetClusterNameFromArn(settings.ECSCluster.ClusterArn), SecurityGroups = new ISecurityGroup[0], Vpc = vpc }); } IRole taskRole; if (settings.ApplicationIAMRole.CreateNew) { taskRole = new Role(this, "TaskRole", new RoleProps { AssumedBy = new ServicePrincipal("ecs-tasks.amazonaws.com") }); } else { taskRole = Role.FromRoleArn(this, "TaskRole", settings.ApplicationIAMRole.RoleArn, new FromRoleArnOptions { Mutable = false }); } var taskDefinition = new FargateTaskDefinition(this, "TaskDefinition", new FargateTaskDefinitionProps { TaskRole = taskRole, Cpu = settings.TaskCpu, MemoryLimitMiB = settings.TaskMemory }); var logging = new AwsLogDriver(new AwsLogDriverProps { StreamPrefix = recipeConfiguration.StackName }); var ecrRepository = Repository.FromRepositoryName(this, "ECRRepository", recipeConfiguration.ECRRepositoryName); taskDefinition.AddContainer("Container", new ContainerDefinitionOptions { Image = ContainerImage.FromEcrRepository(ecrRepository, recipeConfiguration.ECRImageTag), Logging = logging }); SubnetSelection subnetSelection = null; if (settings.Vpc.IsDefault) { subnetSelection = new SubnetSelection { SubnetType = SubnetType.PUBLIC }; } new ScheduledFargateTask(this, "FargateService", new ScheduledFargateTaskProps { Cluster = cluster, Schedule = Schedule.Expression(settings.Schedule), Vpc = vpc, ScheduledFargateTaskDefinitionOptions = new ScheduledFargateTaskDefinitionOptions { TaskDefinition = taskDefinition }, SubnetSelection = subnetSelection }); }
private void ConfigureECSClusterAndService(IRecipeProps <Configuration> recipeConfiguration) { if (AppVpc == null) { throw new InvalidOperationException($"{nameof(AppVpc)} has not been set. The {nameof(ConfigureVpc)} method should be called before {nameof(ConfigureECSClusterAndService)}"); } var settings = recipeConfiguration.Settings; if (settings.ECSCluster.CreateNew) { EcsCluster = new Cluster(this, nameof(EcsCluster), InvokeCustomizeCDKPropsEvent(nameof(EcsCluster), this, new ClusterProps { Vpc = AppVpc, ClusterName = settings.ECSCluster.NewClusterName })); } else { EcsCluster = Cluster.FromClusterAttributes(this, nameof(EcsCluster), InvokeCustomizeCDKPropsEvent(nameof(EcsCluster), this, new ClusterAttributes { ClusterArn = settings.ECSCluster.ClusterArn, ClusterName = ECSFargateUtilities.GetClusterNameFromArn(settings.ECSCluster.ClusterArn), SecurityGroups = new ISecurityGroup[0], Vpc = AppVpc })); } AppTaskDefinition = new FargateTaskDefinition(this, nameof(AppTaskDefinition), InvokeCustomizeCDKPropsEvent(nameof(AppTaskDefinition), this, new FargateTaskDefinitionProps { TaskRole = AppIAMTaskRole, Cpu = settings.TaskCpu, MemoryLimitMiB = settings.TaskMemory })); AppLogging = new AwsLogDriver(InvokeCustomizeCDKPropsEvent(nameof(AppLogging), this, new AwsLogDriverProps { StreamPrefix = recipeConfiguration.StackName })); if (string.IsNullOrEmpty(recipeConfiguration.ECRRepositoryName)) { throw new InvalidOrMissingConfigurationException("The provided ECR Repository Name is null or empty."); } EcrRepository = Repository.FromRepositoryName(this, nameof(EcrRepository), recipeConfiguration.ECRRepositoryName); AppContainerDefinition = AppTaskDefinition.AddContainer(nameof(AppContainerDefinition), InvokeCustomizeCDKPropsEvent(nameof(AppContainerDefinition), this, new ContainerDefinitionOptions { Image = ContainerImage.FromEcrRepository(EcrRepository, recipeConfiguration.ECRImageTag), Logging = AppLogging })); AppContainerDefinition.AddPortMappings(new PortMapping { ContainerPort = 80, Protocol = Amazon.CDK.AWS.ECS.Protocol.TCP }); WebAccessSecurityGroup = new SecurityGroup(this, nameof(WebAccessSecurityGroup), InvokeCustomizeCDKPropsEvent(nameof(WebAccessSecurityGroup), this, new SecurityGroupProps { Vpc = AppVpc, SecurityGroupName = $"{recipeConfiguration.StackName}-ECSService" })); EcsServiceSecurityGroups = new List <ISecurityGroup>(); EcsServiceSecurityGroups.Add(WebAccessSecurityGroup); if (!string.IsNullOrEmpty(settings.AdditionalECSServiceSecurityGroups)) { var count = 1; foreach (var securityGroupId in settings.AdditionalECSServiceSecurityGroups.Split(',')) { EcsServiceSecurityGroups.Add(SecurityGroup.FromSecurityGroupId(this, $"AdditionalGroup-{count++}", securityGroupId.Trim(), new SecurityGroupImportOptions { Mutable = false })); } } AppFargateService = new FargateService(this, nameof(AppFargateService), InvokeCustomizeCDKPropsEvent(nameof(AppFargateService), this, new FargateServiceProps { Cluster = EcsCluster, TaskDefinition = AppTaskDefinition, DesiredCount = settings.DesiredCount, ServiceName = settings.ECSServiceName, AssignPublicIp = settings.Vpc.IsDefault, SecurityGroups = EcsServiceSecurityGroups.ToArray() })); }
internal AppStack(Construct scope, RecipeConfiguration <Configuration> recipeConfiguration, IStackProps props = null) : base(scope, recipeConfiguration.StackName, props) { var settings = recipeConfiguration.Settings; IVpc vpc; if (settings.Vpc.IsDefault) { vpc = Vpc.FromLookup(this, "Vpc", new VpcLookupOptions { IsDefault = true }); } else if (settings.Vpc.CreateNew) { vpc = new Vpc(this, "Vpc", new VpcProps { MaxAzs = 2 }); } else { vpc = Vpc.FromLookup(this, "Vpc", new VpcLookupOptions { VpcId = settings.Vpc.VpcId }); } ICluster cluster; if (settings.ECSCluster.CreateNew) { cluster = new Cluster(this, "Cluster", new ClusterProps { Vpc = vpc, ClusterName = settings.ECSCluster.NewClusterName }); } else { cluster = Cluster.FromClusterAttributes(this, "Cluster", new ClusterAttributes { ClusterArn = settings.ECSCluster.ClusterArn, ClusterName = ECSFargateUtilities.GetClusterNameFromArn(settings.ECSCluster.ClusterArn), SecurityGroups = new ISecurityGroup[0], Vpc = vpc }); } IRole taskRole; if (settings.ApplicationIAMRole.CreateNew) { taskRole = new Role(this, "TaskRole", new RoleProps { AssumedBy = new ServicePrincipal("ecs-tasks.amazonaws.com") }); } else { taskRole = Role.FromRoleArn(this, "TaskRole", settings.ApplicationIAMRole.RoleArn, new FromRoleArnOptions { Mutable = false }); } var taskDefinition = new FargateTaskDefinition(this, "TaskDefinition", new FargateTaskDefinitionProps { TaskRole = taskRole, Cpu = settings.TaskCpu, MemoryLimitMiB = settings.TaskMemory }); var logging = new AwsLogDriver(new AwsLogDriverProps { StreamPrefix = recipeConfiguration.StackName }); var ecrRepository = Repository.FromRepositoryName(this, "ECRRepository", recipeConfiguration.ECRRepositoryName); taskDefinition.AddContainer("Container", new ContainerDefinitionOptions { Image = ContainerImage.FromEcrRepository(ecrRepository, recipeConfiguration.ECRImageTag), Logging = logging }); var fargateServiceProps = new FargateServiceProps { Cluster = cluster, TaskDefinition = taskDefinition, AssignPublicIp = settings.Vpc.IsDefault, DesiredCount = settings.DesiredCount }; if (!string.IsNullOrEmpty(settings.ECSServiceSecurityGroups)) { var ecsServiceSecurityGroups = new List <ISecurityGroup>(); var count = 1; foreach (var securityGroupId in settings.ECSServiceSecurityGroups.Split(',')) { ecsServiceSecurityGroups.Add(SecurityGroup.FromSecurityGroupId(this, $"AdditionalGroup-{count++}", securityGroupId.Trim(), new SecurityGroupImportOptions { Mutable = false })); } fargateServiceProps.SecurityGroups = ecsServiceSecurityGroups.ToArray(); } new FargateService(this, "FargateService", fargateServiceProps); }
public ApiStack(Construct parent, string id, IApiStackProps props) : base(parent, id, props) { var cluster = new Cluster( this, "Example", new ClusterProps { Vpc = props.Vpc, }); var logging = new AwsLogDriver(new AwsLogDriverProps { StreamPrefix = "Example", }); var taskDef = new FargateTaskDefinition( this, "Task", new FargateTaskDefinitionProps { MemoryLimitMiB = 512, Cpu = 256, }); var repo = Repository.FromRepositoryName( this, "EcrRepository", props.Repository.RepositoryName); var imageTag = new CfnParameter( this, props.ApiImageTag, new CfnParameterProps { Default = "latest", }); var container = new ContainerDefinition( this, "ApiContainer", new ContainerDefinitionProps { TaskDefinition = taskDef, Image = ContainerImage.FromEcrRepository(repo, imageTag.ValueAsString), Logging = logging, }); container.AddPortMappings(new PortMapping { ContainerPort = 80, HostPort = 80, Protocol = Amazon.CDK.AWS.ECS.Protocol.TCP, }); var loadBalancer = new ApplicationLoadBalancer( this, "LoadBalancer", new ApplicationLoadBalancerProps { Vpc = props.Vpc, Http2Enabled = false, IdleTimeout = Duration.Seconds(5), InternetFacing = true, IpAddressType = IpAddressType.IPV4, VpcSubnets = new SubnetSelection { Subnets = props.Vpc.PublicSubnets, }, }); var ecsService = new ApplicationLoadBalancedFargateService( this, "Service", new ApplicationLoadBalancedFargateServiceProps { Cluster = cluster, TaskDefinition = taskDef, AssignPublicIp = false, PublicLoadBalancer = true, LoadBalancer = loadBalancer, }); PrintLoadBalancerDnsName(ecsService); }