예제 #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 static FargateTaskDefinition CreateTaskDefinition1(Construct scope)
        {
            var repo = CreateDockerContainerImage(scope);

            var taskDefinition = new FargateTaskDefinition(scope, "DownloadAccuzipFileTaskDefinition", new FargateTaskDefinitionProps()
            {
                MemoryLimitMiB = 2048,
            });

            taskDefinition.AddContainer(Config.ECR_REPO_NAME, new ContainerDefinitionProps()
            {
                MemoryLimitMiB = 2048,
                Image          = ContainerImage.FromEcrRepository(repo),
                Logging        = new AwsLogDriver(new AwsLogDriverProps()
                {
                    StreamPrefix = "dmappresort"
                })
            });



            var policyStatement = new Amazon.CDK.AWS.IAM.PolicyStatement();

            policyStatement.AddAllResources();
            policyStatement.AddActions(new string[] { "s3:*" });
            taskDefinition.AddToTaskRolePolicy(policyStatement);


            return(taskDefinition);
        }
        internal CdkFargateStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
        {
            var vpc = new Vpc(this, "SatellytesVpc", new VpcProps
            {
                Cidr   = "10.0.0.0/16",
                MaxAzs = 1,
                SubnetConfiguration = new[] {
                    new SubnetConfiguration()
                    {
                        Name       = "Satellytes/public",
                        SubnetType = SubnetType.PUBLIC,
                    }
                },
            });

            var cluster = new Cluster(this, "SatellytesCluster", new ClusterProps
            {
                Vpc = vpc,
            });

            var taskDefinition = new TaskDefinition(this, "SatellytesWebTask", new TaskDefinitionProps {
                TaskRole = Role.FromRoleArn(this, "taskRole", "arn:aws:iam::576853867587:role/ecsTaskExecutionRole", new FromRoleArnOptions()
                {
                    Mutable = false
                }),
                ExecutionRole = Role.FromRoleArn(this, "taskExecutionRole", "arn:aws:iam::576853867587:role/ecsTaskExecutionRole", new FromRoleArnOptions()
                {
                    Mutable = false
                }),
                Compatibility = Compatibility.FARGATE,
                Cpu           = "256",
                MemoryMiB     = "512",
            });

            var inboundSecurityGrp = new SecurityGroup(this, "satellytesSecurityGrpInboundInet", new SecurityGroupProps {
                Vpc = vpc
            });

            inboundSecurityGrp.AddIngressRule(Peer.AnyIpv4(), Port.Tcp(8080), "inbound http");



            taskDefinition.AddContainer("satellytesWebImage", new ContainerDefinitionProps {
                Image = ContainerImage.FromEcrRepository(Repository.FromRepositoryName(this, "repo", "satellytes-website/backend"), "1cfb651f73fcd20895fc44c06f7bb180ca0e8322"),
            });

            new FargateService(this, "SatellytesWebService", new FargateServiceProps {
                Cluster        = cluster,
                TaskDefinition = taskDefinition,
                VpcSubnets     = new SubnetSelection {
                    SubnetType = SubnetType.PUBLIC
                },
                AssignPublicIp = true,
            });
        }
        private void CreateContainerDefinition(EcsTaskDefinitionOptions definitionOptions, TaskDefinition taskDefinition)
        {
            foreach (var containerDef in definitionOptions.Containers)
            {
                var ecr = StackResources.EcrRepositories.FirstOrDefault(ecr => ecr.Key == containerDef.RepositoryId);

                if (ecr.Key == null || ecr.Value == null)
                {
                    throw new ArgumentException("Please add a ECR definition option properly set up on your json configuration. No task definition could not be added.");
                }

                var portMapping = new List <PortMapping>();
                if (containerDef.TCPPortMapping?.Any() == true)
                {
                    foreach (var ports in containerDef.TCPPortMapping)
                    {
                        portMapping.Add(new PortMapping
                        {
                            ContainerPort = ports.ContainerPort,
                            HostPort      = ports.HostPort,
                            Protocol      = Amazon.CDK.AWS.ECS.Protocol.TCP
                        });
                    }
                }

                var containerDefinitionProps = new ContainerDefinitionProps
                {
                    TaskDefinition = taskDefinition,
                    Image          = ContainerImage.FromEcrRepository(ecr.Value, containerDef.ImageTag),
                    MemoryLimitMiB = containerDef.MemoryLimitMiB,
                    Cpu            = containerDef.CpuUnits,
                    StartTimeout   = Duration.Minutes(containerDef.StartTimeOutMinutes),
                    PortMappings   = portMapping.ToArray(),
                    Environment    = containerDef.EnvironmentVariables,
                    DnsServers     = containerDef.DnsServers?.ToArray()
                };

                var container = AwsCdkHandler.CreateContainerDefinitionByProps(containerDef.Id, containerDefinitionProps);

                if (definitionOptions.MountPoints?.Any() == true)
                {
                    var mountPoints = new List <MountPoint>();
                    foreach (var mountPointOption in definitionOptions.MountPoints)
                    {
                        mountPoints.Add(new MountPoint
                        {
                            SourceVolume  = mountPointOption.SourceVolume,
                            ContainerPath = mountPointOption.ContainerPath
                        });
                    }
                    container.AddMountPoints(mountPoints.ToArray());
                }
            }
        }
        internal MyDotNetCoreServerlessWebAppEcsFargateCdkAppStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
        {
            var         imageTagParameter = this.Node.TryGetContext("ImageTag");
            string      imageTag          = imageTagParameter.ToString() ?? "latest";
            IRepository ecrRepository     = Repository.FromRepositoryArn(this, "MyDotNetCorServerlessWebAppServiceContainerRepository", "arn:aws:ecr:eu-west-1:098208531922:repository/mydotnetcorewebapp");

            var loadBalancedFargateService = new ApplicationLoadBalancedFargateService(this, "MyDotNetCorServerlessWebAppService", new ApplicationLoadBalancedFargateServiceProps()
            {
                AssignPublicIp   = true,
                TaskImageOptions = new ApplicationLoadBalancedTaskImageOptions()
                {
                    Image = ContainerImage.FromEcrRepository(ecrRepository, imageTag),
                }
            });;
        }
        private ApplicationLoadBalancedFargateService CreateEcsService(
            Cluster ecsCluster,
            Secret dbPasswordSecret,
            DatabaseConstructFactory dbConstructFactory,
            DatabaseConstructOutput dbConstructOutput
            )
        {
            var imageRepository = Repository.FromRepositoryName(this, "ExistingEcrRepository", settings.DockerImageRepository);

            var ecsService = new ApplicationLoadBalancedFargateService(this, $"{settings.ScopeName}FargateService",
                                                                       new ApplicationLoadBalancedFargateServiceProps
            {
                Cluster            = ecsCluster,
                DesiredCount       = settings.DesiredComputeReplicaCount,
                Cpu                = settings.CpuMillicores,
                MemoryLimitMiB     = settings.MemoryMiB,
                PublicLoadBalancer = settings.PublicLoadBalancer,
                LoadBalancer       = new ApplicationLoadBalancer(this, $"{settings.ScopeName}-ALB", new ApplicationLoadBalancerProps {
                    LoadBalancerName = "unicorn-store",
                    Vpc                = ecsCluster.Vpc,
                    InternetFacing     = true,
                    DeletionProtection = false,
                }),
                TaskImageOptions = new ApplicationLoadBalancedTaskImageOptions
                {
                    Image       = ContainerImage.FromEcrRepository(imageRepository, settings.ImageTag),
                    Environment = new Dictionary <string, string>()
                    {
                        { "ASPNETCORE_ENVIRONMENT", settings.DotNetEnvironment ?? "Production" },
                        { "DefaultAdminUsername", settings.DefaultSiteAdminUsername },
                        { $"UnicornDbConnectionStringBuilder__{dbConstructFactory.DbConnStrBuilderServerPropName}",
                          dbConstructOutput.EndpointAddress },
                        { $"UnicornDbConnectionStringBuilder__Port", dbConstructOutput.Port },
                        { $"UnicornDbConnectionStringBuilder__{dbConstructFactory.DBConnStrBuilderUserPropName}",
                          settings.DbUsername },
                    },
                    Secrets = new Dictionary <string, Secret>
                    {
                        { "DefaultAdminPassword", Helpers.CreateAutoGenPasswordSecretDef($"{settings.ScopeName}DefaultSiteAdminPassword").CreateSecret(this) },
                        { $"UnicornDbConnectionStringBuilder__{dbConstructFactory.DBConnStrBuilderPasswordPropName}", dbPasswordSecret }
                    }
                },
            }
                                                                       );

            return(ecsService);
        }
