Ejemplo n.º 1
0
        internal ApiStack(Construct scope, string id, ApiStackProps props) : base(scope, id, props)
        {
            var securityGroup = SecurityGroup.FromSecurityGroupId(this, "aurora-sg", props.AuroraSecurityGroupId);

            var apiLambda = new Function(this, "apiLambda", new FunctionProps
            {
                Runtime        = Runtime.DOTNET_CORE_3_1,
                Handler        = "something",
                Code           = Code.FromAsset("EtlEnqueue/bin/Debug/netcoreapp3.1/publish"),
                SecurityGroups = new ISecurityGroup[] { securityGroup },
                ReservedConcurrentExecutions = 2
            });

            new LambdaRestApi(this, "apiGateway", new LambdaRestApiProps
            {
                Handler = apiLambda
            });
        }
Ejemplo n.º 2
0
        private void ConfigureService(Configuration settings)
        {
            if (EcsCluster == null)
            {
                throw new InvalidOperationException($"{nameof(EcsCluster)} has not been set. The {nameof(ConfigureCluster)} method should be called before {nameof(ConfigureService)}");
            }
            if (AppTaskDefinition == null)
            {
                throw new InvalidOperationException($"{nameof(AppTaskDefinition)} has not been set. The {nameof(ConfigureTaskDefinition)} method should be called before {nameof(ConfigureService)}");
            }

            var fargateServiceProps = new FargateServiceProps
            {
                Cluster        = EcsCluster,
                TaskDefinition = AppTaskDefinition,
                AssignPublicIp = settings.Vpc.IsDefault,
                DesiredCount   = settings.DesiredCount
            };


            if (!string.IsNullOrEmpty(settings.ECSServiceSecurityGroups))
            {
                var ecsServiceSecurityGroups = new List <ISecurityGroup>();
                var count = 1;
                foreach (var securityGroupId in settings.ECSServiceSecurityGroups.Split(','))
                {
                    ecsServiceSecurityGroups.Add(SecurityGroup.FromSecurityGroupId(this, $"AdditionalGroup-{count++}", securityGroupId.Trim(), new SecurityGroupImportOptions
                    {
                        Mutable = false
                    }));
                }

                fargateServiceProps.SecurityGroups = ecsServiceSecurityGroups.ToArray();
            }

            AppFargateService = new FargateService(this, nameof(AppFargateService), InvokeCustomizeCDKPropsEvent(nameof(AppFargateService), this, fargateServiceProps));
        }
Ejemplo n.º 3
0
        internal CreditoWebApiStack(Construct scope, string id, CustomStackProps props = null)
            : base(scope, id, props)
        {
            var vpc = props.Vpc;

            var creditoWebApiTargetGroup = new ApplicationTargetGroup(this, "CreditoWebApiTargetGroup",
                                                                      new ApplicationTargetGroupProps
            {
                Protocol            = ApplicationProtocol.HTTP,
                Port                = 80,
                Vpc                 = vpc,
                TargetType          = TargetType.IP,
                DeregistrationDelay = Duration.Seconds(60),
                HealthCheck         =
                    new Amazon.CDK.AWS.ElasticLoadBalancingV2.HealthCheck
                {
                    Enabled  = true,
                    Path     = "/api/credito/_monitor/shallow",
                    Protocol = Amazon.CDK.AWS.ElasticLoadBalancingV2.Protocol.HTTP,
                    Port     = "traffic-port",
                    UnhealthyThresholdCount = 2,
                    Interval = Duration.Seconds(60),
                    HealthyThresholdCount = 5,
                    Timeout          = Duration.Seconds(5),
                    HealthyHttpCodes = "200"
                }
            });

            var webApiServiceSecurityGroup = SecurityGroup.FromSecurityGroupId(this,
                                                                               "WebApiServiceSecurityGroup",
                                                                               Fn.ImportValue(Globals.GetDeployEnvironment(this).PutEnvNamePrefixWithDash("WebApiServiceSecurityGroupId")));

            var appListener = ApplicationListener.FromApplicationListenerAttributes(this, "AppListener",
                                                                                    new ApplicationListenerAttributes
            {
                ListenerArn   = Fn.ImportValue(Globals.GetDeployEnvironment(this).PutEnvNamePrefixWithDash("AppListenerArn")),
                SecurityGroup = webApiServiceSecurityGroup
            });

            appListener.AddTargetGroups("CreditoWebApiTargetGroup",
                                        new AddApplicationTargetGroupsProps
            {
                Conditions =
                    new ListenerCondition[]
                {
                    ListenerCondition.PathPatterns(new string[] { "/api/credito*" })
                },
                Priority     = 100,
                TargetGroups = new ApplicationTargetGroup[] { creditoWebApiTargetGroup }
            });

            var creditoWebApiLogGroup = new LogGroup(this, "CreditoWebApiContainerLogGroup",
                                                     new LogGroupProps
            {
                LogGroupName  = $"/ecs/{Globals.GetDeployEnvironment(this).EnvName}/credito/web-api",
                Retention     = RetentionDays.FIVE_DAYS,
                RemovalPolicy = RemovalPolicy.SNAPSHOT
            });

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

            var creditoWebApiLogging = new AwsLogDriver(
                new AwsLogDriverProps
            {
                StreamPrefix = "ecs",
                LogGroup     = creditoWebApiLogGroup
            });

            var creditoWebApiContainer = creditoWebApiTaskDefinition.AddContainer("CreditoWebApiContainer",
                                                                                  new ContainerDefinitionOptions
            {
                Image = ContainerImage.FromAsset(
                    Directory.GetCurrentDirectory(),
                    new AssetImageProps
                {
                    File = "src/Credito.WebApi/Dockerfile"
                }),
                Logging     = creditoWebApiLogging,
                Environment =
                    new Dictionary <string, string>()
                {
                    ["CreditoDatabase__ConnectionString"] =
                        StringParameter.ValueFromLookup(
                            this,
                            $"/{Globals.GetDeployEnvironment(this).EnvName}/credito/web-api/db/connection-string"),
                    ["CreditoDatabase__DatabaseName"] =
                        StringParameter.ValueFromLookup(
                            this,
                            $"/{Globals.GetDeployEnvironment(this).EnvName}/credito/web-api/db/database-name")
                }
            });

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

            var cluster = Cluster.FromClusterAttributes(this, "Cluster",
                                                        new ClusterAttributes
            {
                ClusterName    = Fn.ImportValue(Globals.GetDeployEnvironment(this).PutEnvNamePrefixWithDash("ClusterName")),
                Vpc            = vpc,
                SecurityGroups = new SecurityGroup[] { }
            });

            var creditoWebApiService = new FargateService(this, "CreditoWebApiService",
                                                          new FargateServiceProps
            {
                Cluster        = cluster,
                TaskDefinition = creditoWebApiTaskDefinition,
                DesiredCount   = 1,
                CircuitBreaker = new DeploymentCircuitBreaker {
                    Rollback = true
                },
                AssignPublicIp         = false,
                HealthCheckGracePeriod = Duration.Seconds(60),
                SecurityGroups         = new ISecurityGroup[] { webApiServiceSecurityGroup },
                VpcSubnets             = new SubnetSelection {
                    SubnetType = SubnetType.PRIVATE
                }
            });

            creditoWebApiService.AttachToApplicationTargetGroup(creditoWebApiTargetGroup);
        }
