Пример #1
0
        internal NetworkStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
        {
            //UsingLevel2Constructs();
            var vpc = new CfnVPC(this, Program.PREFIX + "primary-vpc", new CfnVPCProps {
                CidrBlock = "10.20.0.0/16"
            });

            vpc.Tags.SetTag(Program.NAME, Program.PREFIX + "primary-vpc");
            VpcRef = vpc.Ref;

            //var vpcId = (string)this.Node.TryGetContext(Program.PREFIX + "primary-vpc");
            var L1Vpc = Vpc.FromLookup(this, "VPC", new VpcLookupOptions
            {
                VpcName = Program.PREFIX + "primary-vpc"
            });

            /*var L1VPC = Vpc.FromLookup(this, VpcRef, new VpcLookupOptions{
             *  VpcId = VpcRef
             * });*/

            var privateSubnetA = new CfnSubnet(this, Program.PREFIX + "private-subnet-a", new CfnSubnetProps {
                CidrBlock = "10.20.0.0/24", AvailabilityZone = this.AvailabilityZones[0], VpcId = vpc.Ref
            });

            privateSubnetA.Tags.SetTag(Program.NAME, Program.PREFIX + "private-subnet-a");

            var privateSubnetB = new CfnSubnet(this, Program.PREFIX + "private-subnet-b", new CfnSubnetProps {
                CidrBlock = "10.20.1.0/24", AvailabilityZone = this.AvailabilityZones[1], VpcId = vpc.Ref
            });

            privateSubnetB.Tags.SetTag(Program.NAME, Program.PREFIX + "private-subnet-b");
        }
Пример #2
0
        internal Stack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
        {
            //setup the image
            var asset = new DockerImageAsset(this, $"{Config.AppName}Image", new DockerImageAssetProps {
                Directory = Path.Combine(System.Environment.CurrentDirectory, "api"),
            });

            //Create the Fargate service
            var vpc = Vpc.FromLookup(
                this, "sandbox", new VpcLookupOptions
            {
                VpcName = "sandbox_vpc"
            }
                );

            var cluster = new Cluster(this, $"{Config.AppName}Cluster", new ClusterProps
            {
                Vpc = vpc
            });

            var applicationDomain = $"{Config.ApplicationSubdomain}.{Config.DomainName}";
            var hostedZone        = HostedZone.FromLookup(
                this, "HostedZone", new HostedZoneProviderProps
            {
                DomainName  = $"{Config.DomainName}.",
                PrivateZone = false
            }
                );

            // Create a load-balanced Fargate service and make it public
            var fargateService = new ApplicationLoadBalancedFargateService(this, $"{Config.AppName}Service",
                                                                           new ApplicationLoadBalancedFargateServiceProps
            {
                Cluster          = cluster,     // Required
                DesiredCount     = 1,           // Default is 1
                TaskImageOptions = new ApplicationLoadBalancedTaskImageOptions
                {
                    Image = ContainerImage.FromDockerImageAsset(asset)
                },
                MemoryLimitMiB     = 1024,      // Default is 256
                PublicLoadBalancer = true,      // Default is false
                DomainName         = applicationDomain,
                DomainZone         = hostedZone,
            }
                                                                           );

            new CfnOutput(
                this, "Route53Url", new CfnOutputProps
            {
                Value       = applicationDomain,
                Description = "Nice Route53 Url"
            }
                );
        }
Пример #3
0
        private IVpc findVpcByVpcId(string vpcId)
        {
            // How to import existing VPC
            // https://qiita.com/kai_kou/items/e35fd8c6af7dff9f2624
            // see difference of fromLookup and fromVpcAttributes
            // https://garbe.io/blog/2019/09/20/hey-cdk-how-to-use-existing-resources/
            var vpc = Vpc.FromLookup(this, "ExistingVPC", new VpcLookupOptions()
            {
                VpcId = vpcId
            });

            return(vpc);
        }
Пример #4
0
        public static Cluster CreateCluster(Construct scope)
        {
            var vpc = Vpc.FromLookup(scope, "MyVPC", new VpcLookupOptions()
            {
                VpcId = "vpc-00b85526a33fa6e93"
            });

            return(new Cluster(scope, "DownloadAccuzipFilesCluster", new ClusterProps
            {
                ClusterName = Config.FARGATE_CLUSTER_NAME,
                Vpc = vpc
            }));
        }
Пример #5
0
 internal IVpc AddVpc(string id, PingPongNetworkProps props)
 {
     if (props.UseExistingVpc)
     {
         System.Console.WriteLine($"Using VPC = {props.ExistingVpcName}");
         return(Vpc.FromLookup(this, $"{id}-vpc", new VpcLookupOptions()
         {
             VpcName = props.ExistingVpcName
         }));
     }
     else
     {
         return(new Vpc(this, $"{id}-vpc", new VpcProps
         {
         }));
     }
 }
