Example #1
0
        public TimestreamService(Construct scope, string id) : base(scope, id)
        {
            var handler = new Function(this, "StepHandler", new FunctionProps
            {
                Runtime = Runtime.NODEJS_10_X,
                Code    = Code.FromAsset("LambdaResources"),
                Handler = "steps.main",
            });
            var db = new CfnDatabase(this, "TimestreamDB", new CfnDatabaseProps
            {
                DatabaseName = "StepDatabase",
            });
            var table = new CfnTable(this, "stepTable", new CfnTableProps()
            {
                TableName    = "StepTable",
                DatabaseName = db.DatabaseName
            });
            var api = new RestApi(this, "Steps-API", new RestApiProps
            {
                RestApiName = "Step Service",
                Description = "This service services Steps."
            });

            var postStepsIntegration = new LambdaIntegration(handler);

            var steps = api.Root.AddResource("healthInput");

            steps.AddMethod("POST", postStepsIntegration);
        }
Example #2
0
        internal SimpleWebServiceStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
        {
            var userTable = new Table(this, "questions", new TableProps
            {
                PartitionKey = new Attribute
                {
                    Name = "id",
                    Type = AttributeType.STRING
                }
            });

            var api = new RestApi(this, "Simple Web service API", new RestApiProps {
            });

            var handler = new Function(this, "SimpleServiceApiHandler", new FunctionProps {
                Runtime = Runtime.DOTNET_CORE_3_1,
                Code    = Code.FromAsset("src/SimpleWebService/resources"), // path from CDK app root (foler that contains cdk.json)
                Handler = "LambdaService.handler"                           // LambdaService is the name of the source file, without the extension;
                                                                            // handler is the function within simpleWebService.cs that is called to invoke the Lambda function.
            });

            // So Lambda function can access the table
            handler.AddEnvironment("TABLE_NAME", userTable.TableName);

            // So Lambda function can read/write to table
            userTable.GrantReadWriteData(handler);

            var apiHandler = new LambdaIntegration(handler);

            var user = api.Root.AddResource("user").AddResource("{id}");

            user.AddMethod("GET", apiHandler);
        }
Example #3
0
        internal EndpointsStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
        {
            // The code that defines your stack goes here

            var fn = new Function(this, "myfunction", new FunctionProps
            {
                Runtime = Runtime.NODEJS_12_X,
                Code    = Code.FromAsset("src/EdgyRegions/resources/endpoint"),
                Handler = "lazy.handler"
            });
            var fnIntegration = new LambdaIntegration(fn, new LambdaIntegrationOptions
            {
                Proxy = true,
                // IntegrationResponses = new IIntegrationResponse[] { new IntegrationResponse { StatusCode = "200" } }
            });

            var edgeCompressedApi = new RestApi(this, "edgeCompressedApi", new RestApiProps
            {
                EndpointConfiguration = new EndpointConfiguration {
                    Types = new EndpointType[] { EndpointType.EDGE }
                },
                MinimumCompressionSize = 1
            });

            edgeCompressedApi.Root.AddMethod("GET", fnIntegration);
            generateCloudFront(edgeCompressedApi, "edgeCompressed");

            var edgeUncompressedApi = new RestApi(this, "edgeUncompressedApi", new RestApiProps
            {
                EndpointConfiguration = new EndpointConfiguration {
                    Types = new EndpointType[] { EndpointType.EDGE }
                },
                // MinimumCompressionSize = -1 // default is disabled
            });

            edgeUncompressedApi.Root.AddMethod("GET", fnIntegration);
            generateCloudFront(edgeUncompressedApi, "edgeUncompressed");

            var regionalCompressedApi = new RestApi(this, "regionalCompressedApi", new RestApiProps
            {
                EndpointConfiguration = new EndpointConfiguration {
                    Types = new EndpointType[] { EndpointType.REGIONAL }
                },
                MinimumCompressionSize = 1
            });

            regionalCompressedApi.Root.AddMethod("GET", fnIntegration);
            generateCloudFront(regionalCompressedApi, "regionalCompressed");

            var regionalUncompressedApi = new RestApi(this, "regionalUncompressed", new RestApiProps
            {
                EndpointConfiguration = new EndpointConfiguration {
                    Types = new EndpointType[] { EndpointType.REGIONAL }
                },
                // MinimumCompressionSize = -1 // default is disabled
            });

            regionalUncompressedApi.Root.AddMethod("GET", fnIntegration);
            generateCloudFront(regionalUncompressedApi, "regionalUncompressed");
        }
