Beispiel #1
0
 public void ToStringTest()
 {
     Assert.AreEqual("ALL TRAFFIC", Port.AllTraffic().ToString());
     Assert.AreEqual("ALL PORTS", Port.AllTcp().ToString());
     Assert.AreEqual("UDP ALL PORTS", Port.AllUdp().ToString());
     Assert.AreEqual("2000-3000", Port.TcpRange(2000, 3000).ToString());
     Assert.AreEqual("2000", Port.Tcp(2000).ToString());
     Assert.AreEqual("2000-3000", Port.TcpRange(2000, 3000).ToString());
     Assert.AreEqual("UDP 2000", Port.Udp(2000).ToString());
     Assert.AreEqual("UDP 2000-3000", Port.UdpRange(2000, 3000).ToString());
 }
Beispiel #2
0
        public static Port Parse(string s, int p1 = 0, int p2 = 0)
        {
            var fields = s.Split(' ', StringSplitOptions.RemoveEmptyEntries);

            if (1 == fields.Length)
            {
                return(ParseRange(fields[0], (p) => Port.Tcp(p), (b, e) => Port.TcpRange(b, e), p1, p2));
            }
            else if (2 <= fields.Length)
            {
                switch (fields[0].ToUpper())
                {
                case "UDP":
                    if (3 == fields.Length && "ALL" == fields[1].ToUpper() && "PORTS" == fields[2].ToUpper())
                    {
                        return(Port.AllUdp());
                    }
                    return(ParseRange(fields[1], (p) => Port.Udp(p), (b, e) => Port.UdpRange(b, e), p1, p2));

                case "ICMP":
                    if ("TYPE" == fields[1].ToUpper())
                    {
                        switch (fields.Length)
                        {
                        case 3:
                            return(Port.IcmpType(0 < p1 ? p1 : int.Parse(fields[2])));

                        case 5:
                            if ("CODE" == fields[3].ToUpper())
                            {
                                return(Port.IcmpTypeAndCode(0 < p1 ? p1 : int.Parse(fields[2]), 0 < p2 ? p2 : int.Parse(fields[4])));
                            }
                            break;
                        }
                    }
                    break;

                case "ALL":
                    switch (fields[1].ToUpper())
                    {
                    case "TRAFFIC": return(Port.AllTraffic());

                    case "PORTS": return(Port.AllTcp());
                    }
                    break;
                }
            }
            throw new FormatException($"Can't parse Port: '{s}'");
        }
        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
            });
        }
        internal TargetInstanceStack(Construct scope, string id, Vpc vpc, string keyPairName, IStackProps props = null) : base(scope, id, props)
        {
            SecurityGroup = new SecurityGroup(this, "TargetInstance-Security-Group", new SecurityGroupProps
            {
                Vpc = vpc,
                AllowAllOutbound  = true,
                Description       = "TargetInstance-Security-Group",
                SecurityGroupName = "secgroup-" + id
            });


            Role = new Role(this, "ec2-targetinstance-role", new RoleProps
            {
                AssumedBy = new ServicePrincipal("ec2.amazonaws.com")
            });

            Role.AddManagedPolicy(ManagedPolicy.FromAwsManagedPolicyName("SecretsManagerReadWrite"));

            TargetInstance = new Instance_(this, id, new InstanceProps
            {
                InstanceType = InstanceType.Of(InstanceClass.BURSTABLE3, InstanceSize.MICRO),
                MachineImage = new WindowsImage(WindowsVersion.WINDOWS_SERVER_2019_ENGLISH_FULL_BASE),
                Vpc          = vpc,
                UserData     = UserData.Custom(Utils.GetResource("target_instance_user_data.ps1")),
                KeyName      = keyPairName,
                Role         = Role,
                VpcSubnets   = new SubnetSelection {
                    SubnetType = SubnetType.PRIVATE
                },
                SecurityGroup = SecurityGroup
            });

            SecurityGroup.AddIngressRule(Peer.AnyIpv4(), Port.AllTraffic(), "Allow all trafic in. In production - change this!");

            new CfnOutput(this, "target-instance", new CfnOutputProps {
                Value = TargetInstance.InstancePrivateIp
            });
        }
Beispiel #5
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();
            }
        }