The aws:apigateway/integration:Integration resource, part of the Pulumi AWS provider, connects API Gateway methods to backend targets: Lambda functions, HTTP endpoints, AWS services, or mock responses. This guide focuses on three capabilities: mock responses for testing, Lambda proxy integration, and VPC Link for private backends.
Integrations belong to API Gateway methods (which belong to resources and REST APIs). They may reference Lambda functions, VPC Links, or load balancers that must exist separately. The examples are intentionally small. Combine them with your own API structure and backend services.
Return mock responses without a backend
During API development, teams often need to test client code before backend services are ready. Mock integrations return static responses without calling any real backend.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const myDemoAPI = new aws.apigateway.RestApi("MyDemoAPI", {
name: "MyDemoAPI",
description: "This is my API for demonstration purposes",
});
const myDemoResource = new aws.apigateway.Resource("MyDemoResource", {
restApi: myDemoAPI.id,
parentId: myDemoAPI.rootResourceId,
pathPart: "mydemoresource",
});
const myDemoMethod = new aws.apigateway.Method("MyDemoMethod", {
restApi: myDemoAPI.id,
resourceId: myDemoResource.id,
httpMethod: "GET",
authorization: "NONE",
});
const myDemoIntegration = new aws.apigateway.Integration("MyDemoIntegration", {
restApi: myDemoAPI.id,
resourceId: myDemoResource.id,
httpMethod: myDemoMethod.httpMethod,
type: "MOCK",
cacheKeyParameters: ["method.request.path.param"],
cacheNamespace: "foobar",
timeoutMilliseconds: 29000,
requestParameters: {
"integration.request.header.X-Authorization": "'static'",
},
requestTemplates: {
"application/xml": `{
\\"body\\" : input.json('')
}
`,
},
});
import pulumi
import pulumi_aws as aws
my_demo_api = aws.apigateway.RestApi("MyDemoAPI",
name="MyDemoAPI",
description="This is my API for demonstration purposes")
my_demo_resource = aws.apigateway.Resource("MyDemoResource",
rest_api=my_demo_api.id,
parent_id=my_demo_api.root_resource_id,
path_part="mydemoresource")
my_demo_method = aws.apigateway.Method("MyDemoMethod",
rest_api=my_demo_api.id,
resource_id=my_demo_resource.id,
http_method="GET",
authorization="NONE")
my_demo_integration = aws.apigateway.Integration("MyDemoIntegration",
rest_api=my_demo_api.id,
resource_id=my_demo_resource.id,
http_method=my_demo_method.http_method,
type="MOCK",
cache_key_parameters=["method.request.path.param"],
cache_namespace="foobar",
timeout_milliseconds=29000,
request_parameters={
"integration.request.header.X-Authorization": "'static'",
},
request_templates={
"application/xml": """{
\"body\" : $input.json('$')
}
""",
})
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/apigateway"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
myDemoAPI, err := apigateway.NewRestApi(ctx, "MyDemoAPI", &apigateway.RestApiArgs{
Name: pulumi.String("MyDemoAPI"),
Description: pulumi.String("This is my API for demonstration purposes"),
})
if err != nil {
return err
}
myDemoResource, err := apigateway.NewResource(ctx, "MyDemoResource", &apigateway.ResourceArgs{
RestApi: myDemoAPI.ID(),
ParentId: myDemoAPI.RootResourceId,
PathPart: pulumi.String("mydemoresource"),
})
if err != nil {
return err
}
myDemoMethod, err := apigateway.NewMethod(ctx, "MyDemoMethod", &apigateway.MethodArgs{
RestApi: myDemoAPI.ID(),
ResourceId: myDemoResource.ID(),
HttpMethod: pulumi.String("GET"),
Authorization: pulumi.String("NONE"),
})
if err != nil {
return err
}
_, err = apigateway.NewIntegration(ctx, "MyDemoIntegration", &apigateway.IntegrationArgs{
RestApi: myDemoAPI.ID(),
ResourceId: myDemoResource.ID(),
HttpMethod: myDemoMethod.HttpMethod,
Type: pulumi.String("MOCK"),
CacheKeyParameters: pulumi.StringArray{
pulumi.String("method.request.path.param"),
},
CacheNamespace: pulumi.String("foobar"),
TimeoutMilliseconds: pulumi.Int(29000),
RequestParameters: pulumi.StringMap{
"integration.request.header.X-Authorization": pulumi.String("'static'"),
},
RequestTemplates: pulumi.StringMap{
"application/xml": pulumi.String("{\n \\\"body\\\" : $input.json('$')\n}\n"),
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var myDemoAPI = new Aws.ApiGateway.RestApi("MyDemoAPI", new()
{
Name = "MyDemoAPI",
Description = "This is my API for demonstration purposes",
});
var myDemoResource = new Aws.ApiGateway.Resource("MyDemoResource", new()
{
RestApi = myDemoAPI.Id,
ParentId = myDemoAPI.RootResourceId,
PathPart = "mydemoresource",
});
var myDemoMethod = new Aws.ApiGateway.Method("MyDemoMethod", new()
{
RestApi = myDemoAPI.Id,
ResourceId = myDemoResource.Id,
HttpMethod = "GET",
Authorization = "NONE",
});
var myDemoIntegration = new Aws.ApiGateway.Integration("MyDemoIntegration", new()
{
RestApi = myDemoAPI.Id,
ResourceId = myDemoResource.Id,
HttpMethod = myDemoMethod.HttpMethod,
Type = "MOCK",
CacheKeyParameters = new[]
{
"method.request.path.param",
},
CacheNamespace = "foobar",
TimeoutMilliseconds = 29000,
RequestParameters =
{
{ "integration.request.header.X-Authorization", "'static'" },
},
RequestTemplates =
{
{ "application/xml", @"{
\""body\"" : $input.json('$')
}
" },
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.apigateway.RestApi;
import com.pulumi.aws.apigateway.RestApiArgs;
import com.pulumi.aws.apigateway.Resource;
import com.pulumi.aws.apigateway.ResourceArgs;
import com.pulumi.aws.apigateway.Method;
import com.pulumi.aws.apigateway.MethodArgs;
import com.pulumi.aws.apigateway.Integration;
import com.pulumi.aws.apigateway.IntegrationArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var myDemoAPI = new RestApi("myDemoAPI", RestApiArgs.builder()
.name("MyDemoAPI")
.description("This is my API for demonstration purposes")
.build());
var myDemoResource = new Resource("myDemoResource", ResourceArgs.builder()
.restApi(myDemoAPI.id())
.parentId(myDemoAPI.rootResourceId())
.pathPart("mydemoresource")
.build());
var myDemoMethod = new Method("myDemoMethod", MethodArgs.builder()
.restApi(myDemoAPI.id())
.resourceId(myDemoResource.id())
.httpMethod("GET")
.authorization("NONE")
.build());
var myDemoIntegration = new Integration("myDemoIntegration", IntegrationArgs.builder()
.restApi(myDemoAPI.id())
.resourceId(myDemoResource.id())
.httpMethod(myDemoMethod.httpMethod())
.type("MOCK")
.cacheKeyParameters("method.request.path.param")
.cacheNamespace("foobar")
.timeoutMilliseconds(29000)
.requestParameters(Map.of("integration.request.header.X-Authorization", "'static'"))
.requestTemplates(Map.of("application/xml", """
{
\"body\" : $input.json('$')
}
"""))
.build());
}
}
resources:
myDemoAPI:
type: aws:apigateway:RestApi
name: MyDemoAPI
properties:
name: MyDemoAPI
description: This is my API for demonstration purposes
myDemoResource:
type: aws:apigateway:Resource
name: MyDemoResource
properties:
restApi: ${myDemoAPI.id}
parentId: ${myDemoAPI.rootResourceId}
pathPart: mydemoresource
myDemoMethod:
type: aws:apigateway:Method
name: MyDemoMethod
properties:
restApi: ${myDemoAPI.id}
resourceId: ${myDemoResource.id}
httpMethod: GET
authorization: NONE
myDemoIntegration:
type: aws:apigateway:Integration
name: MyDemoIntegration
properties:
restApi: ${myDemoAPI.id}
resourceId: ${myDemoResource.id}
httpMethod: ${myDemoMethod.httpMethod}
type: MOCK
cacheKeyParameters:
- method.request.path.param
cacheNamespace: foobar
timeoutMilliseconds: 29000
requestParameters:
integration.request.header.X-Authorization: '''static'''
requestTemplates:
application/xml: |
{
\"body\" : $input.json('$')
}
The type property set to MOCK tells API Gateway to return a response without invoking any backend. The requestTemplates property transforms incoming requests into the format your mock response expects. The timeoutMilliseconds property controls how long API Gateway waits before timing out (default is 29 seconds).
Invoke Lambda functions with proxy integration
Most serverless APIs route requests to Lambda functions, passing the entire HTTP request as a JSON event and returning the function’s response directly to the client.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
import * as std from "@pulumi/std";
const config = new pulumi.Config();
const myregion = config.requireObject<any>("myregion");
const accountId = config.requireObject<any>("accountId");
// API Gateway
const api = new aws.apigateway.RestApi("api", {name: "myapi"});
const resource = new aws.apigateway.Resource("resource", {
pathPart: "resource",
parentId: api.rootResourceId,
restApi: api.id,
});
const method = new aws.apigateway.Method("method", {
restApi: api.id,
resourceId: resource.id,
httpMethod: "GET",
authorization: "NONE",
});
// IAM
const assumeRole = aws.iam.getPolicyDocument({
statements: [{
effect: "Allow",
principals: [{
type: "Service",
identifiers: ["lambda.amazonaws.com"],
}],
actions: ["sts:AssumeRole"],
}],
});
const role = new aws.iam.Role("role", {
name: "myrole",
assumeRolePolicy: assumeRole.then(assumeRole => assumeRole.json),
});
const lambda = new aws.lambda.Function("lambda", {
code: new pulumi.asset.FileArchive("lambda.zip"),
name: "mylambda",
role: role.arn,
handler: "lambda.lambda_handler",
runtime: aws.lambda.Runtime.Python3d12,
sourceCodeHash: std.filebase64sha256({
input: "lambda.zip",
}).then(invoke => invoke.result),
});
const integration = new aws.apigateway.Integration("integration", {
restApi: api.id,
resourceId: resource.id,
httpMethod: method.httpMethod,
integrationHttpMethod: "POST",
type: "AWS_PROXY",
uri: lambda.invokeArn,
});
// Lambda
const apigwLambda = new aws.lambda.Permission("apigw_lambda", {
statementId: "AllowExecutionFromAPIGateway",
action: "lambda:InvokeFunction",
"function": lambda.name,
principal: "apigateway.amazonaws.com",
sourceArn: pulumi.interpolate`arn:aws:execute-api:${myregion}:${accountId}:${api.id}/*/${method.httpMethod}${resource.path}`,
});
import pulumi
import pulumi_aws as aws
import pulumi_std as std
config = pulumi.Config()
myregion = config.require_object("myregion")
account_id = config.require_object("accountId")
# API Gateway
api = aws.apigateway.RestApi("api", name="myapi")
resource = aws.apigateway.Resource("resource",
path_part="resource",
parent_id=api.root_resource_id,
rest_api=api.id)
method = aws.apigateway.Method("method",
rest_api=api.id,
resource_id=resource.id,
http_method="GET",
authorization="NONE")
# IAM
assume_role = aws.iam.get_policy_document(statements=[{
"effect": "Allow",
"principals": [{
"type": "Service",
"identifiers": ["lambda.amazonaws.com"],
}],
"actions": ["sts:AssumeRole"],
}])
role = aws.iam.Role("role",
name="myrole",
assume_role_policy=assume_role.json)
lambda_ = aws.lambda_.Function("lambda",
code=pulumi.FileArchive("lambda.zip"),
name="mylambda",
role=role.arn,
handler="lambda.lambda_handler",
runtime=aws.lambda_.Runtime.PYTHON3D12,
source_code_hash=std.filebase64sha256(input="lambda.zip").result)
integration = aws.apigateway.Integration("integration",
rest_api=api.id,
resource_id=resource.id,
http_method=method.http_method,
integration_http_method="POST",
type="AWS_PROXY",
uri=lambda_.invoke_arn)
# Lambda
apigw_lambda = aws.lambda_.Permission("apigw_lambda",
statement_id="AllowExecutionFromAPIGateway",
action="lambda:InvokeFunction",
function=lambda_.name,
principal="apigateway.amazonaws.com",
source_arn=pulumi.Output.all(
id=api.id,
http_method=method.http_method,
path=resource.path
).apply(lambda resolved_outputs: f"arn:aws:execute-api:{myregion}:{account_id}:{resolved_outputs['id']}/*/{resolved_outputs['http_method']}{resolved_outputs['path']}")
)
package main
import (
"fmt"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/apigateway"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/iam"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/lambda"
"github.com/pulumi/pulumi-std/sdk/go/std"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi/config"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
cfg := config.New(ctx, "")
myregion := cfg.RequireObject("myregion")
accountId := cfg.RequireObject("accountId")
// API Gateway
api, err := apigateway.NewRestApi(ctx, "api", &apigateway.RestApiArgs{
Name: pulumi.String("myapi"),
})
if err != nil {
return err
}
resource, err := apigateway.NewResource(ctx, "resource", &apigateway.ResourceArgs{
PathPart: pulumi.String("resource"),
ParentId: api.RootResourceId,
RestApi: api.ID(),
})
if err != nil {
return err
}
method, err := apigateway.NewMethod(ctx, "method", &apigateway.MethodArgs{
RestApi: api.ID(),
ResourceId: resource.ID(),
HttpMethod: pulumi.String("GET"),
Authorization: pulumi.String("NONE"),
})
if err != nil {
return err
}
// IAM
assumeRole, err := iam.GetPolicyDocument(ctx, &iam.GetPolicyDocumentArgs{
Statements: []iam.GetPolicyDocumentStatement{
{
Effect: pulumi.StringRef("Allow"),
Principals: []iam.GetPolicyDocumentStatementPrincipal{
{
Type: "Service",
Identifiers: []string{
"lambda.amazonaws.com",
},
},
},
Actions: []string{
"sts:AssumeRole",
},
},
},
}, nil)
if err != nil {
return err
}
role, err := iam.NewRole(ctx, "role", &iam.RoleArgs{
Name: pulumi.String("myrole"),
AssumeRolePolicy: pulumi.String(assumeRole.Json),
})
if err != nil {
return err
}
invokeFilebase64sha256, err := std.Filebase64sha256(ctx, &std.Filebase64sha256Args{
Input: "lambda.zip",
}, nil)
if err != nil {
return err
}
lambda, err := lambda.NewFunction(ctx, "lambda", &lambda.FunctionArgs{
Code: pulumi.NewFileArchive("lambda.zip"),
Name: pulumi.String("mylambda"),
Role: role.Arn,
Handler: pulumi.String("lambda.lambda_handler"),
Runtime: pulumi.String(lambda.RuntimePython3d12),
SourceCodeHash: pulumi.String(invokeFilebase64sha256.Result),
})
if err != nil {
return err
}
_, err = apigateway.NewIntegration(ctx, "integration", &apigateway.IntegrationArgs{
RestApi: api.ID(),
ResourceId: resource.ID(),
HttpMethod: method.HttpMethod,
IntegrationHttpMethod: pulumi.String("POST"),
Type: pulumi.String("AWS_PROXY"),
Uri: lambda.InvokeArn,
})
if err != nil {
return err
}
// Lambda
_, err = lambda.NewPermission(ctx, "apigw_lambda", &lambda.PermissionArgs{
StatementId: pulumi.String("AllowExecutionFromAPIGateway"),
Action: pulumi.String("lambda:InvokeFunction"),
Function: lambda.Name,
Principal: pulumi.String("apigateway.amazonaws.com"),
SourceArn: pulumi.All(api.ID(), method.HttpMethod, resource.Path).ApplyT(func(_args []interface{}) (string, error) {
id := _args[0].(string)
httpMethod := _args[1].(string)
path := _args[2].(string)
return fmt.Sprintf("arn:aws:execute-api:%v:%v:%v/*/%v%v", myregion, accountId, id, httpMethod, path), nil
}).(pulumi.StringOutput),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
using Std = Pulumi.Std;
return await Deployment.RunAsync(() =>
{
var config = new Config();
var myregion = config.RequireObject<dynamic>("myregion");
var accountId = config.RequireObject<dynamic>("accountId");
// API Gateway
var api = new Aws.ApiGateway.RestApi("api", new()
{
Name = "myapi",
});
var resource = new Aws.ApiGateway.Resource("resource", new()
{
PathPart = "resource",
ParentId = api.RootResourceId,
RestApi = api.Id,
});
var method = new Aws.ApiGateway.Method("method", new()
{
RestApi = api.Id,
ResourceId = resource.Id,
HttpMethod = "GET",
Authorization = "NONE",
});
// IAM
var assumeRole = Aws.Iam.GetPolicyDocument.Invoke(new()
{
Statements = new[]
{
new Aws.Iam.Inputs.GetPolicyDocumentStatementInputArgs
{
Effect = "Allow",
Principals = new[]
{
new Aws.Iam.Inputs.GetPolicyDocumentStatementPrincipalInputArgs
{
Type = "Service",
Identifiers = new[]
{
"lambda.amazonaws.com",
},
},
},
Actions = new[]
{
"sts:AssumeRole",
},
},
},
});
var role = new Aws.Iam.Role("role", new()
{
Name = "myrole",
AssumeRolePolicy = assumeRole.Apply(getPolicyDocumentResult => getPolicyDocumentResult.Json),
});
var lambda = new Aws.Lambda.Function("lambda", new()
{
Code = new FileArchive("lambda.zip"),
Name = "mylambda",
Role = role.Arn,
Handler = "lambda.lambda_handler",
Runtime = Aws.Lambda.Runtime.Python3d12,
SourceCodeHash = Std.Filebase64sha256.Invoke(new()
{
Input = "lambda.zip",
}).Apply(invoke => invoke.Result),
});
var integration = new Aws.ApiGateway.Integration("integration", new()
{
RestApi = api.Id,
ResourceId = resource.Id,
HttpMethod = method.HttpMethod,
IntegrationHttpMethod = "POST",
Type = "AWS_PROXY",
Uri = lambda.InvokeArn,
});
// Lambda
var apigwLambda = new Aws.Lambda.Permission("apigw_lambda", new()
{
StatementId = "AllowExecutionFromAPIGateway",
Action = "lambda:InvokeFunction",
Function = lambda.Name,
Principal = "apigateway.amazonaws.com",
SourceArn = Output.Tuple(api.Id, method.HttpMethod, resource.Path).Apply(values =>
{
var id = values.Item1;
var httpMethod = values.Item2;
var path = values.Item3;
return $"arn:aws:execute-api:{myregion}:{accountId}:{id}/*/{httpMethod}{path}";
}),
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.apigateway.RestApi;
import com.pulumi.aws.apigateway.RestApiArgs;
import com.pulumi.aws.apigateway.Resource;
import com.pulumi.aws.apigateway.ResourceArgs;
import com.pulumi.aws.apigateway.Method;
import com.pulumi.aws.apigateway.MethodArgs;
import com.pulumi.aws.iam.IamFunctions;
import com.pulumi.aws.iam.inputs.GetPolicyDocumentArgs;
import com.pulumi.aws.iam.Role;
import com.pulumi.aws.iam.RoleArgs;
import com.pulumi.aws.lambda.Function;
import com.pulumi.aws.lambda.FunctionArgs;
import com.pulumi.std.StdFunctions;
import com.pulumi.std.inputs.Filebase64sha256Args;
import com.pulumi.aws.apigateway.Integration;
import com.pulumi.aws.apigateway.IntegrationArgs;
import com.pulumi.aws.lambda.Permission;
import com.pulumi.aws.lambda.PermissionArgs;
import com.pulumi.asset.FileArchive;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
final var config = ctx.config();
final var myregion = config.get("myregion");
final var accountId = config.get("accountId");
// API Gateway
var api = new RestApi("api", RestApiArgs.builder()
.name("myapi")
.build());
var resource = new Resource("resource", ResourceArgs.builder()
.pathPart("resource")
.parentId(api.rootResourceId())
.restApi(api.id())
.build());
var method = new Method("method", MethodArgs.builder()
.restApi(api.id())
.resourceId(resource.id())
.httpMethod("GET")
.authorization("NONE")
.build());
// IAM
final var assumeRole = IamFunctions.getPolicyDocument(GetPolicyDocumentArgs.builder()
.statements(GetPolicyDocumentStatementArgs.builder()
.effect("Allow")
.principals(GetPolicyDocumentStatementPrincipalArgs.builder()
.type("Service")
.identifiers("lambda.amazonaws.com")
.build())
.actions("sts:AssumeRole")
.build())
.build());
var role = new Role("role", RoleArgs.builder()
.name("myrole")
.assumeRolePolicy(assumeRole.json())
.build());
var lambda = new Function("lambda", FunctionArgs.builder()
.code(new FileArchive("lambda.zip"))
.name("mylambda")
.role(role.arn())
.handler("lambda.lambda_handler")
.runtime("python3.12")
.sourceCodeHash(StdFunctions.filebase64sha256(Filebase64sha256Args.builder()
.input("lambda.zip")
.build()).result())
.build());
var integration = new Integration("integration", IntegrationArgs.builder()
.restApi(api.id())
.resourceId(resource.id())
.httpMethod(method.httpMethod())
.integrationHttpMethod("POST")
.type("AWS_PROXY")
.uri(lambda.invokeArn())
.build());
// Lambda
var apigwLambda = new Permission("apigwLambda", PermissionArgs.builder()
.statementId("AllowExecutionFromAPIGateway")
.action("lambda:InvokeFunction")
.function(lambda.name())
.principal("apigateway.amazonaws.com")
.sourceArn(Output.tuple(api.id(), method.httpMethod(), resource.path()).applyValue(values -> {
var id = values.t1;
var httpMethod = values.t2;
var path = values.t3;
return String.format("arn:aws:execute-api:%s:%s:%s/*/%s%s", myregion,accountId,id,httpMethod,path);
}))
.build());
}
}
configuration:
# Variables
myregion:
type: dynamic
accountId:
type: dynamic
resources:
# API Gateway
api:
type: aws:apigateway:RestApi
properties:
name: myapi
resource:
type: aws:apigateway:Resource
properties:
pathPart: resource
parentId: ${api.rootResourceId}
restApi: ${api.id}
method:
type: aws:apigateway:Method
properties:
restApi: ${api.id}
resourceId: ${resource.id}
httpMethod: GET
authorization: NONE
integration:
type: aws:apigateway:Integration
properties:
restApi: ${api.id}
resourceId: ${resource.id}
httpMethod: ${method.httpMethod}
integrationHttpMethod: POST
type: AWS_PROXY
uri: ${lambda.invokeArn}
# Lambda
apigwLambda:
type: aws:lambda:Permission
name: apigw_lambda
properties:
statementId: AllowExecutionFromAPIGateway
action: lambda:InvokeFunction
function: ${lambda.name}
principal: apigateway.amazonaws.com
sourceArn: arn:aws:execute-api:${myregion}:${accountId}:${api.id}/*/${method.httpMethod}${resource.path}
lambda:
type: aws:lambda:Function
properties:
code:
fn::FileArchive: lambda.zip
name: mylambda
role: ${role.arn}
handler: lambda.lambda_handler
runtime: python3.12
sourceCodeHash:
fn::invoke:
function: std:filebase64sha256
arguments:
input: lambda.zip
return: result
role:
type: aws:iam:Role
properties:
name: myrole
assumeRolePolicy: ${assumeRole.json}
variables:
# IAM
assumeRole:
fn::invoke:
function: aws:iam:getPolicyDocument
arguments:
statements:
- effect: Allow
principals:
- type: Service
identifiers:
- lambda.amazonaws.com
actions:
- sts:AssumeRole
When type is AWS_PROXY, API Gateway forwards the complete HTTP request to Lambda and expects a response with statusCode, headers, and body. The integrationHttpMethod must be POST for Lambda invocations. The uri property points to the Lambda function’s invoke ARN. The lambda.Permission resource grants API Gateway permission to invoke your function.
Connect to private backends via VPC Link
Applications with internal services behind network load balancers need private integrations to route API Gateway traffic through a VPC Link without exposing endpoints to the public internet.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const config = new pulumi.Config();
const name = config.requireObject<any>("name");
const subnetId = config.requireObject<any>("subnetId");
const test = new aws.lb.LoadBalancer("test", {
name: name,
internal: true,
loadBalancerType: "network",
subnets: [subnetId],
});
const testVpcLink = new aws.apigateway.VpcLink("test", {
name: name,
targetArn: test.arn,
});
const testRestApi = new aws.apigateway.RestApi("test", {name: name});
const testResource = new aws.apigateway.Resource("test", {
restApi: testRestApi.id,
parentId: testRestApi.rootResourceId,
pathPart: "test",
});
const testMethod = new aws.apigateway.Method("test", {
restApi: testRestApi.id,
resourceId: testResource.id,
httpMethod: "GET",
authorization: "NONE",
requestModels: {
"application/json": "Error",
},
});
const testIntegration = new aws.apigateway.Integration("test", {
restApi: testRestApi.id,
resourceId: testResource.id,
httpMethod: testMethod.httpMethod,
requestTemplates: {
"application/json": "",
"application/xml": `#set(inputRoot = input.path(''))
{ }`,
},
requestParameters: {
"integration.request.header.X-Authorization": "'static'",
"integration.request.header.X-Foo": "'Bar'",
},
type: "HTTP",
uri: "https://www.google.de",
integrationHttpMethod: "GET",
passthroughBehavior: "WHEN_NO_MATCH",
contentHandling: "CONVERT_TO_TEXT",
connectionType: "VPC_LINK",
connectionId: testVpcLink.id,
});
import pulumi
import pulumi_aws as aws
config = pulumi.Config()
name = config.require_object("name")
subnet_id = config.require_object("subnetId")
test = aws.lb.LoadBalancer("test",
name=name,
internal=True,
load_balancer_type="network",
subnets=[subnet_id])
test_vpc_link = aws.apigateway.VpcLink("test",
name=name,
target_arn=test.arn)
test_rest_api = aws.apigateway.RestApi("test", name=name)
test_resource = aws.apigateway.Resource("test",
rest_api=test_rest_api.id,
parent_id=test_rest_api.root_resource_id,
path_part="test")
test_method = aws.apigateway.Method("test",
rest_api=test_rest_api.id,
resource_id=test_resource.id,
http_method="GET",
authorization="NONE",
request_models={
"application/json": "Error",
})
test_integration = aws.apigateway.Integration("test",
rest_api=test_rest_api.id,
resource_id=test_resource.id,
http_method=test_method.http_method,
request_templates={
"application/json": "",
"application/xml": """#set($inputRoot = $input.path('$'))
{ }""",
},
request_parameters={
"integration.request.header.X-Authorization": "'static'",
"integration.request.header.X-Foo": "'Bar'",
},
type="HTTP",
uri="https://www.google.de",
integration_http_method="GET",
passthrough_behavior="WHEN_NO_MATCH",
content_handling="CONVERT_TO_TEXT",
connection_type="VPC_LINK",
connection_id=test_vpc_link.id)
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/apigateway"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/lb"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi/config"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
cfg := config.New(ctx, "")
name := cfg.RequireObject("name")
subnetId := cfg.RequireObject("subnetId")
test, err := lb.NewLoadBalancer(ctx, "test", &lb.LoadBalancerArgs{
Name: pulumi.Any(name),
Internal: pulumi.Bool(true),
LoadBalancerType: pulumi.String("network"),
Subnets: pulumi.StringArray{
subnetId,
},
})
if err != nil {
return err
}
testVpcLink, err := apigateway.NewVpcLink(ctx, "test", &apigateway.VpcLinkArgs{
Name: pulumi.Any(name),
TargetArn: test.Arn,
})
if err != nil {
return err
}
testRestApi, err := apigateway.NewRestApi(ctx, "test", &apigateway.RestApiArgs{
Name: pulumi.Any(name),
})
if err != nil {
return err
}
testResource, err := apigateway.NewResource(ctx, "test", &apigateway.ResourceArgs{
RestApi: testRestApi.ID(),
ParentId: testRestApi.RootResourceId,
PathPart: pulumi.String("test"),
})
if err != nil {
return err
}
testMethod, err := apigateway.NewMethod(ctx, "test", &apigateway.MethodArgs{
RestApi: testRestApi.ID(),
ResourceId: testResource.ID(),
HttpMethod: pulumi.String("GET"),
Authorization: pulumi.String("NONE"),
RequestModels: pulumi.StringMap{
"application/json": pulumi.String("Error"),
},
})
if err != nil {
return err
}
_, err = apigateway.NewIntegration(ctx, "test", &apigateway.IntegrationArgs{
RestApi: testRestApi.ID(),
ResourceId: testResource.ID(),
HttpMethod: testMethod.HttpMethod,
RequestTemplates: pulumi.StringMap{
"application/json": pulumi.String(""),
"application/xml": pulumi.String("#set($inputRoot = $input.path('$'))\n{ }"),
},
RequestParameters: pulumi.StringMap{
"integration.request.header.X-Authorization": pulumi.String("'static'"),
"integration.request.header.X-Foo": pulumi.String("'Bar'"),
},
Type: pulumi.String("HTTP"),
Uri: pulumi.String("https://www.google.de"),
IntegrationHttpMethod: pulumi.String("GET"),
PassthroughBehavior: pulumi.String("WHEN_NO_MATCH"),
ContentHandling: pulumi.String("CONVERT_TO_TEXT"),
ConnectionType: pulumi.String("VPC_LINK"),
ConnectionId: testVpcLink.ID(),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var config = new Config();
var name = config.RequireObject<dynamic>("name");
var subnetId = config.RequireObject<dynamic>("subnetId");
var test = new Aws.LB.LoadBalancer("test", new()
{
Name = name,
Internal = true,
LoadBalancerType = "network",
Subnets = new[]
{
subnetId,
},
});
var testVpcLink = new Aws.ApiGateway.VpcLink("test", new()
{
Name = name,
TargetArn = test.Arn,
});
var testRestApi = new Aws.ApiGateway.RestApi("test", new()
{
Name = name,
});
var testResource = new Aws.ApiGateway.Resource("test", new()
{
RestApi = testRestApi.Id,
ParentId = testRestApi.RootResourceId,
PathPart = "test",
});
var testMethod = new Aws.ApiGateway.Method("test", new()
{
RestApi = testRestApi.Id,
ResourceId = testResource.Id,
HttpMethod = "GET",
Authorization = "NONE",
RequestModels =
{
{ "application/json", "Error" },
},
});
var testIntegration = new Aws.ApiGateway.Integration("test", new()
{
RestApi = testRestApi.Id,
ResourceId = testResource.Id,
HttpMethod = testMethod.HttpMethod,
RequestTemplates =
{
{ "application/json", "" },
{ "application/xml", @"#set($inputRoot = $input.path('$'))
{ }" },
},
RequestParameters =
{
{ "integration.request.header.X-Authorization", "'static'" },
{ "integration.request.header.X-Foo", "'Bar'" },
},
Type = "HTTP",
Uri = "https://www.google.de",
IntegrationHttpMethod = "GET",
PassthroughBehavior = "WHEN_NO_MATCH",
ContentHandling = "CONVERT_TO_TEXT",
ConnectionType = "VPC_LINK",
ConnectionId = testVpcLink.Id,
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.lb.LoadBalancer;
import com.pulumi.aws.lb.LoadBalancerArgs;
import com.pulumi.aws.apigateway.VpcLink;
import com.pulumi.aws.apigateway.VpcLinkArgs;
import com.pulumi.aws.apigateway.RestApi;
import com.pulumi.aws.apigateway.RestApiArgs;
import com.pulumi.aws.apigateway.Resource;
import com.pulumi.aws.apigateway.ResourceArgs;
import com.pulumi.aws.apigateway.Method;
import com.pulumi.aws.apigateway.MethodArgs;
import com.pulumi.aws.apigateway.Integration;
import com.pulumi.aws.apigateway.IntegrationArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
final var config = ctx.config();
final var name = config.get("name");
final var subnetId = config.get("subnetId");
var test = new LoadBalancer("test", LoadBalancerArgs.builder()
.name(name)
.internal(true)
.loadBalancerType("network")
.subnets(subnetId)
.build());
var testVpcLink = new VpcLink("testVpcLink", VpcLinkArgs.builder()
.name(name)
.targetArn(test.arn())
.build());
var testRestApi = new RestApi("testRestApi", RestApiArgs.builder()
.name(name)
.build());
var testResource = new Resource("testResource", ResourceArgs.builder()
.restApi(testRestApi.id())
.parentId(testRestApi.rootResourceId())
.pathPart("test")
.build());
var testMethod = new Method("testMethod", MethodArgs.builder()
.restApi(testRestApi.id())
.resourceId(testResource.id())
.httpMethod("GET")
.authorization("NONE")
.requestModels(Map.of("application/json", "Error"))
.build());
var testIntegration = new Integration("testIntegration", IntegrationArgs.builder()
.restApi(testRestApi.id())
.resourceId(testResource.id())
.httpMethod(testMethod.httpMethod())
.requestTemplates(Map.ofEntries(
Map.entry("application/json", ""),
Map.entry("application/xml", """
#set($inputRoot = $input.path('$'))
{ } """)
))
.requestParameters(Map.ofEntries(
Map.entry("integration.request.header.X-Authorization", "'static'"),
Map.entry("integration.request.header.X-Foo", "'Bar'")
))
.type("HTTP")
.uri("https://www.google.de")
.integrationHttpMethod("GET")
.passthroughBehavior("WHEN_NO_MATCH")
.contentHandling("CONVERT_TO_TEXT")
.connectionType("VPC_LINK")
.connectionId(testVpcLink.id())
.build());
}
}
configuration:
name:
type: dynamic
subnetId:
type: dynamic
resources:
test:
type: aws:lb:LoadBalancer
properties:
name: ${name}
internal: true
loadBalancerType: network
subnets:
- ${subnetId}
testVpcLink:
type: aws:apigateway:VpcLink
name: test
properties:
name: ${name}
targetArn: ${test.arn}
testRestApi:
type: aws:apigateway:RestApi
name: test
properties:
name: ${name}
testResource:
type: aws:apigateway:Resource
name: test
properties:
restApi: ${testRestApi.id}
parentId: ${testRestApi.rootResourceId}
pathPart: test
testMethod:
type: aws:apigateway:Method
name: test
properties:
restApi: ${testRestApi.id}
resourceId: ${testResource.id}
httpMethod: GET
authorization: NONE
requestModels:
application/json: Error
testIntegration:
type: aws:apigateway:Integration
name: test
properties:
restApi: ${testRestApi.id}
resourceId: ${testResource.id}
httpMethod: ${testMethod.httpMethod}
requestTemplates:
application/json: ""
application/xml: |-
#set($inputRoot = $input.path('$'))
{ }
requestParameters:
integration.request.header.X-Authorization: '''static'''
integration.request.header.X-Foo: '''Bar'''
type: HTTP
uri: https://www.google.de
integrationHttpMethod: GET
passthroughBehavior: WHEN_NO_MATCH
contentHandling: CONVERT_TO_TEXT
connectionType: VPC_LINK
connectionId: ${testVpcLink.id}
The connectionType property set to VPC_LINK routes traffic through a VpcLink resource, which connects to a network load balancer in your VPC. The connectionId references the VPC Link. The type property is HTTP for standard HTTP integrations. This configuration keeps your backend services private while exposing them through API Gateway.
Route to application load balancers with VPC Link V2
VPC Link V2 supports application load balancers in addition to network load balancers, enabling private integrations with ALB-based services.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const example = new aws.apigatewayv2.VpcLink("example", {
name: "example",
securityGroupIds: [exampleAwsSecurityGroup.id],
subnetIds: exampleAwsSubnet.map(__item => __item.id),
});
const exampleLoadBalancer = new aws.lb.LoadBalancer("example", {
name: "example-alb",
internal: true,
loadBalancerType: "application",
securityGroups: [exampleAwsSecurityGroup.id],
subnets: exampleAwsSubnet.map(__item => __item.id),
});
const exampleListener = new aws.lb.Listener("example", {
loadBalancerArn: exampleLoadBalancer.arn,
port: 80,
protocol: "HTTP",
defaultActions: [{
type: "fixed-response",
fixedResponse: {
contentType: "text/plain",
messageBody: "OK",
statusCode: "200",
},
}],
});
const exampleRestApi = new aws.apigateway.RestApi("example", {name: "example"});
const exampleResource = new aws.apigateway.Resource("example", {
restApi: exampleRestApi.id,
parentId: exampleRestApi.rootResourceId,
pathPart: "example",
});
const exampleMethod = new aws.apigateway.Method("example", {
restApi: exampleRestApi.id,
resourceId: exampleResource.id,
httpMethod: "GET",
authorization: "NONE",
});
const exampleIntegration = new aws.apigateway.Integration("example", {
restApi: exampleRestApi.id,
resourceId: exampleResource.id,
httpMethod: exampleMethod.httpMethod,
integrationHttpMethod: "GET",
type: "HTTP_PROXY",
connectionType: "VPC_LINK",
connectionId: example.id,
integrationTarget: exampleLoadBalancer.arn,
uri: "http://example.com",
});
import pulumi
import pulumi_aws as aws
example = aws.apigatewayv2.VpcLink("example",
name="example",
security_group_ids=[example_aws_security_group["id"]],
subnet_ids=[__item["id"] for __item in example_aws_subnet])
example_load_balancer = aws.lb.LoadBalancer("example",
name="example-alb",
internal=True,
load_balancer_type="application",
security_groups=[example_aws_security_group["id"]],
subnets=[__item["id"] for __item in example_aws_subnet])
example_listener = aws.lb.Listener("example",
load_balancer_arn=example_load_balancer.arn,
port=80,
protocol="HTTP",
default_actions=[{
"type": "fixed-response",
"fixed_response": {
"content_type": "text/plain",
"message_body": "OK",
"status_code": "200",
},
}])
example_rest_api = aws.apigateway.RestApi("example", name="example")
example_resource = aws.apigateway.Resource("example",
rest_api=example_rest_api.id,
parent_id=example_rest_api.root_resource_id,
path_part="example")
example_method = aws.apigateway.Method("example",
rest_api=example_rest_api.id,
resource_id=example_resource.id,
http_method="GET",
authorization="NONE")
example_integration = aws.apigateway.Integration("example",
rest_api=example_rest_api.id,
resource_id=example_resource.id,
http_method=example_method.http_method,
integration_http_method="GET",
type="HTTP_PROXY",
connection_type="VPC_LINK",
connection_id=example.id,
integration_target=example_load_balancer.arn,
uri="http://example.com")
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/apigateway"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/apigatewayv2"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/lb"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
var splat0 []interface{}
for _, val0 := range exampleAwsSubnet {
splat0 = append(splat0, val0.Id)
}
example, err := apigatewayv2.NewVpcLink(ctx, "example", &apigatewayv2.VpcLinkArgs{
Name: pulumi.String("example"),
SecurityGroupIds: pulumi.StringArray{
exampleAwsSecurityGroup.Id,
},
SubnetIds: toPulumiArray(splat0),
})
if err != nil {
return err
}
var splat1 []interface{}
for _, val0 := range exampleAwsSubnet {
splat1 = append(splat1, val0.Id)
}
exampleLoadBalancer, err := lb.NewLoadBalancer(ctx, "example", &lb.LoadBalancerArgs{
Name: pulumi.String("example-alb"),
Internal: pulumi.Bool(true),
LoadBalancerType: pulumi.String("application"),
SecurityGroups: pulumi.StringArray{
exampleAwsSecurityGroup.Id,
},
Subnets: toPulumiArray(splat1),
})
if err != nil {
return err
}
_, err = lb.NewListener(ctx, "example", &lb.ListenerArgs{
LoadBalancerArn: exampleLoadBalancer.Arn,
Port: pulumi.Int(80),
Protocol: pulumi.String("HTTP"),
DefaultActions: lb.ListenerDefaultActionArray{
&lb.ListenerDefaultActionArgs{
Type: pulumi.String("fixed-response"),
FixedResponse: &lb.ListenerDefaultActionFixedResponseArgs{
ContentType: pulumi.String("text/plain"),
MessageBody: pulumi.String("OK"),
StatusCode: pulumi.String("200"),
},
},
},
})
if err != nil {
return err
}
exampleRestApi, err := apigateway.NewRestApi(ctx, "example", &apigateway.RestApiArgs{
Name: pulumi.String("example"),
})
if err != nil {
return err
}
exampleResource, err := apigateway.NewResource(ctx, "example", &apigateway.ResourceArgs{
RestApi: exampleRestApi.ID(),
ParentId: exampleRestApi.RootResourceId,
PathPart: pulumi.String("example"),
})
if err != nil {
return err
}
exampleMethod, err := apigateway.NewMethod(ctx, "example", &apigateway.MethodArgs{
RestApi: exampleRestApi.ID(),
ResourceId: exampleResource.ID(),
HttpMethod: pulumi.String("GET"),
Authorization: pulumi.String("NONE"),
})
if err != nil {
return err
}
_, err = apigateway.NewIntegration(ctx, "example", &apigateway.IntegrationArgs{
RestApi: exampleRestApi.ID(),
ResourceId: exampleResource.ID(),
HttpMethod: exampleMethod.HttpMethod,
IntegrationHttpMethod: pulumi.String("GET"),
Type: pulumi.String("HTTP_PROXY"),
ConnectionType: pulumi.String("VPC_LINK"),
ConnectionId: example.ID(),
IntegrationTarget: exampleLoadBalancer.Arn,
Uri: pulumi.String("http://example.com"),
})
if err != nil {
return err
}
return nil
})
}
func toPulumiArray(arr []) pulumi.Array {
var pulumiArr pulumi.Array
for _, v := range arr {
pulumiArr = append(pulumiArr, pulumi.(v))
}
return pulumiArr
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var example = new Aws.ApiGatewayV2.VpcLink("example", new()
{
Name = "example",
SecurityGroupIds = new[]
{
exampleAwsSecurityGroup.Id,
},
SubnetIds = exampleAwsSubnet.Select(__item => __item.Id).ToList(),
});
var exampleLoadBalancer = new Aws.LB.LoadBalancer("example", new()
{
Name = "example-alb",
Internal = true,
LoadBalancerType = "application",
SecurityGroups = new[]
{
exampleAwsSecurityGroup.Id,
},
Subnets = exampleAwsSubnet.Select(__item => __item.Id).ToList(),
});
var exampleListener = new Aws.LB.Listener("example", new()
{
LoadBalancerArn = exampleLoadBalancer.Arn,
Port = 80,
Protocol = "HTTP",
DefaultActions = new[]
{
new Aws.LB.Inputs.ListenerDefaultActionArgs
{
Type = "fixed-response",
FixedResponse = new Aws.LB.Inputs.ListenerDefaultActionFixedResponseArgs
{
ContentType = "text/plain",
MessageBody = "OK",
StatusCode = "200",
},
},
},
});
var exampleRestApi = new Aws.ApiGateway.RestApi("example", new()
{
Name = "example",
});
var exampleResource = new Aws.ApiGateway.Resource("example", new()
{
RestApi = exampleRestApi.Id,
ParentId = exampleRestApi.RootResourceId,
PathPart = "example",
});
var exampleMethod = new Aws.ApiGateway.Method("example", new()
{
RestApi = exampleRestApi.Id,
ResourceId = exampleResource.Id,
HttpMethod = "GET",
Authorization = "NONE",
});
var exampleIntegration = new Aws.ApiGateway.Integration("example", new()
{
RestApi = exampleRestApi.Id,
ResourceId = exampleResource.Id,
HttpMethod = exampleMethod.HttpMethod,
IntegrationHttpMethod = "GET",
Type = "HTTP_PROXY",
ConnectionType = "VPC_LINK",
ConnectionId = example.Id,
IntegrationTarget = exampleLoadBalancer.Arn,
Uri = "http://example.com",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.apigatewayv2.VpcLink;
import com.pulumi.aws.apigatewayv2.VpcLinkArgs;
import com.pulumi.aws.lb.LoadBalancer;
import com.pulumi.aws.lb.LoadBalancerArgs;
import com.pulumi.aws.lb.Listener;
import com.pulumi.aws.lb.ListenerArgs;
import com.pulumi.aws.lb.inputs.ListenerDefaultActionArgs;
import com.pulumi.aws.lb.inputs.ListenerDefaultActionFixedResponseArgs;
import com.pulumi.aws.apigateway.RestApi;
import com.pulumi.aws.apigateway.RestApiArgs;
import com.pulumi.aws.apigateway.Resource;
import com.pulumi.aws.apigateway.ResourceArgs;
import com.pulumi.aws.apigateway.Method;
import com.pulumi.aws.apigateway.MethodArgs;
import com.pulumi.aws.apigateway.Integration;
import com.pulumi.aws.apigateway.IntegrationArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var example = new VpcLink("example", VpcLinkArgs.builder()
.name("example")
.securityGroupIds(exampleAwsSecurityGroup.id())
.subnetIds(exampleAwsSubnet.stream().map(element -> element.id()).collect(toList()))
.build());
var exampleLoadBalancer = new LoadBalancer("exampleLoadBalancer", LoadBalancerArgs.builder()
.name("example-alb")
.internal(true)
.loadBalancerType("application")
.securityGroups(exampleAwsSecurityGroup.id())
.subnets(exampleAwsSubnet.stream().map(element -> element.id()).collect(toList()))
.build());
var exampleListener = new Listener("exampleListener", ListenerArgs.builder()
.loadBalancerArn(exampleLoadBalancer.arn())
.port(80)
.protocol("HTTP")
.defaultActions(ListenerDefaultActionArgs.builder()
.type("fixed-response")
.fixedResponse(ListenerDefaultActionFixedResponseArgs.builder()
.contentType("text/plain")
.messageBody("OK")
.statusCode("200")
.build())
.build())
.build());
var exampleRestApi = new RestApi("exampleRestApi", RestApiArgs.builder()
.name("example")
.build());
var exampleResource = new Resource("exampleResource", ResourceArgs.builder()
.restApi(exampleRestApi.id())
.parentId(exampleRestApi.rootResourceId())
.pathPart("example")
.build());
var exampleMethod = new Method("exampleMethod", MethodArgs.builder()
.restApi(exampleRestApi.id())
.resourceId(exampleResource.id())
.httpMethod("GET")
.authorization("NONE")
.build());
var exampleIntegration = new Integration("exampleIntegration", IntegrationArgs.builder()
.restApi(exampleRestApi.id())
.resourceId(exampleResource.id())
.httpMethod(exampleMethod.httpMethod())
.integrationHttpMethod("GET")
.type("HTTP_PROXY")
.connectionType("VPC_LINK")
.connectionId(example.id())
.integrationTarget(exampleLoadBalancer.arn())
.uri("http://example.com")
.build());
}
}
VPC Link V2 uses apigatewayv2.VpcLink instead of apigateway.VpcLink. The integrationTarget property specifies the ALB ARN, while uri sets the Host header for routing. The type property is HTTP_PROXY for proxy-style integrations. This extends the VPC Link pattern to support application load balancers.
Beyond these examples
These snippets focus on specific integration features: mock and Lambda proxy integrations, VPC Link for private backends, and request transformation and parameter mapping. They’re intentionally minimal rather than full API deployments.
The examples reference pre-existing infrastructure such as RestApi, Resource, and Method resources, Lambda functions with execution roles, and VPC infrastructure (subnets, security groups, load balancers). They focus on configuring the integration rather than provisioning the complete API structure.
To keep things focused, common integration patterns are omitted, including:
- Response transformation and status code mapping
- AWS service integrations (DynamoDB, SQS, Step Functions)
- Request validation and authorization
- TLS configuration for backend connections
These omissions are intentional: the goal is to illustrate how each integration type is wired, not provide drop-in API modules. See the API Gateway Integration resource reference for all available configuration options.
Let's configure AWS API Gateway Integrations
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Integration Types & Required Fields
HTTP (HTTP backends), MOCK (no real backend), AWS (AWS services), AWS_PROXY (Lambda proxy), and HTTP_PROXY (HTTP proxy). Private integrations use HTTP or HTTP_PROXY with connectionType set to VPC_LINK.AWS, AWS_PROXY, HTTP, and HTTP_PROXY types, both uri and integrationHttpMethod are required. MOCK integrations don’t require these fields. Additionally, passthroughBehavior is required if you use requestTemplates.integrationHttpMethod is set to POST when using AWS_PROXY or AWS integration types with Lambda.VPC & Private Integrations
connectionType to VPC_LINK and provide the VPC Link ID in connectionId. For VPC Link V2 with Application Load Balancers, also specify the load balancer ARN in integrationTarget.integrationTarget to specify the ALB or NLB ARN, while uri sets the Host header. In V1, uri is used for routing. V2 is created with aws.apigatewayv2.VpcLink, while V1 uses aws.apigateway.VpcLink.uri is not used for routing requests to your endpoint. Instead, it’s used for setting the Host header and for certificate validation.Timeouts & Response Handling
BUFFERED mode or 900,000ms (15 minutes) for STREAM mode. To increase beyond 29,000ms for BUFFERED mode, you must raise a Service Quota Ticket.responseTransferMode is set to BUFFERED, you must explicitly specify BUFFERED rather than removing the argument. This is a known behavior of the property.Authentication & Permissions
AWS integrations, you have two options: specify an IAM role ARN for API Gateway to assume, or use arn:aws:iam::*:user/* to pass through the caller’s identity from the request. Note that credentials is immutable after creation.aws.lambda.Permission resource to allow API Gateway to invoke your Lambda function. Set principal to apigateway.amazonaws.com and sourceArn to match your API Gateway execution ARN.Immutability & Lifecycle
type, httpMethod, resourceId, restApi, passthroughBehavior, integrationHttpMethod, and credentials. Plan these carefully during initial configuration.passthroughBehavior is required if you use requestTemplates. Valid values are WHEN_NO_MATCH, WHEN_NO_TEMPLATES, and NEVER. This property is also immutable after creation.Using a different cloud?
Explore integration guides for other cloud providers: