---
# System prepended metadata

title: AWS CDK API GateWay 連進 VPC 內的Lambdas
tags: [C#, AWS, CDK]

---

# AWS CDK API GateWay 連進 VPC 內的Lambdas

API GateWay提供連結讓外部網路連進AWS Service

VPC提供個人的Private、Public、Isolate子網域，可以讓一些AWS Service放在其中

在VPC中可以架Firewall、WAF之類的防護措施，VPC的架構可以參考

[AWS教學 - Network - VPC架構介紹(Subnet, IGW, NAT, SG, NACL)](https://www.youtube.com/watch?v=0YG3vo78gSM&t=196s)

Lambdas 提供 serverless Function，可以run Application、API等等的程式

可以藉由連結API Gateway進行觸發，也可以監聽其他Service，做出相對應的行為

----
## CDK

### VPC

```csharp=
var vpc = new Vpc(this, "MyVpc");
```
VPC如果沒有設定，預設會提供 3 個 Az，每個Az有 2 Private、1 Public Subnet、1 NAT GateWay、Cidr 10.0.0.0

### Lambdas

參考
[Creating an AWS Serverless C# DotNet Application (S3, DynamoDB, API Gateway, Lambdas(C-Sharp) and CDK)](https://www.xerris.com/insights/creating-an-aws-serverless-c-dotnet-application-s3-dynamodb-api-gateway-lambdas-c-sharp-and-cdk/)

先在cdk專案下開啟Powershell

```bash=
$ dotnet new -i Amazon.Lambda.Templates
```

會列出支援的Lambdas Trmplate

這時候選**serverless.AspNetCoreWebAPI**

因為是寫API

```bash=
$ dotnet new serverless.AspNetCoreWebAPI --name Lambdas
```

可以看到新增一個Lambdas資料夾

到CDK專案內直接加入現有專案 ( src / Lambdas / Lambdas.csproj )

這邊先寫CDK的部分，下面補充Lambdas的寫法

```csharp=
var default_handler = new Function(this, "defaultFunction", new FunctionProps
            {
                Vpc = vpc,                                      //放在VPC內
                VpcSubnets = new SubnetSelection                //放在Private網域內
                {
                    SubnetType = SubnetType.PRIVATE
                },
                Runtime = Runtime.DOTNET_CORE_3_1,              //指定程式語言
                Code = Code.FromAsset("Lambdas\\src\\Lambdas\\bin\\Debug\\netcoreapp3.1"), //程式位置
                Handler = "Lambdas::Lambdas.Controllers.DefaultController::GetJson" //程式帶入
            });
```

### API Gateway

```csharp=
            var api = new LambdaRestApi(this, "MyAPI", new LambdaRestApiProps
            {
                Handler = default_handler, //指定API gateway的後端
                RestApiName = "Myapi",
                Proxy = false
            });

            //新增API Method 把POST往後送
            var OrderSearch_API = api.Root.AddResource("OrderSearch");
            OrderSearch_API.AddMethod("POST", new LambdaIntegration(OrderSearch_handler));
```

### Lambdas

因為是寫API，就是寫Controller

主要是注意POST回傳的方法是APIGatewayProxyResponse

```csharp=
[HttpPost]
        public APIGatewayProxyResponse GetJson(Offline obj)
        {
            var result = new APIGatewayProxyResponse();
            try
            {
                var body = new
                {
                    Message = "POST Wrong Way"
                };

                var res = new APIGatewayProxyResponse
                {
                    StatusCode = 200,
                    Headers = new Dictionary<string, string> { { "Content-Type", "application/json" } },
                    Body = JsonConvert.SerializeObject(body),
                    IsBase64Encoded = false
                };
                result = res;
            }
            catch (Exception e)
            {
                result = new APIGatewayProxyResponse
                {
                    StatusCode = (int)HttpStatusCode.InternalServerError,
                    Headers = new Dictionary<string, string> { { "Content-Type", "text/plain" } },
                    Body = e.Message,
                    IsBase64Encoded = false
                };
            }
            return result;
        }
```

注意APIGatewayProxyResponse，回傳的格式有規定，

一定要有

```csharp=
var res = new APIGatewayProxyResponse
                {
                    StatusCode = 200,
                    Headers = new Dictionary<string, string> { { "Content-Type", "application/json" } },
                    Body = JsonConvert.SerializeObject(body),
                    IsBase64Encoded = false
                };
```

不然在AWS上測試會有問題

寫好之後cdk Deploy 到 AWS 上

到Lambdas測試，

![](https://i.imgur.com/8G2zprz.png)
![](https://i.imgur.com/nwgxMTj.png)


測過後就能到API Gateway測傳輸
![](https://i.imgur.com/AB0IfNx.png)
![](https://i.imgur.com/d53OBRI.png)
![](https://i.imgur.com/wyaTw04.png)



過了之後就到Postman測


cdk deploy成功後會輸出API gateway的網址
把POST裡面送
![](https://i.imgur.com/8bRitCz.png)
![](https://i.imgur.com/55xPjtf.png)


都可以的話就成功啦



參考連結:
* [Could not find the LambdaSerializerAttribute](https://github.com/timheuer/alexa-skills-dotnet/issues/61)
* [AWS CDK 部署 Lambda 與 API Gateway 服務](https://ithelp.ithome.com.tw/articles/10240180)
* [Launch a C# .NET Core Lambda Function — Step by Step](https://medium.com/devtechblogs/launch-a-c-net-core-lambda-function-in-aws-step-by-step-5e4636516758)
* [Creating an AWS Serverless C# DotNet Application (S3, DynamoDB, API Gateway, Lambdas(C-Sharp) and CDK)](https://www.xerris.com/insights/creating-an-aws-serverless-c-dotnet-application-s3-dynamodb-api-gateway-lambdas-c-sharp-and-cdk/)
* [處理 API Gateway 中的 Lambda 錯誤](https://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/handle-errors-in-lambda-integration.html)
* [教學課程：建置具有 Lambda 代理整合的 Hello World REST API](https://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/api-gateway-create-api-as-simple-proxy-for-lambda.html)
* [如何解决 API Gateway 的“malformed Lamda proxy response”或 502 状态代码？](https://aws.amazon.com/cn/premiumsupport/knowledge-center/malformed-502-api-gateway/)
* [影片教學 【Pahud Dev】EP17 - 立即開箱 Amazon API Gateway HTTP API with AWS CDK](https://www.youtube.com/watch?v=9Jr928vb1Yc&list=PLD6e3vg1Inj9qvHFkvHUJXWBuTFKcI9J_&index=11)
* [影片教學 An Introduction to AWS API Gateway with AWS Lambda (.NET Core 3.1 Application)](https://www.youtube.com/watch?v=ad2md33t1U0)
* [Create Lambda Functions in a VPC in AWS CDK](https://bobbyhadz.com/blog/aws-cdk-lambda-function-vpc)
###### tags: `AWS`,`C#`,`CDK`