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, }); }
public static SecurityGroup CreateHttpHttps(Constructs.Construct construct, Vpc vpc, string name, string description, IPeer[] peers = null) { // create the security groups var sg = CreateHostSG(construct, vpc, name, description); // add the rules if (peers == null || peers.Length == 0) { var source = Peer.AnyIpv4(); peers = new[] { source }; } foreach (var peer in peers) { var http = new Port(Utils.Ports.GetPortProps(80, 80, "http")); var https = new Port(Utils.Ports.GetPortProps(443, 443, "https")); sg.AddIngressRule(peer, http, "ipv4-http"); sg.AddIngressRule(peer, https, "ipv4-https"); } return(sg); }
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 }); }
internal InfraStack(Construct scope, string id, CustomStackProps props = null) : base(scope, id, props) { var vpc = props.Vpc; var cluster = new Cluster(this, "Cluster", new ClusterProps { Vpc = vpc, ClusterName = Globals.GetDeployEnvironment(this).PutEnvNamePrefixWithDash("Cluster") }); var albSecurityGroup = new SecurityGroup(this, "AlbSecurityGroup", new SecurityGroupProps { Vpc = vpc, AllowAllOutbound = true }); albSecurityGroup.AddIngressRule(Peer.AnyIpv4(), Port.Tcp(80)); var alb = new ApplicationLoadBalancer(this, "ALB", new ApplicationLoadBalancerProps { Vpc = vpc, InternetFacing = true, Http2Enabled = true, IdleTimeout = Duration.Seconds(60), IpAddressType = IpAddressType.IPV4, SecurityGroup = albSecurityGroup }); var webApiServiceSecurityGroup = new SecurityGroup(this, "WebApiServiceSecurityGroup", new SecurityGroupProps { Vpc = vpc, AllowAllOutbound = true }); webApiServiceSecurityGroup.AddIngressRule(albSecurityGroup, Port.Tcp(80)); var appListener = alb.AddListener("AppListener", new BaseApplicationListenerProps { Port = 80, Protocol = ApplicationProtocol.HTTP, DefaultAction = ListenerAction.FixedResponse(404, new FixedResponseOptions { ContentType = "text/plain", MessageBody = "This is not here..." }) }); new CfnOutput(this, "ClusterName", new CfnOutputProps { ExportName = Globals.GetDeployEnvironment(this).PutEnvNamePrefixWithDash("ClusterName"), Value = cluster.ClusterName }); new CfnOutput(this, "WebApiServiceSecurityGroupId", new CfnOutputProps { ExportName = Globals.GetDeployEnvironment(this).PutEnvNamePrefixWithDash("WebApiServiceSecurityGroupId"), Value = albSecurityGroup.SecurityGroupId }); new CfnOutput(this, "AppListenerArn", new CfnOutputProps { ExportName = Globals.GetDeployEnvironment(this).PutEnvNamePrefixWithDash("AppListenerArn"), Value = appListener.ListenerArn }); }
private (FargateService, Amazon.CDK.AWS.ServiceDiscovery.IService) CreateService(string id, string serviceName, string branch, IVpc vpc, Cluster cluster, PrivateDnsNamespace cloudMapNamespace, string appMeshVirtualNodeName, Mesh mesh, IRole taskExecutionRole, RepositoryImage envoyImage, ContainerImage containerImage) { var taskDefinition = new TaskDefinition(this, $"{id}_{serviceName}-{branch}-task-definiton", new TaskDefinitionProps { Compatibility = Compatibility.FARGATE, MemoryMiB = "512", Cpu = "256", ProxyConfiguration = new AppMeshProxyConfiguration(new AppMeshProxyConfigurationConfigProps() { ContainerName = "envoy", Properties = new AppMeshProxyConfigurationProps() { AppPorts = new double[1] { 5000 }, ProxyIngressPort = 15000, ProxyEgressPort = 15001, IgnoredUID = 1337, EgressIgnoredIPs = new string[2] { "169.254.170.2", "169.254.169.254" } } }), Family = $"{id}_{serviceName}-task-definition", ExecutionRole = taskExecutionRole }); var envoyContainer = taskDefinition.AddContainer("envoy", new ContainerDefinitionOptions { User = "******", Image = envoyImage, Essential = true, Environment = new Dictionary <string, string> { { "APPMESH_VIRTUAL_NODE_NAME", $"mesh/{mesh.MeshName}/virtualNode/{appMeshVirtualNodeName}" } }, HealthCheck = new Amazon.CDK.AWS.ECS.HealthCheck() { Command = new string[] { "CMD-SHELL", "curl -s http://localhost:9901/server_info | grep state | grep -q LIVE" }, Interval = Duration.Seconds(5), Timeout = Duration.Seconds(2), StartPeriod = Duration.Seconds(10), Retries = 3 }, MemoryLimitMiB = 500, Logging = new AwsLogDriver(new AwsLogDriverProps() { StreamPrefix = $"{id}_{serviceName}-{branch}-envoy", LogRetention = RetentionDays.ONE_DAY }), }); var container = taskDefinition.AddContainer($"{serviceName}-container", new ContainerDefinitionOptions() { Image = containerImage, Logging = new AwsLogDriver(new AwsLogDriverProps() { StreamPrefix = $"{id}_{serviceName}-{branch}-service", LogRetention = RetentionDays.ONE_DAY }), Essential = true, Environment = new Dictionary <string, string> { { "BRANCH", branch }, { "APPMESH_NAMESPACE", cloudMapNamespace.PrivateDnsNamespaceName } } }); container.AddPortMappings(new Amazon.CDK.AWS.ECS.PortMapping() { ContainerPort = 5000 }); container.AddContainerDependencies(new ContainerDependency() { Condition = ContainerDependencyCondition.HEALTHY, Container = envoyContainer }); // Cloudmap will append the namespace to the dns entry in R53. // We're explicitly checking for master here because for service to service lookups to go via the envoy proxy, the DNS name must resolve. // see https://github.com/aws/aws-app-mesh-roadmap/issues/65 // i.e I want the ping service to call http://pong-service.{namespace}:5000/ and for this to be routed correctly by the proxy. // If you create the fargate task with cloudmap service integration with a more specific (branched) DNS name then pong-service.{namespace} r53 entry will never be created // and routing doesn't work through envoy. var dnsName = $"{serviceName}-service{(branch == "master" ? "" : "-" + branch)}"; var sg = new SecurityGroup(this, $"{id}_{serviceName}-{branch}-sg", new SecurityGroupProps() { AllowAllOutbound = true, SecurityGroupName = $"{id}_{serviceName}-{branch}-sg", Vpc = vpc, }); sg.AddIngressRule(Peer.AnyIpv4(), new Port(new PortProps() { Protocol = Amazon.CDK.AWS.EC2.Protocol.TCP, FromPort = 5000, ToPort = 5000, StringRepresentation = "tcp:5000:5000" }), "allow access from outside."); var fargateService = new Amazon.CDK.AWS.ECS.FargateService(this, $"{serviceName}-{branch}-service", new FargateServiceProps { ServiceName = $"{serviceName}-{branch}-service", AssignPublicIp = true, Cluster = cluster, TaskDefinition = taskDefinition, VpcSubnets = new SubnetSelection() { Subnets = vpc.PublicSubnets }, CloudMapOptions = new CloudMapOptions() { Name = dnsName, DnsRecordType = DnsRecordType.A, CloudMapNamespace = cloudMapNamespace }, SecurityGroup = sg }); return(fargateService, fargateService.CloudMapService); }