Пример #6
0
        public ContainersStack(Construct parent, string id, IStackProps props) : base(parent, id, props)
        {
            var vpc = Vpc.FromLookup(this, id = "DefaultVpc", new VpcLookupOptions
            {
                IsDefault = true
            });

            if (vpc == null)
            {
                throw new System.NullReferenceException($"Unable to determine default VPC in region {this.Region}");
            }

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

            var taskDef = new FargateTaskDefinition(this, "FargateTaskDefinition");

            var currentDir = Directory.GetCurrentDirectory();
            var path       = Path.GetFullPath(Path.Combine(currentDir, @"dotnetapp/"));

            var containerOptions = new ContainerDefinitionOptions
            {
                Image = ContainerImage.FromAsset("dotnetapp")
            };

            var portMapping = new PortMapping()
            {
                ContainerPort = 80,
                HostPort      = 80
            };

            taskDef.AddContainer("Container", containerOptions).AddPortMappings(portMapping);

            var serviceProps = new ApplicationLoadBalancedFargateServiceProps()
            {
                MemoryLimitMiB = 512,
                Cpu            = 256,
                TaskDefinition = taskDef
            };

            ApplicationLoadBalancedFargateService service
                = new ApplicationLoadBalancedFargateService(this, "DotnetFargateApp", serviceProps);
        }
Пример #7
0
        internal AuroraDatabaseStack(Construct scope, string id, AuroraDatabaseStackProps props)
            : base(scope, id, props)
        {
            var defaultVpc = Vpc.FromLookup(this, "default", new VpcLookupOptions
            {
                IsDefault = true
            });

            var securityGroup = new SecurityGroup(this, "aurora-sg", new SecurityGroupProps
            {
                AllowAllOutbound = true,
                Description      = "Primary Aurora Serverless SG.  Used by Lambdas",
                Vpc = defaultVpc
            });

            securityGroup.AddIngressRule(securityGroup, Port.AllTraffic());

            new CfnDBCluster(this, "aurora-cluster", new CfnDBClusterProps
            {
                Engine               = "aurora",
                EngineMode           = "serverless",
                Port                 = 3306,
                MasterUsername       = "******",
                MasterUserPassword   = "******",
                DeletionProtection   = false,
                StorageEncrypted     = true,
                VpcSecurityGroupIds  = new string[] { securityGroup.SecurityGroupId },
                ScalingConfiguration = new ScalingConfigurationProperty
                {
                    AutoPause             = true,
                    MinCapacity           = 1,
                    MaxCapacity           = 1,
                    SecondsUntilAutoPause = 300
                }
            });

            new BastionHostLinux(this, "bastion-host", new BastionHostLinuxProps
            {
                Vpc           = defaultVpc,
                SecurityGroup = securityGroup
            });
        }
Пример #8
0
        public IVpc Locate(string identification, string vpcId, bool isDefault = true)
        {
            if (string.IsNullOrEmpty(vpcId))
            {
                throw new ArgumentException("The VPC id cannot be null ");
            }

            var result = Vpc.FromLookup(Scope, string.IsNullOrEmpty(identification) ? $"{ApplicationName}{EnvironmentName}vpc" : identification, new VpcLookupOptions
            {
                IsDefault = isDefault,
                VpcId     = vpcId
            });

            if (result == null)
            {
                throw new ArgumentException($"The provided vpcId {vpcId} does not exists");
            }

            return(result);
        }
Пример #9
0
        public AppStack(Construct parent, string id, IStackProps props) : base(parent, id, props)
        {
            var cluster = new Cluster(this, "AppCluster", new ClusterProps
            {
                Vpc = Vpc.FromLookup(this, "DefaultVpc", new VpcLookupOptions()
                {
                    IsDefault = true
                }),
            });

            new ApplicationLoadBalancedFargateService(this, "AppService",
                                                      new ApplicationLoadBalancedFargateServiceProps
            {
                Cluster          = cluster,
                DesiredCount     = 1,
                TaskImageOptions = new ApplicationLoadBalancedTaskImageOptions
                {
                    Image = ContainerImage.FromAsset(DockerFolderBuilder.GetBuildFolder(), new AssetImageProps()
                    {
                        File = Path.Combine("DockerProject1", "Dockerfile")
                    }),
                    TaskRole = new Role(this, "AppRole", new RoleProps()
                    {
                        RoleName        = "AppRole",
                        AssumedBy       = new ServicePrincipal("ecs-tasks.amazonaws.com"),
                        ManagedPolicies = new IManagedPolicy[]
                        {
                            ManagedPolicy.FromAwsManagedPolicyName("TranslateFullAccess"),
                            ManagedPolicy.FromAwsManagedPolicyName("AmazonS3FullAccess"),
                        }
                    })
                },
                MemoryLimitMiB     = 2048,      // Default is 256
                PublicLoadBalancer = true,      // Default is false
                AssignPublicIp     = true,
            }
                                                      );
        }
