// Defines a new lambda resource
        public CdkWorkshopStack(Construct parent, string id, IStackProps props = null) : base(parent, id, props)
        {
            var hello = new Function(this, "HelloHandler", new FunctionProps
            {
                Runtime = Runtime.NODEJS_10_X,
                Code    = Code.FromAsset("lambda"),
                Handler = "hello.handler"
            });

            var helloWithCounter = new HitCounter(this, "HelloHitCounter", new HitCounterProps
            {
                Downstream = hello
            });

            var gateway = new LambdaRestApi(this, "Endpoint", new LambdaRestApiProps
            {
                Handler = helloWithCounter.Handler
            });

            var tv = new TableViewer(this, "ViewerHitCount", new TableViewerProps
            {
                Title = "Hello Hits",
                Table = helloWithCounter.MyTable
            });

            this.HCViewerUrl = new CfnOutput(this, "TableViewerUrl", new CfnOutputProps
            {
                Value = gateway.Url
            });

            this.HCEndpoint = new CfnOutput(this, "GatewayUrl", new CfnOutputProps
            {
                Value = gateway.Url
            });
        }
        internal CambriaBamDevOpsTalkApiStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
        {
            RestApi api = new RestApi(this, "HelloWorldAPI", new RestApiProps
            {
                RestApiName = "Hello World API",
                Description = "This API says hello!",
                DefaultCorsPreflightOptions = new CorsOptions
                {
                    AllowMethods = Cors.ALL_METHODS,
                    AllowOrigins = Cors.ALL_ORIGINS
                }
            });

            Function helloWorldFunction = new Function(this, "hello-world", new FunctionProps
            {
                Runtime = Runtime.DOTNET_CORE_2_1,
                Code    = Code.FromAsset("./lambda-src/Cambria.BAM.DevOpsTalk.Api.Lambda/bin/Release/netcoreapp2.1/Cambria.BAM.DevOpsTalk.Api.Lambda.zip"),
                Handler = "Cambria.BAM.DevOpsTalk.Api.Lambda::Cambria.BAM.DevOpsTalk.Api.Lambda.Function::Get",
                Timeout = Duration.Seconds(15)
            });

            api.Root.AddMethod("GET", new LambdaIntegration(helloWorldFunction));


            var output = new CfnOutput(this, "RootUri", new CfnOutputProps
            {
                Description = "The root URI of the API",
                Value       = api.Url
            });
        }
        public WorkshopPipelineStage(Construct scope, string id, StageProps props = null)
            : base(scope, id, props)
        {
            var service = new CdkWorkshopStack(this, "WebService");

            this.HCEndpoint  = service.HCEndpoint;
            this.HCViewerUrl = service.HCViewerUrl;
        }
        internal MdsiteStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
        {
            var mdsitebucket = new Bucket(this, "md-site-bucket", new BucketProps
            {
                Versioned = true
            });

            new BucketDeployment(this, "DeployFiles", new BucketDeploymentProps()
            {
                Sources = new[] {
                    Source.Asset("mycontent/site")
                },
                DestinationBucket = mdsitebucket
            });

            Function cfFunction = new Function(this, "append-index-html", new FunctionProps
            {
                Code = FunctionCode.FromFile(new FileCodeOptions()
                {
                    FilePath = "cloudfrontfunction/append-index-html.js"
                })
            });

            var md_distribution = new Distribution(this, "md-site-distribution", new DistributionProps()
            {
                DefaultBehavior = new BehaviorOptions
                {
                    Origin = new S3Origin(mdsitebucket),
                    FunctionAssociations = new FunctionAssociation[]
                    {
                        new FunctionAssociation {
                            Function  = cfFunction,
                            EventType = FunctionEventType.VIEWER_REQUEST
                        }
                    }
                }
            });

            this.MdSiteUrl = new CfnOutput(this, "CloudFront URL", new CfnOutputProps
            {
                Value = string.Format("https://{0}", md_distribution.DomainName)
            });
        }
        private IRepository CreateECRRepository(EcrRepositoryEntity repo)
        {
            var result = new Repository(Scope, repo.RepositoryName, new RepositoryProps
            {
                RepositoryName     = repo.RepositoryName,
                RemovalPolicy      = repo.RemovalPolicy,
                ImageTagMutability = repo.ImageTagMutability,
                ImageScanOnPush    = repo.ImageScanOnPush
            });

            var cfnOutput = new CfnOutput(Scope, $"{repo.RepositoryName}Url", new CfnOutputProps
            {
                Value = result.RepositoryUri
            });

            TagHandler.LogTag($"{ApplicationName}{EnvironmentName}{repo.RepositoryName}Url", cfnOutput);
            TagHandler.LogTag(ApplicationName + EnvironmentName + repo.RepositoryName, result);
            return(result);
        }