예제 #7
0
        private ApplicationLoadBalancedEc2Service CreateService(Cluster cluster)
        {
            var repository = Repository.FromRepositoryAttributes(this, "dev-api-repo", new RepositoryAttributes
            {
                RepositoryName = "app-repo",
                RepositoryArn  = "arn:aws:ecr:us-east-1:714871639201:repository/app-repo",
            });

            return(new ApplicationLoadBalancedEc2Service(this, "dev-ecs-service",
                                                         new ApplicationLoadBalancedEc2ServiceProps()
            {
                ServiceName = "dev-crud-api-service",
                Cluster = cluster,
                DesiredCount = 1,
                TaskImageOptions = new ApplicationLoadBalancedTaskImageOptions
                {
                    Image = ContainerImage.FromEcrRepository(repository, "latest"),
                },
                MemoryLimitMiB = 256,
                PublicLoadBalancer = true,
            }));
        }
예제 #8
0
        public ApiStack(Construct scope, string id, ApiProps props = null) : base(scope, id, props)
        {
            var hostedZone = HostedZone.FromHostedZoneAttributes(this, "HostedZone", new HostedZoneAttributes
            {
                ZoneName     = props.HostedZoneName,
                HostedZoneId = props.HostedZoneId
            });

            FargateService = new ApplicationLoadBalancedFargateService(this, $"{props.ServiceName}-fargate-service", new ApplicationLoadBalancedFargateServiceProps
            {
                ServiceName      = props.ServiceName,
                Cluster          = props.EcsCluster,
                TaskImageOptions = new ApplicationLoadBalancedTaskImageOptions
                {
                    ContainerName = props.ServiceName,
                    Image         = ContainerImage.FromEcrRepository(props.EcrRepository),
                    Environment   = props.ContainerEnvVars,
                    Secrets       = props.ContainerSecrets,
                    EnableLogging = true
                },
                Certificate = props.Certificate,
                DomainName  = $"{props.SubDomain}.{props.HostedZoneName}",
                DomainZone  = hostedZone,
                //this has an internet-facing ALB open to the world - could enhance security by hiding behind an API gateway
            });

            FargateService.TargetGroup.ConfigureHealthCheck(new HealthCheck
            {
                Path = "/health"
            });

            ApiUrl = $"https://{props.SubDomain}.{props.HostedZoneName}";

            //seems handy https://github.com/aws/aws-cdk/issues/8352
            //also handy https://chekkan.com/iam-policy-perm-for-public-load-balanced-ecs-fargate-on-cdk/
        }
        public EcsStack(Construct parent, string id, EcsStackProps props) : base(parent, id)
        {
            this.ecsCluster = new Cluster(this, "Cluster", new ClusterProps
            {
                Vpc = props.Vpc,
            });
            this.ecsCluster.Connections.AllowFromAnyIpv4(Port.Tcp(8080));
            Console.Write(props.ecrRepository.RepositoryArn);
            this.ecsService = new NetworkLoadBalancedFargateService(this, "Service", new NetworkLoadBalancedFargateServiceProps()
            {
                Cluster            = this.ecsCluster,
                DesiredCount       = 1,
                PublicLoadBalancer = true,
                TaskImageOptions   = new NetworkLoadBalancedTaskImageOptions
                {
                    EnableLogging = true,
                    ContainerPort = 8080,
                    Image         = ContainerImage.FromEcrRepository(props.ecrRepository),
                }
            }
                                                                    );
            this.ecsService.Service.Connections.AllowFrom(Peer.Ipv4(props.Vpc.VpcCidrBlock), Port.Tcp(8080));

            var taskDefinitionPolicy = new PolicyStatement();

            taskDefinitionPolicy.AddActions(
                // Rules which allow ECS to attach network interfaces to instances
                // on your behalf in order for awsvpc networking mode to work right
                "ec2:AttachNetworkInterface",
                "ec2:CreateNetworkInterface",
                "ec2:CreateNetworkInterfacePermission",
                "ec2:DeleteNetworkInterface",
                "ec2:DeleteNetworkInterfacePermission",
                "ec2:Describe*",
                "ec2:DetachNetworkInterface",

                // Rules which allow ECS to update load balancers on your behalf
                //  with the information sabout how to send traffic to your containers
                "elasticloadbalancing:DeregisterInstancesFromLoadBalancer",
                "elasticloadbalancing:DeregisterTargets",
                "elasticloadbalancing:Describe*",
                "elasticloadbalancing:RegisterInstancesWithLoadBalancer",
                "elasticloadbalancing:RegisterTargets",

                //  Rules which allow ECS to run tasks that have IAM roles assigned to them.
                "iam:PassRole",

                //  Rules that let ECS create and push logs to CloudWatch.
                "logs:DescribeLogStreams",
                "logs:CreateLogGroup");
            taskDefinitionPolicy.AddAllResources();

            this.ecsService.Service.TaskDefinition.AddToExecutionRolePolicy(
                taskDefinitionPolicy
                );

            var taskRolePolicy = new PolicyStatement();

            taskRolePolicy.AddActions(
                // Allow the ECS Tasks to download images from ECR
                "ecr:GetAuthorizationToken",
                "ecr:BatchCheckLayerAvailability",
                "ecr:GetDownloadUrlForLayer",
                "ecr:BatchGetImage",
                // Allow the ECS tasks to upload logs to CloudWatch
                "logs:CreateLogStream",
                "logs:CreateLogGroup",
                "logs:PutLogEvents"
                );
            taskRolePolicy.AddAllResources();

            this.ecsService.Service.TaskDefinition.AddToTaskRolePolicy(
                taskRolePolicy
                );
        }