Example #4
0
        internal BlogPostStack(Construct scope, PlatformConfig platformConfig, string id,
                               IStackProps props = null) : base(scope, id, props)
        {
            props = CreateProps(platformConfig);

            var blogPostTable = new Table(this, "xerris-blog-post", new TableProps
            {
                TableName    = platformConfig.BlogPostTableName,
                BillingMode  = BillingMode.PAY_PER_REQUEST,
                PartitionKey = new Attribute {
                    Name = "Id", Type = AttributeType.STRING
                },
                RemovalPolicy = RemovalPolicy.DESTROY
            });

            var lambdaPackage = Path.Combine(System.Environment.CurrentDirectory, platformConfig.LambdaPackage);

            var saveBlogPostLambda = CreateFunction("postBlog", lambdaPackage,
                                                    "DevOps.Api::DevOps.Api.Handlers.BlogHandler::PostBlog", 45);

            var getAllBlogPostsLambda = CreateFunction("getAllPosts", lambdaPackage,
                                                       "DevOps.Api::DevOps.Api.Handlers.BlogHandler::GetAllBlogPosts", 45);

            var getBlogPostById = CreateFunction("getById", lambdaPackage,
                                                 "DevOps.Api::DevOps.Api.Handlers.BlogHandler::GetPostById", 45);

            blogPostTable.AllowReadWrite(saveBlogPostLambda);
            blogPostTable.AllowRead(getAllBlogPostsLambda);
            blogPostTable.AllowRead(getBlogPostById);

            var restApi = new RestApi(this, "xerris-blog-api", new RestApiProps
            {
                Deploy      = true,
                Description = "Api endpoints for the Blogging System",
                RestApiName = "xerris-blog-api"
            });

            var blogResource = restApi.Root.AddResource("blog");

            var postBlogIntegration = new LambdaIntegration(saveBlogPostLambda, new LambdaIntegrationOptions());

            blogResource.AddMethod("POST", postBlogIntegration);

            var getAllIntegration = new LambdaIntegration(getAllBlogPostsLambda, new LambdaIntegrationOptions());

            blogResource.AddMethod("GET", getAllIntegration);

            var findByIdIntegration = new LambdaIntegration(getBlogPostById, new LambdaIntegrationOptions());

            blogResource.AddResource("{id}")
            .AddMethod("GET", findByIdIntegration);
        }
Example #5
0
        public QuestionsService(Construct scope, string id) : base(scope, id)
        {
            var table = new Table(this, "QuestionsTable", new TableProps
            {
                PartitionKey = new Attribute
                {
                    Name = "id",
                    Type = AttributeType.STRING
                },
                TableName = "QuestionsTable",
            });

            IBucket mybucket = Bucket.FromBucketName(this, "mybucket", "dougs-groovy-s3-bucket");

            var handler = new Function(this, "QuestionsHandler", new FunctionProps
            {
                Runtime     = Runtime.DOTNET_CORE_3_1,
                Code        = Code.FromBucket(mybucket, "QuestionsFunction.zip"),
                Handler     = "QuestionsFunction::QuestionsFunction.Function::FunctionHandler",
                Environment = new Dictionary <string, string>
                {
                    ["TABLE"] = table.TableName
                }
            });

            table.GrantReadWriteData(handler);

            var api = new RestApi(this, "Questions-API", new RestApiProps
            {
                RestApiName = "Questions Service",
                Description = "This service services questions."
            });

            var getQuestionsIntegration = new LambdaIntegration(handler, new LambdaIntegrationOptions
            {
                RequestTemplates = new Dictionary <string, string>
                {
                    ["application/json"] = "{ \"statusCode\": \"200\" }"
                }
            });

            api.Root.AddMethod("GET", getQuestionsIntegration);
        }
Example #6
0
        internal UsersServiceLambdaStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
        {
            var lambda = new Function(this, "CreateUser", new FunctionProps
            {
                Runtime    = Runtime.DOTNET_CORE_2_1,
                Code       = Code.FromAsset("../Minniowa.Users.Lambda/bin/Debug/netcoreapp2.1/publish"),
                Handler    = "Minniowa.Users.Lambda::Minniowa.Users.Lambda.Functions::CreateUser",
                MemorySize = 1024,
                Timeout    = Duration.Seconds(30)
            });


            var api = new RestApi(this, "MinniowaApi", new RestApiProps
            {
                RestApiName = "Minniowa Service"
            });

            var v1 = api.Root.AddResource("v1");

            var getRequestLambdaIntegration = new LambdaIntegration(lambda);
            var getRequestMethod            = v1.AddMethod("POST", getRequestLambdaIntegration);
        }
        internal AwsGatewayLambdaInfrastructureStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
        {
            var toupper = new Function(this, "toupper", new FunctionProps()
            {
                Runtime      = Runtime.DOTNET_CORE_2_1,
                FunctionName = "TestAPI_toUpper",
                Timeout      = Duration.Minutes(1),
                MemorySize   = 128,
                Code         = Code.FromAsset("../aws-gateway-lambda.lambda/bin/Release/netcoreapp2.1/publish"),
                Handler      = "aws-gateway-lambda.lambda::aws_gateway_lambda.lambda.Function::ToUpper"
            });

            var addperson = new Function(this, "addperson", new FunctionProps()
            {
                Runtime      = Runtime.DOTNET_CORE_2_1,
                FunctionName = "TestAPI_AddPerson",
                Timeout      = Duration.Minutes(1),
                MemorySize   = 128,
                Code         = Code.FromAsset("../aws-gateway-lambda.lambda/bin/Release/netcoreapp2.1/publish"),
                Handler      = "aws-gateway-lambda.lambda::aws_gateway_lambda.lambda.Function::AddPerson"
            });

            var api = new RestApi(this, "api", new RestApiProps()
            {
                RestApiName = "TestApi"
            });

            // api.Root.AddMethod("ANY");
            var root = api.Root.AddResource("{name}");

            var getpersonIntegration = new LambdaIntegration(toupper);

            root.AddMethod("GET", getpersonIntegration);

            var addpersonintegration = new LambdaIntegration(addperson);

            api.Root.AddMethod("POST", addpersonintegration);
        }