Пример #10
0
 private void ConfigureVpc(Configuration settings)
 {
     if (settings.Vpc.IsDefault)
     {
         AppVpc = Vpc.FromLookup(this, nameof(AppVpc), new VpcLookupOptions
         {
             IsDefault = true
         });
     }
     else if (settings.Vpc.CreateNew)
     {
         AppVpc = new Vpc(this, nameof(AppVpc), InvokeCustomizeCDKPropsEvent(nameof(AppVpc), this, new VpcProps
         {
             MaxAzs = 2
         }));
     }
     else
     {
         AppVpc = Vpc.FromLookup(this, nameof(AppVpc), new VpcLookupOptions
         {
             VpcId = settings.Vpc.VpcId
         });
     }
 }
Пример #11
0
        public IvrStack(Construct scope, string stackId, StackProps stackProps, IvrSiteSchema schema, IEnumerable <SecurityGroupRule> securityGroupRules) : base(scope, stackId, stackProps)
        {
            IVpc vpc             = null;
            var  MaxIpsPerSubnet = IvrVpcProps.MaxIpsPerSubnet;

            if (!string.IsNullOrWhiteSpace(schema.VpcName))
            {
                vpc = Vpc.FromLookup(this, "$VPC", new VpcLookupOptions {
                    VpcName = schema.VpcName,
                });                                                                                     // will error if not found
                //MaxIpsPerSubnet = ???;
            }
            else if (!string.IsNullOrWhiteSpace(schema.VpcId))
            {
                vpc = Vpc.FromLookup(this, "$VPC", new VpcLookupOptions {
                    VpcId = schema.VpcId,
                });                                                                                 // will error if not found
                //MaxIpsPerSubnet = ???;
            }
            else if (null != schema.VpcProps)
            {
                // use provided props to create brand new VPC
                vpc = new IvrVpc(this, $"VPC", schema.VpcProps);
            }

            if (schema.AddVpcS3Gateway)
            {
                var s3gw = new GatewayVpcEndpoint(this, $"S3GW", new GatewayVpcEndpointProps
                {
                    Vpc     = vpc,
                    Service = GatewayVpcEndpointAwsService.S3,
                    Subnets = new SubnetSelection[] { new SubnetSelection {
                                                          SubnetType = SubnetType.PUBLIC,
                                                      } },
                });
            }

            var role = new Role(this, "IVR", new RoleProps
            {
                AssumedBy      = new ServicePrincipal("ec2.amazonaws.com"),
                InlinePolicies = new IvrInlinePolicies(stackProps.Env.Account, stackId, schema),
            });

            // Configure inbound security for RDP (and more?)
            var securityGroup = new SecurityGroup(this, $"Ingress", new SecurityGroupProps
            {
                Vpc = vpc,
                AllowAllOutbound = schema.AllowAllOutbound,
            });

            securityGroupRules.ForEach(rule => securityGroup.WithSecurityGroupRule(rule));
            if (schema.AllowAllIntranet)
            {
                securityGroup.WithSecurityGroupRule(new IngressRule(Peer.Ipv4($"{vpc.VpcCidrBlock}"), Port.AllTraffic()).WithDescription($"All intranet traffic"));
            }

            // Finally - create our instances!
            var hosts = new List <HostInstance>();

            for (var subnetIndex = 0; ++subnetIndex <= Math.Min(vpc.PublicSubnets.Length, schema.MaxSubnets);)
            {
                var hostIndexInSubnet = 0;
                foreach (var group in schema.HostGroups)
                {
                    var numberOfHosts = Math.Min(group.HostCount, MaxIpsPerSubnet);
                    if (numberOfHosts != group.HostCount)
                    {
                        Console.WriteLine($"Group({group.Name}) host count changed from {group.HostCount} to {numberOfHosts}");
                        group.HostCount = numberOfHosts;
                    }
                    var instanceProps = IvrInstanceProps.InstanceProps(vpc, vpc.PublicSubnets[subnetIndex - 1], role, securityGroup, group.InstanceProps);
                    for (var hostCount = 0; ++hostCount <= numberOfHosts; ++hostIndexInSubnet)
                    {
                        var hostName         = $"{schema.HostNamePrefix}{subnetIndex}{hostIndexInSubnet:00}";
                        var hostPrimingProps = new HostPrimingProps
                        {
                            HostName           = hostName.AsWindowsComputerName(), // must fit into 15 chars
                            WorkingFolder      = $"{stackId}".AsWindowsFolder(),
                            AwsAccount         = stackProps.Env.Account,
                            AwsRoleName        = role.RoleName,
                            RdpProps           = schema.RdpProps,
                            EC2Users           = schema.EC2Users,
                            DownloadAndInstall = group.DownloadAndInstall,
                            S3iArgs            = $"{group.InstallS3i} --verbose",
                        };
                        var hostCommands = HostPriming.PrimeForS3i(hostPrimingProps)
                                           .WithFirewallAllowInbound($"{vpc.VpcCidrBlock}");
                        hostCommands.WithRenameAndRestart(hostPrimingProps.HostName);
                        instanceProps.KeyName  = schema.KeyPairName;
                        instanceProps.UserData = hostCommands.UserData;
                        hosts.Add(new HostInstance
                        {
                            Group    = group,
                            Instance = new Instance_(this, hostName.AsCloudFormationId(), instanceProps),
                        });
                    }
                }
            }
            // associate pre-allocated EIPs
            var preAllocatedEIPs    = schema.PreAllocatedElasticIPs?.SelectMany(s => s.Csv()).ToList() ?? new List <string> {
            };
            var hostsThatRequireEIP = hosts.Where(h => h.Group.UsePreAllocatedElasticIPs).ToList();

            if (preAllocatedEIPs.Count < hostsThatRequireEIP.Count)
            {
                throw new ArgumentException($"Pre-Allocated Elastic IPs needed: {hostsThatRequireEIP.Count()}, but only {preAllocatedEIPs.Count()} configured in schema.{nameof(IvrSiteSchema.PreAllocatedElasticIPs)}");
            }
            var elasticIPAssociations = hostsThatRequireEIP.Zip(preAllocatedEIPs, (h, a) =>
            {
                return(new CfnEIPAssociation(this, $"EIPA{h.Instance.InstancePrivateIp}".AsCloudFormationId(), new CfnEIPAssociationProps
                {
                    AllocationId = a,
                    InstanceId = h.Instance.InstanceId,
                }));
            }).ToList();    // execute LINQ now

            // We have schema.Domain registered in advance
            if (!string.IsNullOrWhiteSpace(schema.HostedZoneDomain))
            {
                var theZone = HostedZone.FromLookup(this, $"{stackId}_Zone_", new HostedZoneProviderProps
                {
                    DomainName = schema.HostedZoneDomain,
                    //Comment = "HostedZone created by Route53 Registrar",
                });
                // assign new Elastic IPs as needed
                if (!string.IsNullOrWhiteSpace(schema.SubdomainEIPs))
                {
                    var newElasticIPs = hosts.Where(h => h.Group.AllocateNewElasticIPs).Select(h =>
                    {
                        return(new CfnEIP(this, $"EIP{h.Instance.InstancePrivateIp}".AsCloudFormationId(), new CfnEIPProps
                        {
                            // 'standard' or 'vpc': https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-eip.html#cfn-ec2-eip-domain
                            Domain = "vpc",
                            InstanceId = h.Instance.InstanceId,
                        }));
                    }).ToList();   // collect them now to prevent LINQ side effects
                    if (newElasticIPs.Any())
                    {
                        // Register public Elastic IPs
                        var arNewPublic = new ARecord(this, $"ARecord_Public_NewAlloc".AsCloudFormationId(), new ARecordProps
                        {
                            Zone       = theZone,
                            RecordName = $"{schema.SubdomainEIPs}.{theZone.ZoneName}",
                            Target     = RecordTarget.FromValues(newElasticIPs.Select(eip => eip.Ref).ToArray()),
                            Ttl        = Duration.Seconds(300),
                        });
                    }
                    else if (elasticIPAssociations.Any())
                    {
                        // Register public Elastic IPs

                        /*
                         * var arPrePublic = new ARecord(this, $"ARecord_Public_PreAlloc".AsCloudFormationId(), new ARecordProps
                         * {
                         *  Zone = theZone,
                         *  RecordName = $"{schema.SubdomainEIPs}.{theZone.ZoneName}",
                         *  Target = RecordTarget.FromValues(elasticIPAssociations.Select(eipa => eipa.Ref).ToArray()), // ***** how to do that?
                         *  Ttl = Duration.Seconds(300),
                         * });
                         */
                        foreach (var a in elasticIPAssociations)
                        {
                            Console.WriteLine($"Pre-Allocated Elastic IP Associations: {a.AllocationId}/{a.InstanceId}, {a.Eip}/{a.PrivateIpAddress}, {a.Ref} - please put it to {schema.SubdomainEIPs}.{theZone.ZoneName} ARecord manually");
                        }
                    }
                }
                if (0 < hosts.Count && !string.IsNullOrWhiteSpace(schema.SubdomainHosts))
                {
                    // Register private IPs (never changing, as opposed to public - which change on stop/start) addresses of all hosts
                    var arPrivate = new ARecord(this, $"ARecord_Private_".AsCloudFormationId(), new ARecordProps
                    {
                        Zone       = theZone,
                        RecordName = $"{schema.SubdomainHosts}.{theZone.ZoneName}",
                        Target     = RecordTarget.FromIpAddresses(hosts.Select(h => h.Instance.InstancePrivateIp).ToArray()),
                        Ttl        = Duration.Seconds(300),
                    });
                }
                //throw new Exception();
            }
        }
