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