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>
664 lines
17 KiB
Python
664 lines
17 KiB
Python
"""
|
|
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
|