Exemple #6
0
        internal LambdaApiSolutionStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
        {
            DockerImageCode dockerImageCode =
                DockerImageCode.FromImageAsset("src/LambdaApiSolution.DockerFunction/src/LambdaApiSolution.DockerFunction");
            DockerImageFunction dockerImageFunction = new DockerImageFunction(this, "LambdaFunction",
                                                                              new DockerImageFunctionProps()
            {
                Code        = dockerImageCode,
                Description = ".NET 5 Docker Lambda function"
            });
            HttpApi httpApi = new HttpApi(this, "APIGatewayForLambda", new HttpApiProps()
            {
                ApiName            = "APIGatewayForLambda",
                CreateDefaultStage = true,
                CorsPreflight      = new CorsPreflightOptions()
                {
                    AllowMethods = new[] { HttpMethod.GET },
                    AllowOrigins = new[] { "*" },
                    MaxAge       = Duration.Days(10)
                }
            });
            LambdaProxyIntegration lambdaProxyIntegration = new LambdaProxyIntegration(new LambdaProxyIntegrationProps()
            {
                Handler = dockerImageFunction,
                PayloadFormatVersion = PayloadFormatVersion.VERSION_2_0
            });

            httpApi.AddRoutes(new AddRoutesOptions()
            {
                Path        = "/casing",
                Integration = lambdaProxyIntegration,
                Methods     = new[] { HttpMethod.POST }
            });
            string    guid   = Guid.NewGuid().ToString();
            CfnOutput apiUrl = new CfnOutput(this, "APIGatewayURLOutput", new CfnOutputProps()
            {
                ExportName = $"APIGatewayEndpointURL-{guid}",
                Value      = httpApi.ApiEndpoint
            });
        }
        private void AddBucket()
        {
            var bucket = new Bucket(this, "Bucket");

            bucket.ApplyRemovalPolicy(RemovalPolicy.DESTROY);
            bucket.AddToResourcePolicy(new PolicyStatement(new PolicyStatementProps
            {
                Effect     = Effect.ALLOW,
                Actions    = new[] { "s3:*Object" },
                Resources  = new[] { bucket.BucketArn, $"{bucket.BucketArn}/*" },
                Principals = new[]
                {
                    new AccountPrincipal(Fn.Ref("AWS::AccountId")),
                    new ArnPrincipal(Fn.ImportValue("cfn-metadata:DevAgentRoleArn")),
                    new ArnPrincipal(Fn.ImportValue("cfn-metadata:ProdAgentRoleArn")),
                },
            }));

            _ = new CfnOutput(this, "BucketName", new CfnOutputProps
            {
                Value       = bucket.BucketName,
                Description = "Name of the Artifacts Bucket for Brighid Discord Adapter.",
            });
        }
        internal AuthlambdaStack(Construct scope, string id, AuthlambdaStackProps props = null) : base(scope, id, props)
        {
            functionsStack = props.functionsStack;

            Bucket websiteBucket = new Bucket(this, "websiteBucket", new BucketProps()
            {
                BlockPublicAccess = BlockPublicAccess.BLOCK_ALL,
                PublicReadAccess  = false,
                //WebsiteIndexDocument = "index.html",
                RemovalPolicy = RemovalPolicy.DESTROY,
                Cors          = new ICorsRule[] {
                    new CorsRule()
                    {
                        AllowedHeaders = new string[] { "Authorization", "Content-Type", "Origin" },
                        AllowedMethods = new HttpMethods[] { HttpMethods.GET, HttpMethods.HEAD },
                        AllowedOrigins = new string[] { "*" }
                    }
                }
            });

            Bucket privateBucket = new Bucket(this, "privateBucket", new BucketProps()
            {
                BlockPublicAccess = BlockPublicAccess.BLOCK_ALL,
                PublicReadAccess  = false,
                RemovalPolicy     = RemovalPolicy.DESTROY,
                Cors = new ICorsRule[] {
                    new CorsRule()
                    {
                        AllowedHeaders = new string[] { "Authorization", "Content-Type", "Origin" },
                        AllowedMethods = new HttpMethods[] { HttpMethods.GET, HttpMethods.HEAD },
                        AllowedOrigins = new string[] { "*" }
                    }
                }
            });

            // The S3 bucket deployment for the website
            var websiteDeployment = new BucketDeployment(this, "TestStaticWebsiteDeployment", new BucketDeploymentProps()
            {
                Sources           = new [] { Source.Asset("./src/website") },
                DestinationBucket = websiteBucket,
                RetainOnDelete    = false
            });

            var privateDeployment = new BucketDeployment(this, "TestPrivateDeployment", new BucketDeploymentProps()
            {
                Sources           = new [] { Source.Asset("./src/private") },
                DestinationBucket = privateBucket,
                RetainOnDelete    = false
            });

            var cloudfrontOAI = OriginAccessIdentity.FromOriginAccessIdentityName(this, "CloudfrontOAIName", cloudfrontOAIName);

            websiteBucket.GrantRead(cloudfrontOAI.GrantPrincipal);
            privateBucket.GrantRead(cloudfrontOAI.GrantPrincipal);

            var cachePolicy = new CachePolicy(this, "TestCachePolicy", new CachePolicyProps()
            {
                CachePolicyName = "TestCachePolicy",
                Comment         = "Cache policy for Testing",
                DefaultTtl      = Duration.Seconds(0),
                CookieBehavior  = CacheCookieBehavior.All(),
                HeaderBehavior  = CacheHeaderBehavior.AllowList(
                    "Authorization",
                    "Content-Type",
                    "Origin"
                    ),
                QueryStringBehavior        = CacheQueryStringBehavior.All(),
                EnableAcceptEncodingBrotli = false,
                EnableAcceptEncodingGzip   = false
            });

            var websiteOrigin = new S3Origin(websiteBucket, new S3OriginProps()
            {
                OriginAccessIdentity = cloudfrontOAI
            });
            var privateOrigin = new S3Origin(privateBucket, new S3OriginProps()
            {
                OriginAccessIdentity = cloudfrontOAI
            });

            var dummyOrigin = new HttpOrigin("example.com", new HttpOriginProps()
            {
                ProtocolPolicy = OriginProtocolPolicy.HTTPS_ONLY
            });

            // default behavior is for the privateOrigin
            var defaultPrivateBehavior = new BehaviorOptions {
                AllowedMethods       = AllowedMethods.ALLOW_ALL,
                CachePolicy          = cachePolicy,
                OriginRequestPolicy  = OriginRequestPolicy.CORS_S3_ORIGIN,
                ViewerProtocolPolicy = ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
                Origin      = privateOrigin,
                EdgeLambdas = new IEdgeLambda[] {
                    new EdgeLambda()
                    {
                        EventType       = LambdaEdgeEventType.VIEWER_REQUEST,
                        FunctionVersion = functionsStack.checkAuthHandler.CurrentVersion,
                    },
                    new EdgeLambda()
                    {
                        EventType       = LambdaEdgeEventType.ORIGIN_RESPONSE,
                        FunctionVersion = functionsStack.httpHeadersHandler.CurrentVersion
                    }
                }
            };

            // this behavior is for dummy origin
            var parseAuthBehavior = new BehaviorOptions {
                AllowedMethods       = AllowedMethods.ALLOW_GET_HEAD_OPTIONS,
                CachePolicy          = cachePolicy,
                OriginRequestPolicy  = OriginRequestPolicy.CORS_S3_ORIGIN,
                ViewerProtocolPolicy = ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
                Origin      = dummyOrigin,
                EdgeLambdas = new IEdgeLambda[] {
                    new EdgeLambda()
                    {
                        EventType       = LambdaEdgeEventType.VIEWER_REQUEST,
                        FunctionVersion = functionsStack.parseAuthHandler.CurrentVersion,
                    }
                }
            };

            var refreshAuthBehavior = new BehaviorOptions {
                AllowedMethods       = AllowedMethods.ALLOW_GET_HEAD_OPTIONS,
                CachePolicy          = cachePolicy,
                OriginRequestPolicy  = OriginRequestPolicy.CORS_S3_ORIGIN,
                ViewerProtocolPolicy = ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
                Origin      = dummyOrigin,
                EdgeLambdas = new IEdgeLambda[] {
                    new EdgeLambda()
                    {
                        EventType       = LambdaEdgeEventType.VIEWER_REQUEST,
                        FunctionVersion = functionsStack.refreshAuthHandler.CurrentVersion,
                    }
                }
            };

            var signOutBehavior = new BehaviorOptions {
                AllowedMethods       = AllowedMethods.ALLOW_GET_HEAD_OPTIONS,
                CachePolicy          = cachePolicy,
                OriginRequestPolicy  = OriginRequestPolicy.CORS_S3_ORIGIN,
                ViewerProtocolPolicy = ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
                Origin      = dummyOrigin,
                EdgeLambdas = new IEdgeLambda[] {
                    new EdgeLambda()
                    {
                        EventType       = LambdaEdgeEventType.VIEWER_REQUEST,
                        FunctionVersion = functionsStack.signOutHandler.CurrentVersion,
                    }
                }
            };

            Distribution distribution = new Distribution(this, "TestCloudfrontDistribution", new DistributionProps()
            {
                Comment           = "Test Website Distribution",
                DefaultRootObject = "index.html",
                PriceClass        = PriceClass.PRICE_CLASS_ALL,
                GeoRestriction    = GeoRestriction.Whitelist(new [] {
                    "IN"
                }),
                DefaultBehavior = defaultPrivateBehavior,
            });

            distribution.AddBehavior("/parseauth", dummyOrigin, parseAuthBehavior);
            distribution.AddBehavior("/refreshauth", dummyOrigin, refreshAuthBehavior);
            distribution.AddBehavior("/signout", dummyOrigin, signOutBehavior);

            var domainNameOutput = new CfnOutput(this, "TestWebsiteDistributionDomainName", new CfnOutputProps()
            {
                Value = distribution.DistributionDomainName
            });
        }
        internal AppStack(Construct scope, RecipeConfiguration <Configuration> recipeConfiguration, IStackProps props = null)
            : base(scope, recipeConfiguration.StackName, props)
        {
            var settings = recipeConfiguration.Settings;

            var asset = new Asset(this, "Asset", new AssetProps
            {
                Path = recipeConfiguration.DotnetPublishZipPath
            });

            CfnApplication application = null;

            // Create an app version from the S3 asset defined above
            // The S3 "putObject" will occur first before CF generates the template
            var applicationVersion = new CfnApplicationVersion(this, "ApplicationVersion", new CfnApplicationVersionProps
            {
                ApplicationName = settings.BeanstalkApplication.ApplicationName,
                SourceBundle    = new CfnApplicationVersion.SourceBundleProperty
                {
                    S3Bucket = asset.S3BucketName,
                    S3Key    = asset.S3ObjectKey
                }
            });

            if (settings.BeanstalkApplication.CreateNew)
            {
                application = new CfnApplication(this, "Application", new CfnApplicationProps
                {
                    ApplicationName = settings.BeanstalkApplication.ApplicationName
                });

                applicationVersion.AddDependsOn(application);
            }

            IRole role;

            if (settings.ApplicationIAMRole.CreateNew)
            {
                role = new Role(this, "Role", new RoleProps
                {
                    AssumedBy = new ServicePrincipal("ec2.amazonaws.com"),

                    // https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/iam-instanceprofile.html
                    ManagedPolicies = new[]
                    {
                        ManagedPolicy.FromAwsManagedPolicyName("AWSElasticBeanstalkWebTier"),
                        ManagedPolicy.FromAwsManagedPolicyName("AWSElasticBeanstalkWorkerTier")
                    }
                });
            }
            else
            {
                role = Role.FromRoleArn(this, "Role", settings.ApplicationIAMRole.RoleArn);
            }

            var instanceProfile = new CfnInstanceProfile(this, "InstanceProfile", new CfnInstanceProfileProps
            {
                Roles = new[]
                {
                    role.RoleName
                }
            });

            var optionSettingProperties = new List <CfnEnvironment.OptionSettingProperty> {
                new CfnEnvironment.OptionSettingProperty {
                    Namespace  = "aws:autoscaling:launchconfiguration",
                    OptionName = "IamInstanceProfile",
                    Value      = instanceProfile.AttrArn
                },
                new CfnEnvironment.OptionSettingProperty {
                    Namespace  = "aws:elasticbeanstalk:environment",
                    OptionName = "EnvironmentType",
                    Value      = settings.EnvironmentType
                }
            };

            if (!string.IsNullOrEmpty(settings.InstanceType))
            {
                optionSettingProperties.Add(new CfnEnvironment.OptionSettingProperty
                {
                    Namespace  = "aws:autoscaling:launchconfiguration",
                    OptionName = "InstanceType",
                    Value      = settings.InstanceType
                });
            }

            if (settings.EnvironmentType.Equals(ENVIRONMENTTYPE_LOADBALANCED))
            {
                optionSettingProperties.Add(
                    new CfnEnvironment.OptionSettingProperty
                {
                    Namespace  = "aws:elasticbeanstalk:environment",
                    OptionName = "LoadBalancerType",
                    Value      = settings.LoadBalancerType
                }
                    );
            }

            if (!string.IsNullOrEmpty(settings.EC2KeyPair))
            {
                optionSettingProperties.Add(
                    new CfnEnvironment.OptionSettingProperty
                {
                    Namespace  = "aws:autoscaling:launchconfiguration",
                    OptionName = "EC2KeyName",
                    Value      = settings.EC2KeyPair
                }
                    );
            }

            var environment = new CfnEnvironment(this, "Environment", new CfnEnvironmentProps
            {
                EnvironmentName = settings.EnvironmentName,
                ApplicationName = settings.BeanstalkApplication.ApplicationName,
                PlatformArn     = settings.ElasticBeanstalkPlatformArn,
                OptionSettings  = optionSettingProperties.ToArray(),
                // This line is critical - reference the label created in this same stack
                VersionLabel = applicationVersion.Ref,
            });

            var output = new CfnOutput(this, "EndpointURL", new CfnOutputProps
            {
                Value = $"http://{environment.AttrEndpointUrl}/"
            });
        }
        private void AddRepository()
        {
            var repository = new Repository(this, "ImageRepository", new RepositoryProps
            {
                RepositoryName  = "brighid/discord-adapter",
                ImageScanOnPush = true,
                LifecycleRules  = new[]
                {
                    new EcrLifecycleRule
                    {
                        Description   = "Protect prod-tagged images.",
                        RulePriority  = 1,
                        TagStatus     = TagStatus.TAGGED,
                        TagPrefixList = new[] { "production" },
                        MaxImageCount = 1,
                    },
                    new EcrLifecycleRule
                    {
                        Description   = "Protect dev-tagged images.",
                        RulePriority  = 2,
                        TagStatus     = TagStatus.TAGGED,
                        TagPrefixList = new[] { "development" },
                        MaxImageCount = 1,
                    },
                    new EcrLifecycleRule
                    {
                        Description   = "Keep last 3 images not tagged with dev or prod",
                        RulePriority  = 3,
                        TagStatus     = TagStatus.ANY,
                        MaxImageCount = 3,
                    },
                },
            });

            repository.AddToResourcePolicy(new PolicyStatement(new PolicyStatementProps
            {
                Effect  = Effect.ALLOW,
                Actions = new[]
                {
                    "ecr:GetAuthorizationToken",
                    "ecr:GetDownloadUrlForLayer",
                    "ecr:BatchGetImage",
                    "ecr:BatchCheckLayerAvailability",
                    "ecr:ListImages",
                    "ecr:PutImage", // For re-tagging images only
                },
                Principals = new[]
                {
                    new AccountPrincipal(Fn.Ref("AWS::AccountId")),
                    new AccountPrincipal(Fn.ImportValue("cfn-metadata:DevAccountId")),
                    new AccountPrincipal(Fn.ImportValue("cfn-metadata:ProdAccountId")),
                },
            }));

            repository.ApplyRemovalPolicy(RemovalPolicy.DESTROY);

            _ = new CfnOutput(this, "ImageRepositoryUri", new CfnOutputProps
            {
                Value       = repository.RepositoryUri,
                Description = "URI of the container image repository for Brighid Discord Adapter.",
            });
        }
        public void CreateLogConsumerResources()
        {
            //LambdaRole
            var firehoseLambdaRole = new Role(this, "FirehoseLambdaRole", new RoleProps
            {
                AssumedBy = new ServicePrincipal("lambda.amazonaws.com"),
                Path      = "/",
            });

            firehoseLambdaRole.AddToPolicy(new PolicyStatement(new PolicyStatementProps
            {
                Effect    = Effect.ALLOW,
                Resources = new string[] { "arn:aws:logs:*:*:*" },
                Actions   = new string[] { "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents" },
            }));

            //FirehoseDataProcessingFunction
            var handler = new Function(this, "FirehoseDataProcessorFunction", new FunctionProps
            {
                FunctionName = "data-processor-function",
                Runtime      = Runtime.NODEJS_12_X,
                Code         = Code.FromAsset("resources"),
                Handler      = "index.handler",
                Role         = firehoseLambdaRole,
                Timeout      = Duration.Minutes(2)
            });

            //FirehoseDeliveryRole & Policies
            var firehoseDeliveryRole = new Role(this, "FirehoseDeliveryRole", new RoleProps
            {
                AssumedBy = new ServicePrincipal("firehose.amazonaws.com"),
                Path      = "/"
            });

            //S3 permissions
            firehoseDeliveryRole.AddToPolicy(new PolicyStatement(new PolicyStatementProps
            {
                Effect    = Effect.ALLOW,
                Resources = new string[] { _logsBucket.BucketArn, _logsBucket.BucketArn + "/*" },
                Actions   = new string[] { "s3:AbortMultipartUpload", "s3:GetBucketLocation", "s3:GetObject"
                                           , "s3:ListBucket", "s3:ListBucketMultipartUploads", "s3:PutObject" },
            }));

            //Lambda permissions
            firehoseDeliveryRole.AddToPolicy(new PolicyStatement(new PolicyStatementProps
            {
                Effect    = Effect.ALLOW,
                Resources = new string[] { handler.FunctionArn },
                Actions   = new string[] { "lambda:GetFunctionConfiguration", "lambda:InvokeFunction" },
            }));

            //Log group for Firehose logs.
            var firehoseloggroup = new LogGroup(this, "firehoseloggroup", new LogGroupProps
            {
                LogGroupName = "central-logs-delivery-group"
            });
            var logstream = new LogStream(this, "logstream", new LogStreamProps
            {
                LogStreamName = "central-logs-delivery-stream",
                LogGroup      = firehoseloggroup
            });

            firehoseDeliveryRole.AddToPolicy(new PolicyStatement(new PolicyStatementProps
            {
                Effect    = Effect.ALLOW,
                Resources = new string[] { firehoseloggroup.LogGroupArn },
                Actions   = new string[] { "logs:PutLogEvents" },
            }));

            //FirehoseLoggingDeliveryStream - Start
            CfnDeliveryStream.ExtendedS3DestinationConfigurationProperty s3config = new CfnDeliveryStream.ExtendedS3DestinationConfigurationProperty();
            s3config.BucketArn      = _logsBucket.BucketArn;
            s3config.BufferingHints = new CfnDeliveryStream.BufferingHintsProperty
            {
                SizeInMBs         = 50,
                IntervalInSeconds = 300
            };
            s3config.CompressionFormat = "UNCOMPRESSED";
            s3config.RoleArn           = firehoseDeliveryRole.RoleArn;
            s3config.Prefix            = "CentralLogs/AWSLogs/";
            s3config.ErrorOutputPrefix = "CentralLogs/AWSLogs/Error/";

            var parameters = new CfnDeliveryStream.ProcessorParameterProperty();

            parameters.ParameterName  = "LambdaArn";
            parameters.ParameterValue = handler.FunctionArn;

            var paramsArray1 = new CfnDeliveryStream.ProcessorParameterProperty[] { parameters };

            var processorProperty = new CfnDeliveryStream.ProcessorProperty();

            processorProperty.Parameters = paramsArray1;
            processorProperty.Type       = "Lambda";

            var paramsArray = new CfnDeliveryStream.ProcessorProperty[] { processorProperty };

            s3config.ProcessingConfiguration = new CfnDeliveryStream.ProcessingConfigurationProperty
            {
                Enabled    = true,
                Processors = paramsArray
            };

            s3config.CloudWatchLoggingOptions = new CfnDeliveryStream.CloudWatchLoggingOptionsProperty
            {
                Enabled       = true,
                LogGroupName  = firehoseloggroup.LogGroupName,
                LogStreamName = logstream.LogStreamName
            };


            CfnDeliveryStream firehoseDeliveryStream = new CfnDeliveryStream(this, "FirehoseLoggingDeliveryStream", new CfnDeliveryStreamProps
            {
                DeliveryStreamType = "DirectPut",
                ExtendedS3DestinationConfiguration = s3config
            });
            //FirehoseLoggingDeliveryStream - End

            //Policy Statements for LogDestination- start
            var policyStmt = new PolicyStatement(new PolicyStatementProps()
            {
                Actions   = new string[] { "firehose:PutRecord" },
                Resources = new string[] { "*" },
                Effect    = Effect.ALLOW
            });
            var policyDoc = new PolicyDocument();

            policyDoc.AddStatements(new PolicyStatement[] { policyStmt });

            var policyProp = new CfnRole.PolicyProperty();

            policyProp.PolicyName     = "logDestinationPolicy";
            policyProp.PolicyDocument = policyDoc;
            //Policy Statements - end

            //AssumeRolePolicyDocument for LogDestination - start
            var principal             = new ServicePrincipal("logs.amazonaws.com");
            var assumePolicyStatement = new PolicyStatement(new PolicyStatementProps
            {
                Actions    = new string[] { "sts:AssumeRole" },
                Effect     = Effect.ALLOW,
                Principals = new IPrincipal[] { principal }
            });
            var assumePolicyDoc = new PolicyDocument();

            assumePolicyDoc.AddStatements(new PolicyStatement[] { assumePolicyStatement });
            //AssumeRolePolicyDocument - end

            var roleProps = new CfnRoleProps {
                Path = "/",
                AssumeRolePolicyDocument = assumePolicyDoc,
                Policies = new CfnRole.PolicyProperty[] { policyProp }
            };

            CfnRole cfnRole = new CfnRole(this, "CfnRole", roleProps);

            CfnDestination logDestination = new CfnDestination(this, "LogDestination", new CfnDestinationProps
            {
                DestinationName   = "Central-Log-Destination",
                RoleArn           = cfnRole.AttrArn,
                TargetArn         = firehoseDeliveryStream.AttrArn,
                DestinationPolicy = "{\"Version\" : \"2012-10-17\",\"Statement\" : [{\"Effect\" : \"Allow\", \"Principal\" : {\"AWS\" :  [\"" + SourceLogAccountId + "\"]},\"Action\" : \"logs:PutSubscriptionFilter\", \"Resource\" : \"arn:aws:logs:" + this.Region + ":"
                                    + DestinationAccountId + ":destination:Central-Log-Destination\"}]}"
            });

            logDestination.AddDependsOn(firehoseDeliveryStream);
            logDestination.AddDependsOn(cfnRole);
            Console.WriteLine(logDestination.DestinationPolicy);

            LogDestinationArn = logDestination.AttrArn;

            CfnOutput output = new CfnOutput(this, "LogDestinationARN", new CfnOutputProps {
                Description = "LogDestination ARN",
                Value       = logDestination.AttrArn
            });
        }