Example #8
0
        public MyWidgetServiceStack(Construct parent, string id, IStackProps props) : base(parent, id, props)
        {
            var bucket = new Bucket(this, "WidgetStore", null);

            var handler = new Function(this, "WidgetHandler", new FunctionProps {
                Runtime     = Runtime.NODEJS_8_10,
                Code        = AssetCode.Asset("src/MyWidgetService/resources"),
                Handler     = "widgets.main",
                Environment = new Dictionary <string, object> {
                    { "BUCKET", bucket.BucketName }
                }
            });

            bucket.GrantReadWrite(handler, null);

            var api = new RestApi(this, "widgets-api", new RestApiProps {
                RestApiName = "Widget Service",
                Description = "This service serves widgets"
            });

            var getWidgetsIntegration = new LambdaIntegration(handler, new LambdaIntegrationOptions {
                RequestTemplates = new Dictionary <string, string> {
                    { "application/json", "{ 'statusCode', '200'}" }
                },
            });

            api.Root.AddMethod("GET", getWidgetsIntegration, null);

            var widget = api.Root.AddResource("{id}", null);

            var postWidgetIntegration   = new LambdaIntegration(handler, null);
            var getWidgetIntegration    = new LambdaIntegration(handler, null);
            var deleteWidgetIntegration = new LambdaIntegration(handler, null);

            widget.AddMethod("POST", postWidgetIntegration, null);
            widget.AddMethod("GET", getWidgetIntegration, null);
            widget.AddMethod("DELETE", deleteWidgetIntegration, null);
        }