예제 #10
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
            });
        }
예제 #11
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 ecrRepository = Repository.FromRepositoryName(this, "ECRRepository", recipeConfiguration.ECRRepositoryName);
            var container     = taskDefinition.AddContainer("Container", new ContainerDefinitionOptions
            {
                Image = ContainerImage.FromEcrRepository(ecrRepository, recipeConfiguration.ECRImageTag)
            });

            container.AddPortMappings(new PortMapping
            {
                ContainerPort = 80,
                Protocol      = Protocol.TCP
            });

            var ecsLoadBalancerAccessSecurityGroup = new SecurityGroup(this, "WebAccessSecurityGroup", new SecurityGroupProps
            {
                Vpc = vpc,
                SecurityGroupName = $"{recipeConfiguration.StackName}-ECSService"
            });

            var ecsServiceSecurityGroups = new List <ISecurityGroup>();

            ecsServiceSecurityGroups.Add(ecsLoadBalancerAccessSecurityGroup);

            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
                    }));
                }
            }

            new ApplicationLoadBalancedFargateService(this, "FargateService", new ApplicationLoadBalancedFargateServiceProps
            {
                Cluster        = cluster,
                TaskDefinition = taskDefinition,
                DesiredCount   = settings.DesiredCount,
                ServiceName    = settings.ECSServiceName,
                AssignPublicIp = settings.Vpc.IsDefault,
                SecurityGroups = ecsServiceSecurityGroups.ToArray()
            });
        }
