Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 82 additions & 0 deletions examples/internal-alb/.terraform.lock.hcl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

53 changes: 53 additions & 0 deletions examples/internal-alb/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Internal ALB Lambda Example

Example demonstrating Lambda deployment within a VPC using an internal Application Load Balancer (ALB) with the `terraform-aws-lambda-versioned` module.

## What it creates

- VPC with public and private subnets across 3 AZs
- NAT Gateway for outbound internet access
- Internal Application Load Balancer (ALB) in private subnets
- Lambda function deployed in private subnets
- Lambda function accessible only via internal ALB
- Jumphost for VPC connectivity testing

## Usage

```bash
terraform init
terraform plan
terraform apply
```

## Testing

```bash
# Get ALB DNS name
terraform output

# Test via internal ALB (requires VPC access)
curl internal-cltest1-<suffix>-<random>.ap-southeast-2.elb.amazonaws.com

# Access via jumphost (SSM Session Manager)
aws ssm start-session --target <instance-id>
```

## VPC Access

- **Internal ALB**: Private subnets only, not internet-accessible
- **Lambda in VPC**: Private subnets, internet via NAT Gateway
- **Access via Jumphost**: SSM Session Manager to jumphost, then curl ALB endpoint
- **No Function URL**: Lambda is not directly accessible from internet

## Security Features

- Lambda function is completely isolated from internet
- Only accessible through internal ALB
- ALB restricted to VPC CIDR blocks only
- Jumphost provides secure access to test Lambda functionality

## Cleanup

```bash
terraform destroy
```
120 changes: 120 additions & 0 deletions examples/internal-alb/external/lambda/vpc-connectivity-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
const https = require('https');

/**
* VPC Connectivity Test Lambda Function
*
* This function demonstrates that a Lambda function deployed in a VPC can still
* access external APIs and services over the internet. It queries an external
* API to verify VPC configuration, NAT Gateway setup, and security group rules.
*/
module.exports.handler = async (event) => {
const version = process.env.AWS_LAMBDA_FUNCTION_VERSION;
const startTime = Date.now();

console.log('VPC Connectivity Test - Lambda version:', version);
console.log('Event:', JSON.stringify(event, null, 2));

try {
// Query an external API to demonstrate internet connectivity from VPC
const externalData = await queryExternalAPI();
const executionTime = Date.now() - startTime;

const response = {
statusCode: 200,
headers: {
'Content-Type': 'application/json',
'X-Lambda-Version': version,
'X-Execution-Time': `${executionTime}ms`
},
body: JSON.stringify({
message: 'VPC Connectivity Test: Lambda successfully accessed external API from VPC',
test: 'VPC Internet Connectivity',
status: 'PASSED',
lambdaVersion: version,
executionTime: `${executionTime}ms`,
externalAPI: {
status: 'success',
data: externalData
},
timestamp: new Date().toISOString(),
environment: {
region: process.env.AWS_REGION,
functionName: process.env.AWS_LAMBDA_FUNCTION_NAME,
memorySize: process.env.AWS_LAMBDA_FUNCTION_MEMORY_SIZE
}
})
};

console.log('Response:', JSON.stringify(response, null, 2));
return response;

} catch (error) {
console.error('Error:', error);

return {
statusCode: 500,
headers: {
'Content-Type': 'application/json',
'X-Lambda-Version': version
},
body: JSON.stringify({
message: 'VPC Connectivity Test: Failed to access external API',
test: 'VPC Internet Connectivity',
status: 'FAILED',
lambdaVersion: version,
error: error.message,
timestamp: new Date().toISOString()
})
};
}
};

// Helper function to query external API
function queryExternalAPI() {
return new Promise((resolve, reject) => {
const options = {
hostname: 'httpbin.org',
port: 443,
path: '/json',
method: 'GET',
timeout: 5000
};

const req = https.request(options, (res) => {
let data = '';

res.on('data', (chunk) => {
data += chunk;
});

res.on('end', () => {
try {
const jsonData = JSON.parse(data);
resolve({
url: `https://${options.hostname}${options.path}`,
statusCode: res.statusCode,
response: jsonData
});
} catch (parseError) {
resolve({
url: `https://${options.hostname}${options.path}`,
statusCode: res.statusCode,
response: data,
parseError: parseError.message
});
}
});
});

req.on('error', (error) => {
reject(new Error(`External API request failed: ${error.message}`));
});

req.on('timeout', () => {
req.destroy();
reject(new Error('External API request timed out'));
});

req.end();
});
}
Binary file not shown.
Loading