Complete restructure based on AI Agent Skills Benchmark feedback (original score: 66/100):
## Directory Reorganization
- Moved Python scripts to scripts/ directory
- Moved sample files to assets/ directory
- Created references/ directory with extracted content
- Removed HOW_TO_USE.md (integrated into SKILL.md)
- Removed __pycache__
## New Reference Files (3 files)
- architecture_patterns.md: 6 AWS patterns (serverless, microservices, three-tier,
data processing, GraphQL, multi-region) with diagrams, cost breakdowns, pros/cons
- service_selection.md: Decision matrices for compute, database, storage, messaging,
networking, security services with code examples
- best_practices.md: Serverless design, cost optimization, security hardening,
scalability patterns, common pitfalls
## SKILL.md Rewrite
- Reduced from 345 lines to 307 lines (moved patterns to references/)
- Added trigger phrases to description ("design serverless architecture",
"create CloudFormation templates", "optimize AWS costs")
- Structured around 6-step workflow instead of encyclopedia format
- Added Quick Start examples (MVP, Scaling, Cost Optimization, IaC)
- Removed marketing language ("Expert", "comprehensive")
- Consistent imperative voice throughout
## Structure Changes
- scripts/: architecture_designer.py, cost_optimizer.py, serverless_stack.py
- references/: architecture_patterns.md, service_selection.md, best_practices.md
- assets/: sample_input.json, expected_output.json
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,663 @@
|
||||
"""
|
||||
Serverless stack generator for AWS.
|
||||
Creates CloudFormation/CDK templates for serverless applications.
|
||||
"""
|
||||
|
||||
from typing import Dict, List, Any, Optional
|
||||
|
||||
|
||||
class ServerlessStackGenerator:
|
||||
"""Generate serverless application stacks."""
|
||||
|
||||
def __init__(self, app_name: str, requirements: Dict[str, Any]):
|
||||
"""
|
||||
Initialize with application requirements.
|
||||
|
||||
Args:
|
||||
app_name: Application name (used for resource naming)
|
||||
requirements: Dictionary with API, database, auth requirements
|
||||
"""
|
||||
self.app_name = app_name.lower().replace(' ', '-')
|
||||
self.requirements = requirements
|
||||
self.region = requirements.get('region', 'us-east-1')
|
||||
|
||||
def generate_cloudformation_template(self) -> str:
|
||||
"""
|
||||
Generate CloudFormation template for serverless stack.
|
||||
|
||||
Returns:
|
||||
YAML CloudFormation template as string
|
||||
"""
|
||||
template = f"""AWSTemplateFormatVersion: '2010-09-09'
|
||||
Transform: AWS::Serverless-2016-10-31
|
||||
Description: Serverless stack for {self.app_name}
|
||||
|
||||
Parameters:
|
||||
Environment:
|
||||
Type: String
|
||||
Default: dev
|
||||
AllowedValues:
|
||||
- dev
|
||||
- staging
|
||||
- production
|
||||
Description: Deployment environment
|
||||
|
||||
CorsAllowedOrigins:
|
||||
Type: String
|
||||
Default: '*'
|
||||
Description: CORS allowed origins for API Gateway
|
||||
|
||||
Resources:
|
||||
# DynamoDB Table
|
||||
{self.app_name.replace('-', '')}Table:
|
||||
Type: AWS::DynamoDB::Table
|
||||
Properties:
|
||||
TableName: !Sub '${{Environment}}-{self.app_name}-data'
|
||||
BillingMode: PAY_PER_REQUEST
|
||||
AttributeDefinitions:
|
||||
- AttributeName: PK
|
||||
AttributeType: S
|
||||
- AttributeName: SK
|
||||
AttributeType: S
|
||||
KeySchema:
|
||||
- AttributeName: PK
|
||||
KeyType: HASH
|
||||
- AttributeName: SK
|
||||
KeyType: RANGE
|
||||
PointInTimeRecoverySpecification:
|
||||
PointInTimeRecoveryEnabled: true
|
||||
SSESpecification:
|
||||
SSEEnabled: true
|
||||
StreamSpecification:
|
||||
StreamViewType: NEW_AND_OLD_IMAGES
|
||||
Tags:
|
||||
- Key: Environment
|
||||
Value: !Ref Environment
|
||||
- Key: Application
|
||||
Value: {self.app_name}
|
||||
|
||||
# Lambda Execution Role
|
||||
LambdaExecutionRole:
|
||||
Type: AWS::IAM::Role
|
||||
Properties:
|
||||
AssumeRolePolicyDocument:
|
||||
Version: '2012-10-17'
|
||||
Statement:
|
||||
- Effect: Allow
|
||||
Principal:
|
||||
Service: lambda.amazonaws.com
|
||||
Action: sts:AssumeRole
|
||||
ManagedPolicyArns:
|
||||
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
|
||||
Policies:
|
||||
- PolicyName: DynamoDBAccess
|
||||
PolicyDocument:
|
||||
Version: '2012-10-17'
|
||||
Statement:
|
||||
- Effect: Allow
|
||||
Action:
|
||||
- dynamodb:GetItem
|
||||
- dynamodb:PutItem
|
||||
- dynamodb:UpdateItem
|
||||
- dynamodb:DeleteItem
|
||||
- dynamodb:Query
|
||||
- dynamodb:Scan
|
||||
Resource: !GetAtt {self.app_name.replace('-', '')}Table.Arn
|
||||
|
||||
# Lambda Function
|
||||
ApiFunction:
|
||||
Type: AWS::Serverless::Function
|
||||
Properties:
|
||||
FunctionName: !Sub '${{Environment}}-{self.app_name}-api'
|
||||
Handler: index.handler
|
||||
Runtime: nodejs18.x
|
||||
CodeUri: ./src
|
||||
MemorySize: 512
|
||||
Timeout: 10
|
||||
Role: !GetAtt LambdaExecutionRole.Arn
|
||||
Environment:
|
||||
Variables:
|
||||
TABLE_NAME: !Ref {self.app_name.replace('-', '')}Table
|
||||
ENVIRONMENT: !Ref Environment
|
||||
Events:
|
||||
ApiEvent:
|
||||
Type: Api
|
||||
Properties:
|
||||
Path: /{{proxy+}}
|
||||
Method: ANY
|
||||
RestApiId: !Ref ApiGateway
|
||||
Tags:
|
||||
Environment: !Ref Environment
|
||||
Application: {self.app_name}
|
||||
|
||||
# API Gateway
|
||||
ApiGateway:
|
||||
Type: AWS::Serverless::Api
|
||||
Properties:
|
||||
Name: !Sub '${{Environment}}-{self.app_name}-api'
|
||||
StageName: !Ref Environment
|
||||
Cors:
|
||||
AllowMethods: "'GET,POST,PUT,DELETE,OPTIONS'"
|
||||
AllowHeaders: "'Content-Type,Authorization,X-Amz-Date,X-Api-Key,X-Amz-Security-Token'"
|
||||
AllowOrigin: !Sub "'${{CorsAllowedOrigins}}'"
|
||||
Auth:
|
||||
DefaultAuthorizer: CognitoAuthorizer
|
||||
Authorizers:
|
||||
CognitoAuthorizer:
|
||||
UserPoolArn: !GetAtt UserPool.Arn
|
||||
ThrottleSettings:
|
||||
BurstLimit: 200
|
||||
RateLimit: 100
|
||||
Tags:
|
||||
Environment: !Ref Environment
|
||||
Application: {self.app_name}
|
||||
|
||||
# Cognito User Pool
|
||||
UserPool:
|
||||
Type: AWS::Cognito::UserPool
|
||||
Properties:
|
||||
UserPoolName: !Sub '${{Environment}}-{self.app_name}-users'
|
||||
UsernameAttributes:
|
||||
- email
|
||||
AutoVerifiedAttributes:
|
||||
- email
|
||||
Policies:
|
||||
PasswordPolicy:
|
||||
MinimumLength: 8
|
||||
RequireUppercase: true
|
||||
RequireLowercase: true
|
||||
RequireNumbers: true
|
||||
RequireSymbols: false
|
||||
MfaConfiguration: OPTIONAL
|
||||
EnabledMfas:
|
||||
- SOFTWARE_TOKEN_MFA
|
||||
UserAttributeUpdateSettings:
|
||||
AttributesRequireVerificationBeforeUpdate:
|
||||
- email
|
||||
Schema:
|
||||
- Name: email
|
||||
Required: true
|
||||
Mutable: true
|
||||
|
||||
# Cognito User Pool Client
|
||||
UserPoolClient:
|
||||
Type: AWS::Cognito::UserPoolClient
|
||||
Properties:
|
||||
ClientName: !Sub '${{Environment}}-{self.app_name}-client'
|
||||
UserPoolId: !Ref UserPool
|
||||
GenerateSecret: false
|
||||
RefreshTokenValidity: 30
|
||||
AccessTokenValidity: 1
|
||||
IdTokenValidity: 1
|
||||
TokenValidityUnits:
|
||||
RefreshToken: days
|
||||
AccessToken: hours
|
||||
IdToken: hours
|
||||
ExplicitAuthFlows:
|
||||
- ALLOW_USER_SRP_AUTH
|
||||
- ALLOW_REFRESH_TOKEN_AUTH
|
||||
|
||||
# CloudWatch Log Group
|
||||
ApiLogGroup:
|
||||
Type: AWS::Logs::LogGroup
|
||||
Properties:
|
||||
LogGroupName: !Sub '/aws/lambda/${{Environment}}-{self.app_name}-api'
|
||||
RetentionInDays: 7
|
||||
|
||||
Outputs:
|
||||
ApiUrl:
|
||||
Description: API Gateway endpoint URL
|
||||
Value: !Sub 'https://${{ApiGateway}}.execute-api.${{AWS::Region}}.amazonaws.com/${{Environment}}'
|
||||
Export:
|
||||
Name: !Sub '${{Environment}}-{self.app_name}-ApiUrl'
|
||||
|
||||
UserPoolId:
|
||||
Description: Cognito User Pool ID
|
||||
Value: !Ref UserPool
|
||||
Export:
|
||||
Name: !Sub '${{Environment}}-{self.app_name}-UserPoolId'
|
||||
|
||||
UserPoolClientId:
|
||||
Description: Cognito User Pool Client ID
|
||||
Value: !Ref UserPoolClient
|
||||
Export:
|
||||
Name: !Sub '${{Environment}}-{self.app_name}-UserPoolClientId'
|
||||
|
||||
TableName:
|
||||
Description: DynamoDB Table Name
|
||||
Value: !Ref {self.app_name.replace('-', '')}Table
|
||||
Export:
|
||||
Name: !Sub '${{Environment}}-{self.app_name}-TableName'
|
||||
"""
|
||||
return template
|
||||
|
||||
def generate_cdk_stack(self) -> str:
|
||||
"""
|
||||
Generate AWS CDK stack in TypeScript.
|
||||
|
||||
Returns:
|
||||
CDK stack code as string
|
||||
"""
|
||||
stack = f"""import * as cdk from 'aws-cdk-lib';
|
||||
import * as lambda from 'aws-cdk-lib/aws-lambda';
|
||||
import * as apigateway from 'aws-cdk-lib/aws-apigateway';
|
||||
import * as dynamodb from 'aws-cdk-lib/aws-dynamodb';
|
||||
import * as cognito from 'aws-cdk-lib/aws-cognito';
|
||||
import {{ Construct }} from 'constructs';
|
||||
|
||||
export class {self.app_name.replace('-', '').title()}Stack extends cdk.Stack {{
|
||||
constructor(scope: Construct, id: string, props?: cdk.StackProps) {{
|
||||
super(scope, id, props);
|
||||
|
||||
// DynamoDB Table
|
||||
const table = new dynamodb.Table(this, '{self.app_name}Table', {{
|
||||
tableName: `${{cdk.Stack.of(this).stackName}}-data`,
|
||||
partitionKey: {{ name: 'PK', type: dynamodb.AttributeType.STRING }},
|
||||
sortKey: {{ name: 'SK', type: dynamodb.AttributeType.STRING }},
|
||||
billingMode: dynamodb.BillingMode.PAY_PER_REQUEST,
|
||||
encryption: dynamodb.TableEncryption.AWS_MANAGED,
|
||||
pointInTimeRecovery: true,
|
||||
stream: dynamodb.StreamViewType.NEW_AND_OLD_IMAGES,
|
||||
removalPolicy: cdk.RemovalPolicy.RETAIN,
|
||||
}});
|
||||
|
||||
// Cognito User Pool
|
||||
const userPool = new cognito.UserPool(this, '{self.app_name}UserPool', {{
|
||||
userPoolName: `${{cdk.Stack.of(this).stackName}}-users`,
|
||||
selfSignUpEnabled: true,
|
||||
signInAliases: {{ email: true }},
|
||||
autoVerify: {{ email: true }},
|
||||
passwordPolicy: {{
|
||||
minLength: 8,
|
||||
requireLowercase: true,
|
||||
requireUppercase: true,
|
||||
requireDigits: true,
|
||||
requireSymbols: false,
|
||||
}},
|
||||
mfa: cognito.Mfa.OPTIONAL,
|
||||
mfaSecondFactor: {{
|
||||
sms: false,
|
||||
otp: true,
|
||||
}},
|
||||
removalPolicy: cdk.RemovalPolicy.RETAIN,
|
||||
}});
|
||||
|
||||
const userPoolClient = userPool.addClient('{self.app_name}Client', {{
|
||||
authFlows: {{
|
||||
userSrp: true,
|
||||
}},
|
||||
accessTokenValidity: cdk.Duration.hours(1),
|
||||
refreshTokenValidity: cdk.Duration.days(30),
|
||||
}});
|
||||
|
||||
// Lambda Function
|
||||
const apiFunction = new lambda.Function(this, '{self.app_name}ApiFunction', {{
|
||||
functionName: `${{cdk.Stack.of(this).stackName}}-api`,
|
||||
runtime: lambda.Runtime.NODEJS_18_X,
|
||||
handler: 'index.handler',
|
||||
code: lambda.Code.fromAsset('./src'),
|
||||
memorySize: 512,
|
||||
timeout: cdk.Duration.seconds(10),
|
||||
environment: {{
|
||||
TABLE_NAME: table.tableName,
|
||||
USER_POOL_ID: userPool.userPoolId,
|
||||
}},
|
||||
logRetention: 7, // days
|
||||
}});
|
||||
|
||||
// Grant Lambda permissions to DynamoDB
|
||||
table.grantReadWriteData(apiFunction);
|
||||
|
||||
// API Gateway
|
||||
const api = new apigateway.RestApi(this, '{self.app_name}Api', {{
|
||||
restApiName: `${{cdk.Stack.of(this).stackName}}-api`,
|
||||
description: 'API for {self.app_name}',
|
||||
defaultCorsPreflightOptions: {{
|
||||
allowOrigins: apigateway.Cors.ALL_ORIGINS,
|
||||
allowMethods: apigateway.Cors.ALL_METHODS,
|
||||
allowHeaders: ['Content-Type', 'Authorization'],
|
||||
}},
|
||||
deployOptions: {{
|
||||
stageName: 'prod',
|
||||
throttlingRateLimit: 100,
|
||||
throttlingBurstLimit: 200,
|
||||
metricsEnabled: true,
|
||||
loggingLevel: apigateway.MethodLoggingLevel.INFO,
|
||||
}},
|
||||
}});
|
||||
|
||||
// Cognito Authorizer
|
||||
const authorizer = new apigateway.CognitoUserPoolsAuthorizer(this, 'ApiAuthorizer', {{
|
||||
cognitoUserPools: [userPool],
|
||||
}});
|
||||
|
||||
// API Integration
|
||||
const integration = new apigateway.LambdaIntegration(apiFunction);
|
||||
|
||||
// Add proxy resource (/{{proxy+}})
|
||||
const proxyResource = api.root.addProxy({{
|
||||
defaultIntegration: integration,
|
||||
anyMethod: true,
|
||||
defaultMethodOptions: {{
|
||||
authorizer: authorizer,
|
||||
authorizationType: apigateway.AuthorizationType.COGNITO,
|
||||
}},
|
||||
}});
|
||||
|
||||
// Outputs
|
||||
new cdk.CfnOutput(this, 'ApiUrl', {{
|
||||
value: api.url,
|
||||
description: 'API Gateway URL',
|
||||
}});
|
||||
|
||||
new cdk.CfnOutput(this, 'UserPoolId', {{
|
||||
value: userPool.userPoolId,
|
||||
description: 'Cognito User Pool ID',
|
||||
}});
|
||||
|
||||
new cdk.CfnOutput(this, 'UserPoolClientId', {{
|
||||
value: userPoolClient.userPoolClientId,
|
||||
description: 'Cognito User Pool Client ID',
|
||||
}});
|
||||
|
||||
new cdk.CfnOutput(this, 'TableName', {{
|
||||
value: table.tableName,
|
||||
description: 'DynamoDB Table Name',
|
||||
}});
|
||||
}}
|
||||
}}
|
||||
"""
|
||||
return stack
|
||||
|
||||
def generate_terraform_configuration(self) -> str:
|
||||
"""
|
||||
Generate Terraform configuration for serverless stack.
|
||||
|
||||
Returns:
|
||||
Terraform HCL configuration as string
|
||||
"""
|
||||
terraform = f"""terraform {{
|
||||
required_version = ">= 1.0"
|
||||
required_providers {{
|
||||
aws = {{
|
||||
source = "hashicorp/aws"
|
||||
version = "~> 5.0"
|
||||
}}
|
||||
}}
|
||||
}}
|
||||
|
||||
provider "aws" {{
|
||||
region = var.aws_region
|
||||
}}
|
||||
|
||||
variable "aws_region" {{
|
||||
description = "AWS region"
|
||||
type = string
|
||||
default = "{self.region}"
|
||||
}}
|
||||
|
||||
variable "environment" {{
|
||||
description = "Environment name"
|
||||
type = string
|
||||
default = "dev"
|
||||
}}
|
||||
|
||||
variable "app_name" {{
|
||||
description = "Application name"
|
||||
type = string
|
||||
default = "{self.app_name}"
|
||||
}}
|
||||
|
||||
# DynamoDB Table
|
||||
resource "aws_dynamodb_table" "main" {{
|
||||
name = "${{var.environment}}-${{var.app_name}}-data"
|
||||
billing_mode = "PAY_PER_REQUEST"
|
||||
hash_key = "PK"
|
||||
range_key = "SK"
|
||||
|
||||
attribute {{
|
||||
name = "PK"
|
||||
type = "S"
|
||||
}}
|
||||
|
||||
attribute {{
|
||||
name = "SK"
|
||||
type = "S"
|
||||
}}
|
||||
|
||||
server_side_encryption {{
|
||||
enabled = true
|
||||
}}
|
||||
|
||||
point_in_time_recovery {{
|
||||
enabled = true
|
||||
}}
|
||||
|
||||
stream_enabled = true
|
||||
stream_view_type = "NEW_AND_OLD_IMAGES"
|
||||
|
||||
tags = {{
|
||||
Environment = var.environment
|
||||
Application = var.app_name
|
||||
}}
|
||||
}}
|
||||
|
||||
# Cognito User Pool
|
||||
resource "aws_cognito_user_pool" "main" {{
|
||||
name = "${{var.environment}}-${{var.app_name}}-users"
|
||||
|
||||
username_attributes = ["email"]
|
||||
auto_verified_attributes = ["email"]
|
||||
|
||||
password_policy {{
|
||||
minimum_length = 8
|
||||
require_lowercase = true
|
||||
require_numbers = true
|
||||
require_uppercase = true
|
||||
require_symbols = false
|
||||
}}
|
||||
|
||||
mfa_configuration = "OPTIONAL"
|
||||
|
||||
software_token_mfa_configuration {{
|
||||
enabled = true
|
||||
}}
|
||||
|
||||
schema {{
|
||||
name = "email"
|
||||
attribute_data_type = "String"
|
||||
required = true
|
||||
mutable = true
|
||||
}}
|
||||
|
||||
tags = {{
|
||||
Environment = var.environment
|
||||
Application = var.app_name
|
||||
}}
|
||||
}}
|
||||
|
||||
resource "aws_cognito_user_pool_client" "main" {{
|
||||
name = "${{var.environment}}-${{var.app_name}}-client"
|
||||
user_pool_id = aws_cognito_user_pool.main.id
|
||||
|
||||
generate_secret = false
|
||||
|
||||
explicit_auth_flows = [
|
||||
"ALLOW_USER_SRP_AUTH",
|
||||
"ALLOW_REFRESH_TOKEN_AUTH"
|
||||
]
|
||||
|
||||
refresh_token_validity = 30
|
||||
access_token_validity = 1
|
||||
id_token_validity = 1
|
||||
|
||||
token_validity_units {{
|
||||
refresh_token = "days"
|
||||
access_token = "hours"
|
||||
id_token = "hours"
|
||||
}}
|
||||
}}
|
||||
|
||||
# IAM Role for Lambda
|
||||
resource "aws_iam_role" "lambda" {{
|
||||
name = "${{var.environment}}-${{var.app_name}}-lambda-role"
|
||||
|
||||
assume_role_policy = jsonencode({{
|
||||
Version = "2012-10-17"
|
||||
Statement = [{{
|
||||
Action = "sts:AssumeRole"
|
||||
Effect = "Allow"
|
||||
Principal = {{
|
||||
Service = "lambda.amazonaws.com"
|
||||
}}
|
||||
}}]
|
||||
}})
|
||||
|
||||
tags = {{
|
||||
Environment = var.environment
|
||||
Application = var.app_name
|
||||
}}
|
||||
}}
|
||||
|
||||
resource "aws_iam_role_policy_attachment" "lambda_basic" {{
|
||||
role = aws_iam_role.lambda.name
|
||||
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
|
||||
}}
|
||||
|
||||
resource "aws_iam_role_policy" "dynamodb" {{
|
||||
name = "dynamodb-access"
|
||||
role = aws_iam_role.lambda.id
|
||||
|
||||
policy = jsonencode({{
|
||||
Version = "2012-10-17"
|
||||
Statement = [{{
|
||||
Effect = "Allow"
|
||||
Action = [
|
||||
"dynamodb:GetItem",
|
||||
"dynamodb:PutItem",
|
||||
"dynamodb:UpdateItem",
|
||||
"dynamodb:DeleteItem",
|
||||
"dynamodb:Query",
|
||||
"dynamodb:Scan"
|
||||
]
|
||||
Resource = aws_dynamodb_table.main.arn
|
||||
}}]
|
||||
}})
|
||||
}}
|
||||
|
||||
# Lambda Function
|
||||
resource "aws_lambda_function" "api" {{
|
||||
filename = "lambda.zip"
|
||||
function_name = "${{var.environment}}-${{var.app_name}}-api"
|
||||
role = aws_iam_role.lambda.arn
|
||||
handler = "index.handler"
|
||||
runtime = "nodejs18.x"
|
||||
memory_size = 512
|
||||
timeout = 10
|
||||
|
||||
environment {{
|
||||
variables = {{
|
||||
TABLE_NAME = aws_dynamodb_table.main.name
|
||||
USER_POOL_ID = aws_cognito_user_pool.main.id
|
||||
ENVIRONMENT = var.environment
|
||||
}}
|
||||
}}
|
||||
|
||||
tags = {{
|
||||
Environment = var.environment
|
||||
Application = var.app_name
|
||||
}}
|
||||
}}
|
||||
|
||||
# CloudWatch Log Group
|
||||
resource "aws_cloudwatch_log_group" "lambda" {{
|
||||
name = "/aws/lambda/${{aws_lambda_function.api.function_name}}"
|
||||
retention_in_days = 7
|
||||
|
||||
tags = {{
|
||||
Environment = var.environment
|
||||
Application = var.app_name
|
||||
}}
|
||||
}}
|
||||
|
||||
# API Gateway
|
||||
resource "aws_api_gateway_rest_api" "main" {{
|
||||
name = "${{var.environment}}-${{var.app_name}}-api"
|
||||
description = "API for ${{var.app_name}}"
|
||||
|
||||
tags = {{
|
||||
Environment = var.environment
|
||||
Application = var.app_name
|
||||
}}
|
||||
}}
|
||||
|
||||
resource "aws_api_gateway_authorizer" "cognito" {{
|
||||
name = "cognito-authorizer"
|
||||
rest_api_id = aws_api_gateway_rest_api.main.id
|
||||
type = "COGNITO_USER_POOLS"
|
||||
provider_arns = [aws_cognito_user_pool.main.arn]
|
||||
}}
|
||||
|
||||
resource "aws_api_gateway_resource" "proxy" {{
|
||||
rest_api_id = aws_api_gateway_rest_api.main.id
|
||||
parent_id = aws_api_gateway_rest_api.main.root_resource_id
|
||||
path_part = "{{proxy+}}"
|
||||
}}
|
||||
|
||||
resource "aws_api_gateway_method" "proxy" {{
|
||||
rest_api_id = aws_api_gateway_rest_api.main.id
|
||||
resource_id = aws_api_gateway_resource.proxy.id
|
||||
http_method = "ANY"
|
||||
authorization = "COGNITO_USER_POOLS"
|
||||
authorizer_id = aws_api_gateway_authorizer.cognito.id
|
||||
}}
|
||||
|
||||
resource "aws_api_gateway_integration" "lambda" {{
|
||||
rest_api_id = aws_api_gateway_rest_api.main.id
|
||||
resource_id = aws_api_gateway_resource.proxy.id
|
||||
http_method = aws_api_gateway_method.proxy.http_method
|
||||
|
||||
integration_http_method = "POST"
|
||||
type = "AWS_PROXY"
|
||||
uri = aws_lambda_function.api.invoke_arn
|
||||
}}
|
||||
|
||||
resource "aws_lambda_permission" "apigw" {{
|
||||
statement_id = "AllowAPIGatewayInvoke"
|
||||
action = "lambda:InvokeFunction"
|
||||
function_name = aws_lambda_function.api.function_name
|
||||
principal = "apigateway.amazonaws.com"
|
||||
source_arn = "${{aws_api_gateway_rest_api.main.execution_arn}}/*/*"
|
||||
}}
|
||||
|
||||
resource "aws_api_gateway_deployment" "main" {{
|
||||
depends_on = [
|
||||
aws_api_gateway_integration.lambda
|
||||
]
|
||||
|
||||
rest_api_id = aws_api_gateway_rest_api.main.id
|
||||
stage_name = var.environment
|
||||
}}
|
||||
|
||||
# Outputs
|
||||
output "api_url" {{
|
||||
description = "API Gateway URL"
|
||||
value = aws_api_gateway_deployment.main.invoke_url
|
||||
}}
|
||||
|
||||
output "user_pool_id" {{
|
||||
description = "Cognito User Pool ID"
|
||||
value = aws_cognito_user_pool.main.id
|
||||
}}
|
||||
|
||||
output "user_pool_client_id" {{
|
||||
description = "Cognito User Pool Client ID"
|
||||
value = aws_cognito_user_pool_client.main.id
|
||||
}}
|
||||
|
||||
output "table_name" {{
|
||||
description = "DynamoDB Table Name"
|
||||
value = aws_dynamodb_table.main.name
|
||||
}}
|
||||
"""
|
||||
return terraform
|
||||
Reference in New Issue
Block a user