예제 #12
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()
            }));
        }
예제 #13
0
        public static Amazon.CDK.AWS.StepFunctions.Tasks.EcsRunTask CreateTask(Construct scope, Table presortTable)
        {
            var environmentCID = Amazon.CDK.AWS.SSM.StringParameter.ValueFromLookup(scope, Config.PARAMETER_STORE_AWS_ACCOUNTID_CICD);

            var repo = new Amazon.CDK.AWS.ECR.Repository(scope, "ECRRepo", new Amazon.CDK.AWS.ECR.RepositoryProps()
            {
                RemovalPolicy  = RemovalPolicy.DESTROY,
                RepositoryName = Config.ECR_REPO_NAME
            });

            repo.AddToResourcePolicy(new Amazon.CDK.AWS.IAM.PolicyStatement(new Amazon.CDK.AWS.IAM.PolicyStatementProps
            {
                Effect     = Amazon.CDK.AWS.IAM.Effect.ALLOW,
                Actions    = new string[] { "ecr:*" },
                Principals = new Amazon.CDK.AWS.IAM.IPrincipal[]
                {
                    new Amazon.CDK.AWS.IAM.ArnPrincipal("arn:aws:iam::" + environmentCID + ":root")
                }
            }));


            var taskDefinition = new FargateTaskDefinition(scope, "DownloadAccuzipFileTaskDefinition", new FargateTaskDefinitionProps()
            {
                Cpu            = 4096,
                MemoryLimitMiB = 8192,
            });

            var containerDefinition = taskDefinition.AddContainer(Config.ECR_REPO_NAME + "1", new ContainerDefinitionProps()
            {
                Cpu            = 4096,
                MemoryLimitMiB = 8192,
                Image          = ContainerImage.FromEcrRepository(repo),
                Logging        = new AwsLogDriver(new AwsLogDriverProps()
                {
                    StreamPrefix = "dmappresort"
                })
            });


            var policyStatement = new Amazon.CDK.AWS.IAM.PolicyStatement();

            policyStatement.AddAllResources();
            policyStatement.AddActions(new string[] { "dynamoDb:*", "ses:*", "s3:*" });
            taskDefinition.AddToTaskRolePolicy(policyStatement);



            var cluster = CreateCluster(scope);


            var lstEnviron = new List <TaskEnvironmentVariable>();

            //lstEnviron.Add(new TaskEnvironmentVariable
            //{
            //    Name = "accuzipFileS3key",
            //    Value = JsonPath.StringAt("$.accuzipFileS3key")
            //});

            //lstEnviron.Add(new TaskEnvironmentVariable
            //{
            //    Name = "beforeReduceFileS3Key",
            //    Value = JsonPath.StringAt("$.beforeReduceFileS3Key")
            //});


            //lstEnviron.Add(new TaskEnvironmentVariable
            //{
            //    Name = "bucketName",
            //    Value = JsonPath.StringAt("$.bucketName")
            //});

            //lstEnviron.Add(new TaskEnvironmentVariable
            //{
            //    Name = "apiKey",
            //    Value = JsonPath.StringAt("$.apiKey")
            //});

            lstEnviron.Add(new TaskEnvironmentVariable
            {
                Name  = "REQUESTID",
                Value = JsonPath.StringAt("$.requestId")
            });

            lstEnviron.Add(new TaskEnvironmentVariable
            {
                Name  = "DYNAMO_TABLE",
                Value = presortTable.TableName
            });



            return(new EcsRunTask(scope, "FileMergeFargate", new EcsRunTaskProps()
            {
                LaunchTarget = new EcsFargateLaunchTarget(),
                AssignPublicIp = true,
                IntegrationPattern = IntegrationPattern.RUN_JOB,
                Cluster = cluster,
                TaskDefinition = taskDefinition,
                ContainerOverrides = (new List <ContainerOverride>
                {
                    new ContainerOverride
                    {
                        ContainerDefinition = containerDefinition,
                        Environment = lstEnviron.ToArray()
                    }
                }).ToArray()
            }));
        }