Example #9
0
        internal CdkDeckListMagicStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
        {
            var bucket = Bucket.FromBucketArn(this, "bornusS3", "arn:aws:s3:::bornus");

            // The code that defines your stack goes here
            Function fn = new Function(this, "GetAvatar", new FunctionProps
            {
                Runtime     = Runtime.DOTNET_CORE_3_1,
                Code        = Code.FromAsset("./GetAvatar/bin/Release/netcoreapp3.1/GetAvatar.zip"),
                Handler     = "GetAvatar::GetAvatar.Function::FunctionHandler",
                Timeout     = Duration.Seconds(30),
                Environment = new Dictionary <string, string>
                {
                    { "BUCKET", bucket.BucketName }
                }
            });

            bucket.GrantRead(fn);

            var api = new RestApi(this, "Avatar", new RestApiProps
            {
                RestApiName      = "Avatar",
                Description      = "Avatar's services",
                BinaryMediaTypes = new [] { "*/*" },
            });

            var getWidgetsIntegration = new LambdaIntegration(fn, new LambdaIntegrationOptions
            {
                RequestTemplates = new Dictionary <string, string> {
                    { "application/json", "{ 'statusCode', '200'}" }
                },
            });

            api.Root.AddMethod("GET", getWidgetsIntegration);

            //var widget = api.Root.AddResource("{id}");
        }
        public XRayStack(Construct parent, string id) : base(parent, id)
        {
            var table = new Table(this, "Table", new TableProps()
            {
                TableName    = "MysfitsQuestionsTable",
                PartitionKey = new Attribute
                {
                    Name = "QuestionId",
                    Type = AttributeType.STRING
                },
                Stream = StreamViewType.NEW_IMAGE
            });

            var postQuestionLambdaFunctionPolicyStmDDB = new PolicyStatement();

            postQuestionLambdaFunctionPolicyStmDDB.AddActions("dynamodb:PutItem");
            postQuestionLambdaFunctionPolicyStmDDB.AddResources(table.TableArn);

            var LambdaFunctionPolicyStmXRay = new PolicyStatement();

            LambdaFunctionPolicyStmXRay.AddActions(
                //  Allows the Lambda function to interact with X-Ray
                "xray:PutTraceSegments",
                "xray:PutTelemetryRecords",
                "xray:GetSamplingRules",
                "xray:GetSamplingTargets",
                "xray:GetSamplingStatisticSummaries"
                );
            LambdaFunctionPolicyStmXRay.AddAllResources();

            var mysfitsPostQuestion = new Function(this, "PostQuestionFunction", new FunctionProps
            {
                Handler     = "mysfitsPostQuestion.postQuestion",
                Runtime     = Runtime.PYTHON_3_6,
                Description =
                    "A microservice Lambda function that receives a new question submitted to the MythicalMysfits website from a user and inserts it into a DynamoDB database table.",
                MemorySize    = 128,
                Code          = Code.FromAsset("../../lambda-questions/PostQuestionsService"),
                Timeout       = Duration.Seconds(30),
                InitialPolicy = new[]
                {
                    postQuestionLambdaFunctionPolicyStmDDB,
                    LambdaFunctionPolicyStmXRay
                },
                Tracing = Tracing.ACTIVE
            });

            var topic = new Topic(this, "Topic", new TopicProps
            {
                DisplayName = "MythicalMysfitsQuestionsTopic",
                TopicName   = "MythicalMysfitsQuestionsTopic"
            });

            topic.AddSubscription(new EmailSubscription("REPLACE@EMAIL_ADDRESS"));

            var postQuestionLambdaFunctionPolicyStmSNS = new PolicyStatement();

            postQuestionLambdaFunctionPolicyStmSNS.AddActions("sns:Publish");
            postQuestionLambdaFunctionPolicyStmSNS.AddResources(topic.TopicArn);

            var mysfitsProcessQuestionStream = new Function(this, "ProcessQuestionStreamFunction", new FunctionProps
            {
                Handler     = "mysfitsProcessStream.processStream",
                Runtime     = Runtime.PYTHON_3_6,
                Description =
                    "An AWS Lambda function that will process all new questions posted to mythical mysfits" +
                    " and notify the site administrator of the question that was asked.",
                MemorySize    = 128,
                Code          = Code.FromAsset("../../lambda-questions/ProcessQuestionsStream"),
                Timeout       = Duration.Seconds(30),
                InitialPolicy = new[]
                {
                    postQuestionLambdaFunctionPolicyStmSNS,
                    LambdaFunctionPolicyStmXRay
                },
                Tracing     = Tracing.ACTIVE,
                Environment = new Dictionary <string, string>()
                {
                    { "SNS_TOPIC_ARN", topic.TopicArn }
                },
                Events = new IEventSource[]
                {
                    new DynamoEventSource(table, new DynamoEventSourceProps
                    {
                        StartingPosition = StartingPosition.TRIM_HORIZON,
                        BatchSize        = 1
                    })
                }
            });

            var questionsApiRole = new Role(this, "QuestionsApiRole", new RoleProps
            {
                AssumedBy = new ServicePrincipal("apigateway.amazonaws.com")
            });

            var apiPolicy = new PolicyStatement();

            apiPolicy.AddActions("lambda:InvokeFunction");
            apiPolicy.AddResources(mysfitsPostQuestion.FunctionArn);
            new Policy(this, "QuestionsApiPolicy", new PolicyProps
            {
                PolicyName = "questions_api_policy",
                Statements = new[]
                {
                    apiPolicy
                },
                Roles = new IRole[]
                {
                    questionsApiRole
                }
            });

            var questionsIntegration = new LambdaIntegration(mysfitsPostQuestion, new LambdaIntegrationOptions
            {
                CredentialsRole      = questionsApiRole,
                IntegrationResponses = new IntegrationResponse[]
                {
                    new IntegrationResponse()
                    {
                        StatusCode        = "200",
                        ResponseTemplates = new Dictionary <string, string>
                        {
                            { "application/json", "{\"status\":\"OK\"}" }
                        }
                    }
                }
            });

            var api = new LambdaRestApi(this, "APIEndpoint", new LambdaRestApiProps
            {
                Handler       = mysfitsPostQuestion,
                RestApiName   = "Questions API Service",
                DeployOptions = new StageOptions
                {
                    TracingEnabled = true
                },
                Proxy = false
            });

            var questionsMethod = api.Root.AddResource("questions");

            questionsMethod.AddMethod("POST", questionsIntegration, new MethodOptions
            {
                MethodResponses = new MethodResponse[]
                {
                    new MethodResponse
                    {
                        StatusCode         = "200",
                        ResponseParameters = new Dictionary <string, bool>()
                        {
                            { "method.response.header.Access-Control-Allow-Headers", true },
                            { "method.response.header.Access-Control-Allow-Methods", true },
                            { "method.response.header.Access-Control-Allow-Origin", true },
                        }
                    }
                },
                AuthorizationType = AuthorizationType.NONE
            });

            questionsMethod.AddMethod("OPTIONS", new MockIntegration(new IntegrationOptions
            {
                IntegrationResponses = new IntegrationResponse[]
                {
                    new IntegrationResponse
                    {
                        StatusCode         = "200",
                        ResponseParameters = new Dictionary <string, string>
                        {
                            {
                                "method.response.header.Access-Control-Allow-Headers",
                                "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent'"
                            },
                            { "method.response.header.Access-Control-Allow-Origin", "'*'" },
                            { "method.response.header.Access-Control-Allow-Credentials", "'false'" },
                            { "method.response.header.Access-Control-Allow-Methods", "'OPTIONS,GET,PUT,POST,DELETE'" }
                        }
                    }
                },
                PassthroughBehavior = PassthroughBehavior.NEVER,
                RequestTemplates    = new Dictionary <string, string>
                {
                    { "application/json", "{\"statusCode\": 200}" }
                }
            }),
                                      new MethodOptions
            {
                MethodResponses = new MethodResponse[]
                {
                    new MethodResponse
                    {
                        StatusCode         = "200",
                        ResponseParameters = new Dictionary <string, bool>
                        {
                            { "method.response.header.Access-Control-Allow-Headers", true },
                            { "method.response.header.Access-Control-Allow-Methods", true },
                            { "method.response.header.Access-Control-Allow-Credentials", true },
                            { "method.response.header.Access-Control-Allow-Origin", true }
                        }
                    }
                }
            }
                                      );
        }
        internal DynamoDbAppStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
        {
            //Stage setting for Deployment (Need to have Deploy = false in RestApiProps to configure the Stage
            string environment = "PRD";

            //STORAGE INFRASTRUCTURE
            //Create a User DynamoDB Table with a GSI (Primary Key Table)
            var userDynamoDbTable = new Table(this, "User", new TableProps
            {
                TableName    = environment + "-" + "User",
                PartitionKey = new Amazon.CDK.AWS.DynamoDB.Attribute
                {
                    Name = "username",
                    Type = AttributeType.STRING
                },
                ReadCapacity  = 1,
                WriteCapacity = 1,
                RemovalPolicy = RemovalPolicy.DESTROY
            });

            //Adding the Global Secondary Index (GSI)
            userDynamoDbTable.AddGlobalSecondaryIndex(new GlobalSecondaryIndexProps
            {
                IndexName    = "UserGSIEmailIndex",
                PartitionKey = new Amazon.CDK.AWS.DynamoDB.Attribute
                {
                    Name = "email",
                    Type = AttributeType.STRING
                },
                ReadCapacity  = 1,
                WriteCapacity = 1
            });

            //Create a City DynamoDB Table with an LSI (Composite Key Table)
            var cityDynamoDbTable = new Table(this, "City", new TableProps
            {
                TableName    = environment + "-" + "City",
                PartitionKey = new Amazon.CDK.AWS.DynamoDB.Attribute
                {
                    Name = "state",
                    Type = AttributeType.STRING
                },
                SortKey = new Amazon.CDK.AWS.DynamoDB.Attribute
                {
                    Name = "city",
                    Type = AttributeType.STRING
                },
                ReadCapacity  = 1,
                WriteCapacity = 1,
                RemovalPolicy = RemovalPolicy.DESTROY
            });

            //Adding the Local Secondary Index (LSI)
            cityDynamoDbTable.AddLocalSecondaryIndex(new LocalSecondaryIndexProps
            {
                IndexName = "CityLSIPopulationIndex",
                SortKey   = new Amazon.CDK.AWS.DynamoDB.Attribute
                {
                    Name = "population",
                    Type = AttributeType.NUMBER
                }
            });



            //COMPUTE INFRASTRUCTURE
            //User Write DynamoDb Lambda
            var initializeTablesHandler = new Function(this, "initializeTablesHandler", new FunctionProps
            {
                Runtime      = Runtime.DOTNET_CORE_3_1,
                FunctionName = "initializeTablesHandler",
                Timeout      = Duration.Seconds(20),
                //Where to get the code
                Code        = Code.FromAsset("Lambdas\\src\\Lambdas\\bin\\Debug\\netcoreapp3.1"),
                Handler     = "Lambdas::Lambdas.Function::InitializeTablesLambdaHandler",
                Environment = new Dictionary <string, string>
                {
                    ["ENVIRONMENT"] = environment,
                    ["USERTABLE"]   = userDynamoDbTable.TableName,
                    ["CITYTABLE"]   = cityDynamoDbTable.TableName
                }
            });

            userDynamoDbTable.GrantFullAccess(initializeTablesHandler);
            cityDynamoDbTable.GrantFullAccess(initializeTablesHandler);


            //TestPrimaryKeyTable Lambda
            var testPrimaryKeyTableLambdaHandler = new Function(this, "testPrimaryKeyTableLambdaHandler", new FunctionProps
            {
                Runtime      = Runtime.DOTNET_CORE_3_1,
                FunctionName = "testPrimaryKeyDynamoDB",
                Timeout      = Duration.Seconds(20),
                //Where to get the code
                Code        = Code.FromAsset("Lambdas\\src\\Lambdas\\bin\\Debug\\netcoreapp3.1"),
                Handler     = "Lambdas::Lambdas.Function::TestPrimaryKeyTableLambdaHandler",
                Environment = new Dictionary <string, string>
                {
                    ["ENVIRONMENT"] = environment,
                    ["USERTABLE"]   = userDynamoDbTable.TableName,
                    ["CITYTABLE"]   = cityDynamoDbTable.TableName
                }
            });

            userDynamoDbTable.GrantFullAccess(testPrimaryKeyTableLambdaHandler);
            cityDynamoDbTable.GrantFullAccess(testPrimaryKeyTableLambdaHandler);

            //TestCompositeKeyTable Lambda
            var testCompositeKeyTableLambdaHandler = new Function(this, "testCompositeKeyTableLambdaHandler", new FunctionProps
            {
                Runtime      = Runtime.DOTNET_CORE_3_1,
                FunctionName = "testCompositeKeyDynamoDBLambda",
                Timeout      = Duration.Seconds(20),
                //Where to get the code
                Code        = Code.FromAsset("Lambdas\\src\\Lambdas\\bin\\Debug\\netcoreapp3.1"),
                Handler     = "Lambdas::Lambdas.Function::TestCompositeKeyTableLambdaHandler",
                Environment = new Dictionary <string, string>
                {
                    ["ENVIRONMENT"] = environment,
                    ["USERTABLE"]   = userDynamoDbTable.TableName,
                    ["CITYTABLE"]   = cityDynamoDbTable.TableName
                }
            });

            userDynamoDbTable.GrantFullAccess(testCompositeKeyTableLambdaHandler);
            cityDynamoDbTable.GrantFullAccess(testCompositeKeyTableLambdaHandler);


            //This is the name of the API in the APIGateway
            var api = new RestApi(this, "DYNAMODBAPI", new RestApiProps
            {
                RestApiName = "dynamoDBAPI",
                Description = "This our DYNAMODBAPI",
                Deploy      = false
            });

            var deployment = new Deployment(this, "My Deployment", new DeploymentProps {
                Api = api
            });
            var stage = new Amazon.CDK.AWS.APIGateway.Stage(this, "stage name", new Amazon.CDK.AWS.APIGateway.StageProps
            {
                Deployment = deployment,
                StageName  = environment
            });

            api.DeploymentStage = stage;

            //Lambda integrations
            var initializeTablesLambdaIntegration = new LambdaIntegration(initializeTablesHandler, new LambdaIntegrationOptions
            {
                RequestTemplates = new Dictionary <string, string>
                {
                    ["application/json"] = "{ \"statusCode\": \"200\" }"
                }
            });

            var testPrimaryKeyTableLambdaIntegration = new LambdaIntegration(testPrimaryKeyTableLambdaHandler, new LambdaIntegrationOptions
            {
                RequestTemplates = new Dictionary <string, string>
                {
                    ["application/json"] = "{ \"statusCode\": \"200\" }"
                }
            });

            var testCompositeKeyTableLambdaIntegration = new LambdaIntegration(testCompositeKeyTableLambdaHandler, new LambdaIntegrationOptions
            {
                RequestTemplates = new Dictionary <string, string>
                {
                    ["application/json"] = "{ \"statusCode\": \"200\" }"
                }
            });


            //It is up to you if you want to structure your lambdas in separate APIGateway APIs (RestApi)

            //Option 1: Adding at the top level of the APIGateway API
            // api.Root.AddMethod("POST", simpleLambdaIntegration);

            //Option 2: Or break out resources under one APIGateway API as follows
            var initializeTablesResource       = api.Root.AddResource("initializetables");
            var initializeTablesMethod         = initializeTablesResource.AddMethod("POST", initializeTablesLambdaIntegration);
            var testPrimaryKeyDynamoDBResource = api.Root.AddResource("testprimarykeytable");
            var testPrimaryKeyDynamoDBMethod   = testPrimaryKeyDynamoDBResource.AddMethod("POST", testPrimaryKeyTableLambdaIntegration);
            var testCompositeKeyDBResource     = api.Root.AddResource("testcompositekeytable");
            var testCompositeKeyDynamoDBMethod = testCompositeKeyDBResource.AddMethod("POST", testCompositeKeyTableLambdaIntegration);

            //Output results of the CDK Deployment
            new CfnOutput(this, "A Region:", new CfnOutputProps()
            {
                Value = this.Region
            });
            new CfnOutput(this, "B UserDynamoDBTable PrimaryKeyTable:", new CfnOutputProps()
            {
                Value = userDynamoDbTable.TableName
            });
            new CfnOutput(this, "C CityDynamoDBTable CompositeKeyTable:", new CfnOutputProps()
            {
                Value = cityDynamoDbTable.TableName
            });

            new CfnOutput(this, "D API Gateway API:", new CfnOutputProps()
            {
                Value = api.Url
            });
            string urlPrefix = api.Url.Remove(api.Url.Length - 1);

            new CfnOutput(this, "E Initialize Tables Lambda:", new CfnOutputProps()
            {
                Value = urlPrefix + initializeTablesMethod.Resource.Path
            });
            new CfnOutput(this, "F Test Primary Key DynamoDB Lambda:", new CfnOutputProps()
            {
                Value = urlPrefix + testPrimaryKeyDynamoDBMethod.Resource.Path
            });
            new CfnOutput(this, "G Test Composite Key DynamoDB Lambda:", new CfnOutputProps()
            {
                Value = urlPrefix + testCompositeKeyDynamoDBMethod.Resource.Path
            });
        }