Exemple #12
0
        private void ConfigureAppRunnerService(IRecipeProps <Configuration> props)
        {
            if (ServiceAccessRole == null)
            {
                throw new InvalidOperationException($"{nameof(ServiceAccessRole)} has not been set. The {nameof(ConfigureIAMRoles)} method should be called before {nameof(ConfigureAppRunnerService)}");
            }
            if (TaskRole == null)
            {
                throw new InvalidOperationException($"{nameof(TaskRole)} has not been set. The {nameof(ConfigureIAMRoles)} method should be called before {nameof(ConfigureAppRunnerService)}");
            }

            if (string.IsNullOrEmpty(props.ECRRepositoryName))
            {
                throw new InvalidOrMissingConfigurationException("The provided ECR Repository Name is null or empty.");
            }

            var ecrRepository = Repository.FromRepositoryName(this, "ECRRepository", props.ECRRepositoryName);

            Configuration settings             = props.Settings;
            var           appRunnerServiceProp = new CfnServiceProps
            {
                ServiceName         = settings.ServiceName,
                SourceConfiguration = new CfnService.SourceConfigurationProperty
                {
                    AuthenticationConfiguration = new CfnService.AuthenticationConfigurationProperty
                    {
                        AccessRoleArn = ServiceAccessRole.RoleArn
                    },
                    ImageRepository = new CfnService.ImageRepositoryProperty
                    {
                        ImageRepositoryType = "ECR",
                        ImageIdentifier     = ContainerImage.FromEcrRepository(ecrRepository, props.ECRImageTag).ImageName,
                        ImageConfiguration  = new CfnService.ImageConfigurationProperty
                        {
                            Port         = settings.Port.ToString(),
                            StartCommand = !string.IsNullOrWhiteSpace(settings.StartCommand) ? settings.StartCommand : null
                        }
                    }
                }
            };

            if (!string.IsNullOrEmpty(settings.EncryptionKmsKey))
            {
                var encryptionConfig = new CfnService.EncryptionConfigurationProperty();
                appRunnerServiceProp.EncryptionConfiguration = encryptionConfig;

                encryptionConfig.KmsKey = settings.EncryptionKmsKey;
            }

            var healthCheckConfig = new CfnService.HealthCheckConfigurationProperty();

            appRunnerServiceProp.HealthCheckConfiguration = healthCheckConfig;

            healthCheckConfig.HealthyThreshold   = settings.HealthCheckHealthyThreshold;
            healthCheckConfig.Interval           = settings.HealthCheckInterval;
            healthCheckConfig.Protocol           = settings.HealthCheckProtocol;
            healthCheckConfig.Timeout            = settings.HealthCheckTimeout;
            healthCheckConfig.UnhealthyThreshold = settings.HealthCheckUnhealthyThreshold;

            if (string.Equals(healthCheckConfig.Protocol, "HTTP"))
            {
                healthCheckConfig.Path = string.IsNullOrEmpty(settings.HealthCheckPath) ? "/" : settings.HealthCheckPath;
            }

            var instanceConfig = new CfnService.InstanceConfigurationProperty();

            appRunnerServiceProp.InstanceConfiguration = instanceConfig;


            instanceConfig.InstanceRoleArn = TaskRole.RoleArn;

            instanceConfig.Cpu    = settings.Cpu;
            instanceConfig.Memory = settings.Memory;

            AppRunnerService = new CfnService(this, nameof(AppRunnerService), InvokeCustomizeCDKPropsEvent(nameof(AppRunnerService), this, appRunnerServiceProp));

            var output = new CfnOutput(this, "EndpointURL", new CfnOutputProps
            {
                Value = $"https://{AppRunnerService.AttrServiceUrl}/"
            });
        }
        public SrcStack(Construct scope, string id, IStackProps props) : base(scope, id, props)
        {
            #region VPC, Subnets and Security Groups
            IVpc batchVpc = new Vpc(this, Constants.VPC_ID, new VpcProps {
                Cidr   = Constants.CIDR_RANGE,
                MaxAzs = 4
            });

            var privateSubnetIds = new List <string>();
            foreach (Subnet subnet in batchVpc.PrivateSubnets)
            {
                privateSubnetIds.Add(subnet.SubnetId);
            }

            var batchSecurityGroup = new SecurityGroup(this, Constants.BATCH_SECURITY_GROUP_ID,
                                                       new SecurityGroupProps {
                Vpc = batchVpc,
                SecurityGroupName = Constants.BATCH_SECURITY_GROUP_NAME,
                Description       = Constants.BATCH_SECURITY_GROUP_DESCRIPTION,
            }
                                                       );

            var batchSecurityGroupIds = new List <string>()
            {
                batchSecurityGroup.SecurityGroupId
            };

            #endregion

            #region S3, DynamoDB, Lambda (to trigger the batch on file drop)
            s3.Bucket bucket = new s3.Bucket(this, Constants.S3_BUCKET_ID, new s3.BucketProps {
                BucketName = Constants.S3_BUCKET_NAME + this.Account
            });
            var bucketName = bucket.BucketName;

            var gsi = new dynamo.GlobalSecondaryIndexProps()
            {
                IndexName    = "GSI",
                PartitionKey = new dynamo.Attribute {
                    Name = "CreatedTime", Type = dynamo.AttributeType.STRING
                },
                ProjectionType = dynamo.ProjectionType.KEYS_ONLY
            };

            dynamo.Table table = new dynamo.Table(this, Constants.DynamoDB_TABLE_ID, new dynamo.TableProps {
                TableName    = Constants.DynamoDB_TABLE_ID,
                PartitionKey = new dynamo.Attribute {
                    Name = "ProductId", Type = dynamo.AttributeType.STRING
                },
                BillingMode = dynamo.BillingMode.PAY_PER_REQUEST
            });
            table.AddGlobalSecondaryIndex(gsi);


            var lambdaBatchExecutionRoleProvider = new LambdaBatchExecutionRole(this, Constants.LAMBDA_BATCH_EXECUTION_ROLE_ID);
            #endregion

            DockerImageAsset imageAsset = new DockerImageAsset(this, "BatchProcessorImage", new DockerImageAssetProps {
                Directory      = Constants.BATCH_PROCESSOR_PYTHON_CODE_PATH,
                RepositoryName = Constants.ECR_REPOSITORY_NAME
            });

            #region Batch - ComputeEnvironment - Job Queue - Job Definition
            var batchServiceRole     = new BatchServiceRole(this, Constants.BATCH_SERVICE_ROLE_ID);
            var ecsInstanceRole      = new EcsInstanceRole(this, Constants.ECS_INSTANCE_ROLE_ID);
            var batchInstanceProfile = new InstanceProfile(this, Constants.BATCH_INSTANCE_PROFILE_ID, ecsInstanceRole);

            var computeEnvironment = new batch.CfnComputeEnvironment(this, Constants.BATCH_COMPUTE_ENVIRONMENT_ID,
                                                                     new batch.CfnComputeEnvironmentProps {
                ComputeEnvironmentName = Constants.BATCH_COMPUTE_ENVIRONMENT_NAME,
                Type             = Constants.BATCH_COMPUTE_TYPE,
                ServiceRole      = batchServiceRole.Role.RoleName,
                ComputeResources = new batch.CfnComputeEnvironment.ComputeResourcesProperty {
                    Type          = Constants.BATCH_COMPUTE_RESOURCE_TYPE,
                    MinvCpus      = 0,
                    MaxvCpus      = 32,
                    DesiredvCpus  = 0,
                    InstanceRole  = ecsInstanceRole.Role.RoleName,
                    InstanceTypes = new string[] {
                        Constants.BATCH_INSTANCE_TYPE
                    },
                    SecurityGroupIds = batchSecurityGroupIds.ToArray(),
                    Subnets          = privateSubnetIds.ToArray()
                }
            });

            var computeEnvironmentOrders = new List <batch.CfnJobQueue.ComputeEnvironmentOrderProperty>();
            var computeEnvironmentOrder  = new batch.CfnJobQueue.ComputeEnvironmentOrderProperty()
            {
                Order = 1,
                ComputeEnvironment = computeEnvironment.Ref
            };
            computeEnvironmentOrders.Add(computeEnvironmentOrder);

            var batchProcessingJobQueue = new batch.CfnJobQueue(this, Constants.BATCH_JOB_QUEUE_ID, new batch.CfnJobQueueProps {
                JobQueueName            = Constants.BATCH_PROCESSING_JOB_QUEUE,
                Priority                = 1,
                ComputeEnvironmentOrder = computeEnvironmentOrders.ToArray()
            });

            var batchProcessingJobDefinition = new batch.CfnJobDefinition(this, Constants.BATCH_JOB_DEFINITION_ID, new batch.CfnJobDefinitionProps {
                Type = Constants.CONTAINER,
                JobDefinitionName   = Constants.BATCH_JOB_DEFINITION_NAME,
                ContainerProperties = new batch.CfnJobDefinition.ContainerPropertiesProperty()
                {
                    Image   = imageAsset.ImageUri,
                    Vcpus   = Constants.BATCH_JOB_DEFINITION_VCPU,
                    Memory  = Constants.BATCH_JOB_DEFINITION_MemoryLimitMiB,
                    Command = new string[] {
                        "python",
                        "batch_processor.py"
                    }
                }
            });
            #endregion


            #region lambda s3 event trigger

            BatchTriggerLambdaInput batchTriggerLambdaInput = new BatchTriggerLambdaInput {
                BucketName         = bucketName,
                FileName           = "sample.csv",
                Region             = "us-east-1",
                BatchJobDefinition = batchProcessingJobDefinition.JobDefinitionName,
                BatchJobName       = Constants.BATCH_JOB_NAME,
                BatchJobQueue      = batchProcessingJobQueue.JobQueueName,
                DBTable            = table.TableName
            };

            lambda.Function lambda = BatchTriggerLambda.BatchTriggerLambdaFunction(this, Constants.LAMBDA_NAME,
                                                                                   batchTriggerLambdaInput, lambdaBatchExecutionRoleProvider);

            var batchLambdaFunction = new LambdaFunction(
                lambda
                );

            var eventPutSource = new eventsources.S3EventSource(bucket, new eventsources.S3EventSourceProps {
                Events = new s3.EventType[] {
                    s3.EventType.OBJECT_CREATED_PUT
                }
            });

            lambda.AddEventSource(eventPutSource);

            #endregion

            #region OUTPUTS
            var cfnComputeOutput = new CfnOutput(this, Constants.BATCH_COMPUTE_ENVIRONMENT_NAME_OUTPUT_ID,
                                                 new CfnOutputProps {
                Value = computeEnvironment.Ref
            }
                                                 );

            var cfnS3Output = new CfnOutput(this, Constants.S3_BUCKET_OUTPUT_ID,
                                            new CfnOutputProps {
                Value = bucket.BucketName
            }
                                            );

            var cfnEcrRepositoryOutput = new CfnOutput(this, Constants.ECR_REPOSITORY_OUTPUT_ID,
                                                       new CfnOutputProps {
                Value = imageAsset.Repository.RepositoryArn
            }
                                                       );

            var cfnDynamoTableOutput = new CfnOutput(this, Constants.DYNAMO_TABLE_OUTPUT_ID,
                                                     new CfnOutputProps {
                Value = table.TableName
            }
                                                     );

            var cfnLambdaRepositoryOutput = new CfnOutput(this, Constants.LAMBDA_OUTPUT_ID,
                                                          new CfnOutputProps {
                Value = lambda.FunctionArn
            }
                                                          );

            #endregion

            Tag.Add(this, "Name", Constants.APP_NAME);
        }