Пример #12
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
            });
        }
Пример #13
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()
            });
        }
Пример #14
0
        public DevStack(Construct parent, string id, IStackProps props) : base(parent, id, props)
        {
            var cluster = new Cluster(this, "AppCluster", new ClusterProps
            {
                Vpc = Vpc.FromLookup(this, "DefaultVpc", new VpcLookupOptions()
                {
                    IsDefault = true
                }),
            });

            FargateTaskDefinition taskDef = new FargateTaskDefinition(this, "DevStackTaskDef", new FargateTaskDefinitionProps()
            {
            });

            var mysqlContainer = taskDef.AddContainer("mysql", new ContainerDefinitionProps()
            {
                Image = ContainerImage.FromAsset(DockerFolderBuilder.GetBuildFolder(), new AssetImageProps()
                {
                    File = Path.Combine("LocalStack", "Dockerfile.mysql")
                })
            });

            mysqlContainer.AddPortMappings(new PortMapping()
            {
                HostPort      = 3306,
                ContainerPort = 3306,
                Protocol      = Amazon.CDK.AWS.ECS.Protocol.TCP
            });

            var mongoContainer = taskDef.AddContainer("mongodb", new ContainerDefinitionProps()
            {
                Image = ContainerImage.FromAsset(DockerFolderBuilder.GetBuildFolder(), new AssetImageProps()
                {
                    File = Path.Combine("LocalStack", "Dockerfile.mongo")
                })
            });

            mongoContainer.AddPortMappings(new PortMapping()
            {
                HostPort      = 27017,
                ContainerPort = 27017,
                Protocol      = Amazon.CDK.AWS.ECS.Protocol.TCP
            });

            var localStackContainer = taskDef.AddContainer("localstack", new ContainerDefinitionProps()
            {
                Image = ContainerImage.FromAsset(DockerFolderBuilder.GetBuildFolder(), new AssetImageProps()
                {
                    File = Path.Combine("LocalStack", "Dockerfile.localstack")
                })
            });

            localStackContainer.AddPortMappings(new PortMapping()
            {
                HostPort      = 4572,
                ContainerPort = 4572,
                Protocol      = Amazon.CDK.AWS.ECS.Protocol.TCP
            });
            localStackContainer.AddPortMappings(new PortMapping()
            {
                HostPort      = 4576,
                ContainerPort = 4576,
                Protocol      = Amazon.CDK.AWS.ECS.Protocol.TCP
            });
            localStackContainer.AddPortMappings(new PortMapping()
            {
                HostPort      = 4584,
                ContainerPort = 4584,
                Protocol      = Amazon.CDK.AWS.ECS.Protocol.TCP
            });

            var schemabuilder = taskDef.AddContainer("schemaBuilder", new ContainerDefinitionProps()
            {
                Image = ContainerImage.FromAsset(DockerFolderBuilder.GetBuildFolder(), new AssetImageProps()
                {
                    File = Path.Combine("LocalStack", "Dockerfile")
                })
            });

            schemabuilder.AddContainerDependencies(new ContainerDependency[] {
                new ContainerDependency()
                {
                    Container = mysqlContainer,
                    Condition = ContainerDependencyCondition.START
                },
                new ContainerDependency()
                {
                    Container = mongoContainer,
                    Condition = ContainerDependencyCondition.START
                },
                new ContainerDependency()
                {
                    Container = localStackContainer,
                    Condition = ContainerDependencyCondition.START
                }
            });

            // Create a load-balanced Fargate service and make it public
            new ApplicationLoadBalancedFargateService(this, "DevStackService",
                                                      new ApplicationLoadBalancedFargateServiceProps
            {
                Cluster            = cluster,   // Required
                DesiredCount       = 1,
                TaskDefinition     = taskDef,
                MemoryLimitMiB     = 2048,      // Default is 256
                PublicLoadBalancer = true,      // Default is false
                AssignPublicIp     = true
            }
                                                      );
        }