Ejemplo n.º 4
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()
            });
        }
Ejemplo n.º 5
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()
            }));
        }
Ejemplo n.º 6
0
        internal CensusEtlStack(Construct scope, string id, CensusEtlStackProps props) : base(scope, id, props)
        {
            var securityGroup = SecurityGroup.FromSecurityGroupId(this, "aurora-sg", props.AuroraSeucrityGroupId);

            var censusBucket           = Bucket.FromBucketName(this, "lambdaBucket", props.CensusArtifactBucket);
            var awsManagedLambdaPolicy = ManagedPolicy.FromAwsManagedPolicyName("service-role/AWSLambdaBasicExecutionRole");

            var queue = new Queue(this, "queue", new QueueProps
            {
                QueueName = props.CensusEtlQueue
            });

            new CfnOutput(this, "sqs-queue", new CfnOutputProps
            {
                ExportName = "enqueueSQS",
                Value      = queue.QueueUrl
            });

            var enqueueRole = new Role(this, "enqueue-role", new RoleProps
            {
                AssumedBy = new ServicePrincipal("lambda.amazonaws.com")
            });

            enqueueRole.AddToPolicy(new PolicyStatement(new PolicyStatementProps
            {
                Effect    = Effect.ALLOW,
                Resources = new string[] { censusBucket.BucketArn },
                Actions   = new string[] { "s3:ListBucket" }
            }));
            enqueueRole.AddToPolicy(new PolicyStatement(new PolicyStatementProps
            {
                Effect    = Effect.ALLOW,
                Resources = new string[] { queue.QueueArn },
                Actions   = new string[] { "sqs:SendMessage" }
            }));
            enqueueRole.AddManagedPolicy(awsManagedLambdaPolicy);

            new Function(this, "census-etl", new FunctionProps
            {
                Runtime        = Runtime.DOTNET_CORE_3_1,
                Handler        = "EtlEnqueue::EtlEnqueue.Function::FunctionHandler",
                Code           = Code.FromAsset("EtlEnqueue/bin/Debug/netcoreapp3.1/publish"),
                SecurityGroups = new ISecurityGroup[] { securityGroup },
                Role           = enqueueRole
            });

            var workerRole = new Role(this, "worker-role", new RoleProps
            {
                AssumedBy = new ServicePrincipal("lambda.amazonaws.com")
            });

            workerRole.AddToPolicy(new PolicyStatement(new PolicyStatementProps
            {
                Effect    = Effect.ALLOW,
                Resources = new string[] { censusBucket.BucketArn },
                Actions   = new string[] { "s3:GetObject" }
            }));
            workerRole.AddManagedPolicy(awsManagedLambdaPolicy);
            workerRole.AddToPolicy(new PolicyStatement(new PolicyStatementProps
            {
                Effect    = Effect.ALLOW,
                Resources = new string[] { queue.QueueArn },
                Actions   = new string[]
                {
                    "sqs:ReceiveMessage",
                    "sqs:DeleteMessage",
                    "sqs:GetQueueAttributes",
                    "logs:CreateLogGroup",
                    "logs:CreateLogStream",
                    "logs:PutLogEvents"
                }
            }));

            var workerFunction = new Function(this, "worker-function", new FunctionProps
            {
                Runtime        = Runtime.DOTNET_CORE_3_1,
                Handler        = "something",
                Code           = Code.FromAsset("EtlEnqueue/bin/Debug/netcoreapp3.1/publish"),
                SecurityGroups = new ISecurityGroup[] { securityGroup },
                ReservedConcurrentExecutions = 2,
                Role = workerRole
            });

            workerFunction.AddEventSource(new SqsEventSource(queue));
        }
Ejemplo n.º 7
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();
        }