예제 #14
0
        private void ConfigureAppRunnerService(IRecipeProps <Configuration> props)
        {
            if (ServiceAccessRole == null)
            {
                throw new InvalidOperationException($"{nameof(ServiceAccessRole)} has not been set. The {nameof(ConfigureIAMRoles)} method should be called before {nameof(ConfigureAppRunnerService)}");
            }
            if (TaskRole == null)
            {
                throw new InvalidOperationException($"{nameof(TaskRole)} has not been set. The {nameof(ConfigureIAMRoles)} method should be called before {nameof(ConfigureAppRunnerService)}");
            }

            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);

            Configuration settings             = props.Settings;
            var           appRunnerServiceProp = new CfnServiceProps
            {
                ServiceName         = settings.ServiceName,
                SourceConfiguration = new CfnService.SourceConfigurationProperty
                {
                    AuthenticationConfiguration = new CfnService.AuthenticationConfigurationProperty
                    {
                        AccessRoleArn = ServiceAccessRole.RoleArn
                    },
                    ImageRepository = new CfnService.ImageRepositoryProperty
                    {
                        ImageRepositoryType = "ECR",
                        ImageIdentifier     = ContainerImage.FromEcrRepository(ecrRepository, props.ECRImageTag).ImageName,
                        ImageConfiguration  = new CfnService.ImageConfigurationProperty
                        {
                            Port         = settings.Port.ToString(),
                            StartCommand = !string.IsNullOrWhiteSpace(settings.StartCommand) ? settings.StartCommand : null
                        }
                    }
                }
            };

            if (!string.IsNullOrEmpty(settings.EncryptionKmsKey))
            {
                var encryptionConfig = new CfnService.EncryptionConfigurationProperty();
                appRunnerServiceProp.EncryptionConfiguration = encryptionConfig;

                encryptionConfig.KmsKey = settings.EncryptionKmsKey;
            }

            var healthCheckConfig = new CfnService.HealthCheckConfigurationProperty();

            appRunnerServiceProp.HealthCheckConfiguration = healthCheckConfig;

            healthCheckConfig.HealthyThreshold   = settings.HealthCheckHealthyThreshold;
            healthCheckConfig.Interval           = settings.HealthCheckInterval;
            healthCheckConfig.Protocol           = settings.HealthCheckProtocol;
            healthCheckConfig.Timeout            = settings.HealthCheckTimeout;
            healthCheckConfig.UnhealthyThreshold = settings.HealthCheckUnhealthyThreshold;

            if (string.Equals(healthCheckConfig.Protocol, "HTTP"))
            {
                healthCheckConfig.Path = string.IsNullOrEmpty(settings.HealthCheckPath) ? "/" : settings.HealthCheckPath;
            }

            var instanceConfig = new CfnService.InstanceConfigurationProperty();

            appRunnerServiceProp.InstanceConfiguration = instanceConfig;


            instanceConfig.InstanceRoleArn = TaskRole.RoleArn;

            instanceConfig.Cpu    = settings.Cpu;
            instanceConfig.Memory = settings.Memory;

            AppRunnerService = new CfnService(this, nameof(AppRunnerService), InvokeCustomizeCDKPropsEvent(nameof(AppRunnerService), this, appRunnerServiceProp));

            var output = new CfnOutput(this, "EndpointURL", new CfnOutputProps
            {
                Value = $"https://{AppRunnerService.AttrServiceUrl}/"
            });
        }
