예제 #1
0
        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));
        }
예제 #2
0
        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);
        }
예제 #3
0
        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);
        }
예제 #4
0
        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
            });
        }
예제 #5
0
        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()
            }));
        }
예제 #6
0
        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);
        }
예제 #7
0
        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);
        }