Пример #15
0
        internal StepFunctionDemoStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
        {
            Bucket stepFunctionDemoBucket = new Bucket(this, "StepFunctionDemoBucket", new BucketProps
            {
                Encryption    = BucketEncryption.S3_MANAGED,
                RemovalPolicy = RemovalPolicy.RETAIN
            });

            Table stepFunctionDemoTable = new Table(this, "StepFunctionDemoTable", new TableProps {
                BillingMode  = BillingMode.PROVISIONED,
                PartitionKey = new Amazon.CDK.AWS.DynamoDB.Attribute
                {
                    Name = "Id",
                    Type = AttributeType.STRING
                },
                RemovalPolicy = RemovalPolicy.DESTROY
            });

            //Step Function invoking Lambda function
            Function invokeOddEvenStepFunction = new Function(this, "InvokeOddEvenStepFunction", new FunctionProps
            {
                Runtime     = Runtime.DOTNET_CORE_3_1,
                Code        = Code.FromAsset("src/Demo.Services.Lambda/bin/Release/netcoreapp3.1/Demo.Services.Lambda.zip"),
                Handler     = "Demo.Services.Lambda::Demo.Services.Lambda.Functions::InvokeOddEvenStepFunction",
                Timeout     = Duration.Minutes(5),
                MemorySize  = 512,
                Description = "Lambda Function that invokes the Demo Step Function",
            });


            //Function to calculate Odd or Even
            Function oddOrEvenFunction = new Function(this, "OddOrEvenFunction", new FunctionProps
            {
                Runtime     = Runtime.DOTNET_CORE_3_1,
                Code        = Code.FromAsset("src/Demo.Services.Lambda/bin/Release/netcoreapp3.1/Demo.Services.Lambda.zip"),
                Handler     = "Demo.Services.Lambda::Demo.Services.Lambda.Functions::OddOrEvenFunction",
                Timeout     = Duration.Minutes(5),
                MemorySize  = 512,
                Description = "Lambda Function that calculates odd or even",
            });

            //Demo Lambda to perform Process 1
            Function process1Function = new Function(this, "Process1Function", new FunctionProps
            {
                Runtime     = Runtime.DOTNET_CORE_3_1,
                Code        = Code.FromAsset("src/Demo.Services.Lambda/bin/Release/netcoreapp3.1/Demo.Services.Lambda.zip"),
                Handler     = "Demo.Services.Lambda::Demo.Services.Lambda.Functions::Process1Function",
                Timeout     = Duration.Minutes(5),
                MemorySize  = 512,
                Description = "Demo Lambda Function that runs process1",
            });

            Function processAFunction = new Function(this, "ProcessAFunction", new FunctionProps
            {
                Runtime     = Runtime.DOTNET_CORE_3_1,
                Code        = Code.FromAsset("src/Demo.Services.Lambda/bin/Release/netcoreapp3.1/Demo.Services.Lambda.zip"),
                Handler     = "Demo.Services.Lambda::Demo.Services.Lambda.Functions::Process1Function",
                Timeout     = Duration.Minutes(5),
                MemorySize  = 512,
                Description = "Demo Lambda Function that runs process1",
            });

            //Demo Lambda to perform Process 2
            Function process2Function = new Function(this, "Process2Function", new FunctionProps
            {
                Runtime     = Runtime.DOTNET_CORE_3_1,
                Code        = Code.FromAsset("src/Demo.Services.Lambda/bin/Release/netcoreapp3.1/Demo.Services.Lambda.zip"),
                Handler     = "Demo.Services.Lambda::Demo.Services.Lambda.Functions::Process2Function",
                Timeout     = Duration.Minutes(5),
                MemorySize  = 512,
                Description = "Demo Lambda Function that runs process2",
            });

            //Demo Lambda to perform Process 1
            Function process11Function = new Function(this, "Process11Function", new FunctionProps
            {
                Runtime     = Runtime.DOTNET_CORE_3_1,
                Code        = Code.FromAsset("src/Demo.Services.Lambda/bin/Release/netcoreapp3.1/Demo.Services.Lambda.zip"),
                Handler     = "Demo.Services.Lambda::Demo.Services.Lambda.Functions::Process11Function",
                Timeout     = Duration.Minutes(5),
                MemorySize  = 512,
                Description = "Demo Lambda Function that runs job process1",
            });

            //Demo Lambda to perform Process 2
            Function process12Function = new Function(this, "Process12Function", new FunctionProps
            {
                Runtime     = Runtime.DOTNET_CORE_3_1,
                Code        = Code.FromAsset("src/Demo.Services.Lambda/bin/Release/netcoreapp3.1/Demo.Services.Lambda.zip"),
                Handler     = "Demo.Services.Lambda::Demo.Services.Lambda.Functions::Process12Function",
                Timeout     = Duration.Minutes(5),
                MemorySize  = 512,
                Description = "Demo Lambda Function that runs job process2",
            });

            Function taskTokenExecutorFunction = new Function(this, "TaskTokenExecutorFunction", new FunctionProps
            {
                Runtime     = Runtime.DOTNET_CORE_3_1,
                Code        = Code.FromAsset("src/Demo.Services.Lambda/bin/Release/netcoreapp3.1/Demo.Services.Lambda.zip"),
                Handler     = "Demo.Services.Lambda::Demo.Services.Lambda.Functions::TaskTokenExecutor",
                Timeout     = Duration.Minutes(5),
                MemorySize  = 512,
                Description = "Demo Lambda Function that executes Task Token Step",
                Environment = new Dictionary <string, string>()
                {
                    ["STEP_FUNCTION_DEMO_BUCKET"] = stepFunctionDemoBucket.BucketName
                }
            });

            stepFunctionDemoBucket.GrantReadWrite(taskTokenExecutorFunction);


            var oddEvenFunction = new Task(this, "OddEvenFunction", new TaskProps
            {
                Task = new InvokeFunction(oddOrEvenFunction.LatestVersion)
            });


            var process1 = new Task(this, "Process1", new TaskProps
            {
                Task = new InvokeFunction(process1Function.LatestVersion)
            });

            var processA = new Task(this, "ProcessA", new TaskProps
            {
                Task = new InvokeFunction(processAFunction.LatestVersion)
            });


            var process2 = new Task(this, "Process2", new TaskProps
            {
                Task = new InvokeFunction(process2Function.LatestVersion)
            });

            var process11 = new Task(this, "Process11", new TaskProps
            {
                Task       = new InvokeFunction(process11Function.LatestVersion),
                ResultPath = "$.Resolved"
            });

            var process12 = new Task(this, "Process12", new TaskProps
            {
                Task = new InvokeFunction(process12Function.LatestVersion)
            });

            var taskTokenExecutor = new Task(this, "TaskTokenExecutor", new TaskProps
            {
                Task = new RunLambdaTask(taskTokenExecutorFunction.LatestVersion, new RunLambdaTaskProps()
                {
                    IntegrationPattern = ServiceIntegrationPattern.WAIT_FOR_TASK_TOKEN,
                    Payload            = TaskInput.FromContextAt("$$.Task.Token")
                }),
                Parameters = new Dictionary <string, object>
                {
                    ["Payload"] = new Dictionary <string, object>
                    {
                        ["TaskToken.$"] = "$$.Task.Token",
                        ["State.$"]     = "$"
                    }
                }
            });


            //Choice to go to Process 1 or Process 2 based on input number is odd or even.
            var isEven = new Choice(this, "Is the number Even?");
            var isResolvedOrOverriden = new Choice(this, "Is Resolved Or Overriden?");

            //var chain1 = Chain.Start(oddEvenFunction)
            //    .Next(isEven
            //            .When(
            //                Condition.StringEquals("$.Result", "Even"),
            //                Chain.Start(process1)
            //                    .Next(process11)
            //                    .Next(isResolvedOrOverriden
            //                        .When(
            //                            Condition.Or(
            //                                new[]
            //                                {
            //                                    Condition.BooleanEquals("$.Resolved", true),
            //                                    Condition.BooleanEquals("$.Override", true)
            //                                }), process12)
            //                        .Otherwise(process2)))
            //            .When(Condition.StringEquals("$.Result", "Odd"), process2));

            var chain1 = Chain.Start(oddEvenFunction)
                         .Next(isEven
                               .When(
                                   Condition.StringEquals("$.Result", "Even"),
                                   Chain.Start(process1)
                                   .Next(taskTokenExecutor)
                                   .Next(isResolvedOrOverriden
                                         .When(
                                             Condition.Or(
                                                 new[]
            {
                Condition.BooleanEquals("$.Resolved", true),
                Condition.BooleanEquals("$.Override", true)
            }), process12)
                                         .Otherwise(process2)))
                               .When(Condition.StringEquals("$.Result", "Odd"), process2));


            //State Machine

            var stateMachine = new StateMachine(this, "JobDemoStateMachine", new StateMachineProps
            {
                StateMachineName = "JobDemoStateMachine",
                Timeout          = Duration.Minutes(5),
                Definition       = chain1
            });

            stateMachine.Role?.AddManagedPolicy(ManagedPolicy.FromManagedPolicyArn(this, "DynamoDBFullAccessForStepFunction", "arn:aws:iam::aws:policy/AmazonDynamoDBFullAccess"));

            stateMachine.Role?.AddManagedPolicy(ManagedPolicy.FromManagedPolicyArn(this, "LambdaFullAccessForStepFunction", "arn:aws:iam::aws:policy/AWSLambdaFullAccess"));

            var demofargateTask1 = new FargateTaskDefinition(this,
                                                             "demoECSTask1Definition", new FargateTaskDefinitionProps
            {
                MemoryLimitMiB = 4096,
                Cpu            = 2048
            });
            var demofargateTask2 = new FargateTaskDefinition(this,
                                                             "demoECSTask2Definition", new FargateTaskDefinitionProps
            {
                MemoryLimitMiB = 4096,
                Cpu            = 2048
            });

            stepFunctionDemoBucket.GrantReadWrite(demofargateTask2.TaskRole);

            IVpc publicVpc = Vpc.FromLookup(this, "PublicVPC", new VpcLookupOptions
            {
                Tags = new Dictionary <string, string>
                {
                    ["Paces:VpcType"] = "Public"
                }
            });
            var cluster = Cluster.FromClusterAttributes(this, "PublicCluster", new ClusterAttributes
            {
                ClusterName    = "OHC-PACES",
                Vpc            = publicVpc,
                SecurityGroups = new[]
                { SecurityGroup.FromSecurityGroupId(this, "SecurityGroup", "sg-0a1bab8166d8fb715") }
            });

            var container1 = demofargateTask1.AddContainer("app", new ContainerDefinitionOptions
            {
                Image = ContainerImage.FromAsset(".", new AssetImageProps
                {
                    File = "Dockerfile"
                }),
                Logging = LogDriver.AwsLogs(new AwsLogDriverProps
                {
                    LogGroup = new LogGroup(this, "demoECSTask1LogGroup", new LogGroupProps
                    {
                        LogGroupName = "/ecs/demoECSTask1-" + RandomString.Generate(10, StackId),
                    }),
                    StreamPrefix = "logs"
                }),
            });


            var container2 = demofargateTask2.AddContainer("app", new ContainerDefinitionOptions
            {
                Image = ContainerImage.FromAsset(".", new AssetImageProps
                {
                    File = "Dockerfile.1"
                }),
                Environment = new Dictionary <string, string>
                {
                    ["STEP_FUNCTION_DEMO_BUCKET"] = stepFunctionDemoBucket.BucketName
                },
                Logging = LogDriver.AwsLogs(new AwsLogDriverProps
                {
                    LogGroup = new LogGroup(this, "demoECSTask2LogGroup", new LogGroupProps
                    {
                        LogGroupName = $"/ecs/demoECSTask2-{RandomString.Generate(10, StackId)}",
                    }),
                    StreamPrefix = "logs"
                })
            });


            Rule rule = new Rule(this, "DemoJobRule", new RuleProps
            {
                Schedule = Schedule.Cron(new CronOptions
                {
                    Day    = "*",
                    Hour   = "*",
                    Minute = "1",
                    Month  = "*",
                    Year   = "*"
                }),
                Description = "Runs demo job fargate task",
                Targets     = new IRuleTarget[]
                {
                    new EcsTask(
                        new EcsTaskProps
                    {
                        Cluster         = cluster,
                        TaskDefinition  = demofargateTask2,
                        SubnetSelection = new SubnetSelection
                        {
                            OnePerAz = true
                        }
                    })
                }
            });



            //var ecsTask1 = new Task(this, "ecsTask1", new TaskProps
            //{
            //    InputPath = "$",
            //    Task = new CustomTask(new RunEcsFargateTaskProps
            //    {

            //        Cluster = Cluster.FromClusterAttributes(this, "PublicCluster", new ClusterAttributes
            //        {
            //            ClusterName = "OHC-PACES",
            //            Vpc = publicVpc,
            //            SecurityGroups = new[] { SecurityGroup.FromSecurityGroupId(this, "SecurityGroup", "sg-0a1bab8166d8fb715") }
            //        }),
            //        TaskDefinition = fargateTask1,

            //        ContainerOverrides = new[]
            //        {
            //            new ContainerOverride
            //            {
            //               ContainerDefinition = container,
            //               Command = new []{"$.Data"}
            //            },

            //        }
            //    })
            //});

            var ecsTask1 = new Task(this, "EcsTask1", new TaskProps
            {
                InputPath = "$",
                Task      = new RunEcsFargateTask(new RunEcsFargateTaskProps
                {
                    Cluster        = cluster,
                    TaskDefinition = demofargateTask1,

                    //ContainerOverrides = new[]
                    //{
                    //    new ContainerOverride
                    //    {
                    //        ContainerDefinition = container,
                    //
                    //    },

                    //}
                }),
                Parameters = new Dictionary <string, object>
                {
                    ["Overrides"] = new Dictionary <string, object>
                    {
                        ["ContainerOverrides"] = new Dictionary <string, string>[]
                        {
                            new Dictionary <string, string> {
                                ["Name"]      = "app",
                                ["Command.$"] = "$.ECSPayload"
                            }
                        }
                    }
                }
            });

            var chain2 = Chain.Start(processA).Next(ecsTask1);


            var stateMachineWithTask = new StateMachine(this, "JobDemoStateMachine-1", new StateMachineProps
            {
                StateMachineName = "JobDemoStateMachine-1",
                Timeout          = Duration.Minutes(15),
                Definition       = chain2,
                Role             = Role.FromRoleArn(this, "StateMachineWithTaskRole",
                                                    "arn:aws:iam::342600918501:role/service-role/PacesEdi274DefaultStateMachineRole")
            });

            //All Policies
            // 1. Invoke function policies

            invokeOddEvenStepFunction.Role?.AddManagedPolicy(ManagedPolicy.FromManagedPolicyArn(this, "InvokeLambdaPolicy", "arn:aws:iam::aws:policy/AWSLambdaFullAccess"));

            var policyStatement = new PolicyStatement
            {
                Sid    = "CanInvokeStepFunctions",
                Effect = Effect.ALLOW
            };

            policyStatement.AddActions(new[] { "states:StartExecution" });

            invokeOddEvenStepFunction.AddToRolePolicy(policyStatement);
            policyStatement.AddResources(stateMachine.StateMachineArn);
            invokeOddEvenStepFunction.AddEnvironment(Functions.StateMachineArnKey, stateMachine.StateMachineArn);

            process12Function.AddEnvironment(Functions.StepFunctionDemoBucketKey, stepFunctionDemoBucket.BucketName);

            stepFunctionDemoBucket.GrantReadWrite(process12Function);


            var policyStatementDemofargateTask2 = new PolicyStatement
            {
                Sid    = "CanNotifyStepFunction",
                Effect = Effect.ALLOW
            };

            policyStatementDemofargateTask2.AddActions(new[] { "states:SendTask*" });
            demofargateTask2.AddToExecutionRolePolicy(policyStatementDemofargateTask2);
            demofargateTask2.AddToTaskRolePolicy(policyStatementDemofargateTask2);

            policyStatementDemofargateTask2.AddAllResources();
        }