예제 #15
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);
        }
        internal UsersServiceFargateStack(Construct scope, string id, IUsersServiceFargateStackProps props) : base(scope, id, props)
        {
            var repository = Repository.FromRepositoryName(this, "UsersRepository", "users-service");


            var taskDefinition = new FargateTaskDefinition(this, "UsersServiceTaskDef", new FargateTaskDefinitionProps
            {
                Cpu            = 256,
                MemoryLimitMiB = 512
            });

            var container = taskDefinition.AddContainer("WebApi", new ContainerDefinitionOptions
            {
                Image   = ContainerImage.FromEcrRepository(repository),
                Logging = new AwsLogDriver(new AwsLogDriverProps
                {
                    LogRetention = Amazon.CDK.AWS.Logs.RetentionDays.TWO_WEEKS,
                    StreamPrefix = "UsersService-"
                })
            });

            container.AddPortMappings(new PortMapping
            {
                ContainerPort = 80
            });

            var service = new FargateService(this, "UsersService", new FargateServiceProps
            {
                Cluster        = props.Cluster,
                TaskDefinition = taskDefinition,
                DesiredCount   = 2,
                VpcSubnets     = new SubnetSelection
                {
                    SubnetType = SubnetType.PUBLIC
                },
                AssignPublicIp = true
            });

            service.AutoScaleTaskCount(new EnableScalingProps
            {
                MinCapacity = 2,
                MaxCapacity = 4
            }).ScaleOnCpuUtilization("CPU", new CpuUtilizationScalingProps
            {
                TargetUtilizationPercent = 70
            });

            props.Listener.AddTargets("UsersServiceTarget", new AddApplicationTargetsProps
            {
                HealthCheck = new HealthCheck
                {
                    HealthyHttpCodes        = "200-299",
                    Path                    = "/api/users/health",
                    Protocol                = Amazon.CDK.AWS.ElasticLoadBalancingV2.Protocol.HTTP,
                    HealthyThresholdCount   = 2,
                    UnhealthyThresholdCount = 5,
                    Timeout                 = Duration.Seconds(10),
                    Interval                = Duration.Seconds(70),
                    Port                    = "80"
                },
                Protocol    = ApplicationProtocol.HTTP,
                Port        = 80,
                Targets     = new IApplicationLoadBalancerTarget[] { service },
                PathPattern = "/api/users*",
                Priority    = 2
            });
        }