Example #12
0
        private void AddMethod(string httpMethod, Function function, Resource apiGatewayResource)
        {
            var integration = new LambdaIntegration(function);

            apiGatewayResource.AddMethod(httpMethod, integration);
        }
Example #13
0
        internal CdkAppStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
        {
            //Stage setting for Deployment (Need to have Deploy = false in RestApiProps to configure the Stage
            string environment = "PRD";


            //STORAGE INFRASTRUCTURE
            // default RemovalPolicy is RETAIN (on a "cdk destroy")
            //Create an S3 Bucket (s3 Buckets must be unique for each region)
            //S3 Buckets must be unique by region
            //NOTE: If you put objects in this S3 bucket you will be required to delete it manually
            var rand       = new Random();
            int randNumber = rand.Next(100000);
            var s3Bucket   = new Bucket(this, "MyS3Bucket", new BucketProps
            {
                BucketName    = (environment + "-MyS3Bucket" + randNumber).ToLower(),
                RemovalPolicy = RemovalPolicy.DESTROY
            });

            //Create a DynamoDB Table
            var dynamoDbTable = new Table(this, "User", new TableProps
            {
                TableName    = environment + "-" + "User",
                PartitionKey = new Amazon.CDK.AWS.DynamoDB.Attribute
                {
                    Name = "email",
                    Type = AttributeType.STRING
                },
                ReadCapacity  = 1,
                WriteCapacity = 1,
                RemovalPolicy = RemovalPolicy.DESTROY
            });

            //COMPUTE INFRASTRUCTURE
            //Basic Lambda
            var simpleLambdaHandler = new Function(this, "simpleLambdaHandler", new FunctionProps
            {
                Runtime      = Runtime.DOTNET_CORE_3_1,
                FunctionName = "simpleLambda",
                //Where to get the code
                Code        = Code.FromAsset("Lambdas\\src\\Lambdas\\bin\\Debug\\netcoreapp3.1"),
                Handler     = "Lambdas::Lambdas.Function::SimpleLambdaHandler",
                Environment = new Dictionary <string, string>
                {
                    ["ENVIRONMENT"] = environment,
                    ["BUCKET"]      = s3Bucket.BucketName
                }
            });

            s3Bucket.GrantReadWrite(simpleLambdaHandler);

            //S3 Lambda
            var s3LambdaHandler = new Function(this, "s3LambdaHandler", new FunctionProps
            {
                Runtime      = Runtime.DOTNET_CORE_3_1,
                Timeout      = Duration.Seconds(20),
                FunctionName = "s3Lambda",
                //Where to get the code
                Code        = Code.FromAsset("Lambdas\\src\\Lambdas\\bin\\Debug\\netcoreapp3.1"),
                Handler     = "Lambdas::Lambdas.Function::S3LambdaHandler",
                Environment = new Dictionary <string, string>
                {
                    ["ENVIRONMENT"] = environment,
                    ["BUCKET"]      = s3Bucket.BucketName,
                    ["REGION"]      = this.Region
                }
            });

            s3Bucket.GrantReadWrite(s3LambdaHandler);

            //Write DynamoDb Lambda
            var writeDynamoDBHandler = new Function(this, "writeDynamoDBHandler", new FunctionProps
            {
                Runtime      = Runtime.DOTNET_CORE_3_1,
                FunctionName = "writeDynamoDB",
                Timeout      = Duration.Seconds(20),
                //Where to get the code
                Code        = Code.FromAsset("Lambdas\\src\\Lambdas\\bin\\Debug\\netcoreapp3.1"),
                Handler     = "Lambdas::Lambdas.Function::WriteDynamoDBLambdaHandler",
                Environment = new Dictionary <string, string>
                {
                    ["ENVIRONMENT"] = environment,
                    //["BUCKET"] = s3Bucket.BucketName,
                    ["TABLE"] = dynamoDbTable.TableName
                }
            });

            dynamoDbTable.GrantFullAccess(writeDynamoDBHandler);

            //Read DynamoDb Lambda
            var readDynamoDBHandler = new Function(this, "readDynamoDBHandler", new FunctionProps
            {
                Runtime      = Runtime.DOTNET_CORE_3_1,
                FunctionName = "readDynamoDBLambda",
                Timeout      = Duration.Seconds(20),
                //Where to get the code
                Code        = Code.FromAsset("Lambdas\\src\\Lambdas\\bin\\Debug\\netcoreapp3.1"),
                Handler     = "Lambdas::Lambdas.Function::ReadDynamoDBLambdaHandler",
                Environment = new Dictionary <string, string>
                {
                    ["ENVIRONMENT"] = environment,
                    ["BUCKET"]      = s3Bucket.BucketName,
                    ["TABLE"]       = dynamoDbTable.TableName
                }
            });

            dynamoDbTable.GrantFullAccess(readDynamoDBHandler);
            s3Bucket.GrantReadWrite(readDynamoDBHandler);

            //This is the name of the API in the APIGateway
            var api = new RestApi(this, "CDKAPI", new RestApiProps
            {
                RestApiName = "cdkAPI",
                Description = "This our CDKAPI",
                Deploy      = false
            });

            var deployment = new Deployment(this, "My Deployment", new DeploymentProps {
                Api = api
            });
            var stage = new Amazon.CDK.AWS.APIGateway.Stage(this, "stage name", new Amazon.CDK.AWS.APIGateway.StageProps
            {
                Deployment = deployment,
                StageName  = environment
            });

            api.DeploymentStage = stage;

            //Lambda integrations
            var simpleLambdaIntegration = new LambdaIntegration(simpleLambdaHandler, new LambdaIntegrationOptions
            {
                RequestTemplates = new Dictionary <string, string>
                {
                    ["application/json"] = "{ \"statusCode\": \"200\" }"
                }
            });

            var s3LambdaIntegration = new LambdaIntegration(s3LambdaHandler, new LambdaIntegrationOptions
            {
                RequestTemplates = new Dictionary <string, string>
                {
                    ["application/json"] = "{ \"statusCode\": \"200\" }"
                }
            });

            var writeDynamoDbLambdaIntegration = new LambdaIntegration(writeDynamoDBHandler, new LambdaIntegrationOptions
            {
                RequestTemplates = new Dictionary <string, string>
                {
                    ["application/json"] = "{ \"statusCode\": \"200\" }"
                }
            });

            var readDynamoDbLambdaIntegration = new LambdaIntegration(readDynamoDBHandler, new LambdaIntegrationOptions
            {
                RequestTemplates = new Dictionary <string, string>
                {
                    ["application/json"] = "{ \"statusCode\": \"200\" }"
                }
            });


            //It is up to you if you want to structure your lambdas in separate APIGateway APIs (RestApi)

            //Option 1: Adding at the top level of the APIGateway API
            // api.Root.AddMethod("POST", simpleLambdaIntegration);

            //Option 2: Or break out resources under one APIGateway API as follows
            var simpleResource        = api.Root.AddResource("simple");
            var simpleMethod          = simpleResource.AddMethod("POST", simpleLambdaIntegration);
            var s3Resource            = api.Root.AddResource("s3");
            var s3Method              = s3Resource.AddMethod("POST", s3LambdaIntegration);
            var writeDynamoDBResource = api.Root.AddResource("writedynamodb");
            var writeDynamoDBMethod   = writeDynamoDBResource.AddMethod("POST", writeDynamoDbLambdaIntegration);
            var readDynamoDBResource  = api.Root.AddResource("readdynamodb");
            var readDynamoDBMethod    = readDynamoDBResource.AddMethod("POST", readDynamoDbLambdaIntegration);

            //Output results of the CDK Deployment
            new CfnOutput(this, "A Region:", new CfnOutputProps()
            {
                Value = this.Region
            });
            new CfnOutput(this, "B S3 Bucket:", new CfnOutputProps()
            {
                Value = s3Bucket.BucketName
            });
            new CfnOutput(this, "C DynamoDBTable:", new CfnOutputProps()
            {
                Value = dynamoDbTable.TableName
            });
            new CfnOutput(this, "D API Gateway API:", new CfnOutputProps()
            {
                Value = api.Url
            });
            string urlPrefix = api.Url.Remove(api.Url.Length - 1);

            new CfnOutput(this, "E Simple Lambda:", new CfnOutputProps()
            {
                Value = urlPrefix + simpleMethod.Resource.Path
            });
            new CfnOutput(this, "F S3 Lambda:", new CfnOutputProps()
            {
                Value = urlPrefix + s3Method.Resource.Path
            });
            new CfnOutput(this, "G Write DynamoDB Lambda:", new CfnOutputProps()
            {
                Value = urlPrefix + writeDynamoDBMethod.Resource.Path
            });
            new CfnOutput(this, "H Read DynamoDB Lambda:", new CfnOutputProps()
            {
                Value = urlPrefix + readDynamoDBMethod.Resource.Path
            });
        }