A serverless web application for self-service Nobl9 project creation and user role assignment, built on AWS Lambda and S3.
This application converts the existing Nobl9 onboarding tool from a Docker-based deployment to a native AWS serverless architecture. Users can create new projects in Nobl9 by specifying an appID (project name) and assigning users or groups with specific roles through a clean web interface.
- Backend: Go Lambda function using
provided.al2023runtime - Frontend: React application hosted on S3 with static website hosting
- API: AWS API Gateway with public access and CSRF protection
- Security: CSRF tokens, input sanitization, and AWS KMS for encrypted credential management
- Monitoring: CloudWatch for logging, metrics, and alarms
- Infrastructure: Terraform and CloudFormation templates for deployment
- Zero Server Management: No EC2 instances to maintain or scale
- Automatic Scaling: Lambda functions scale from 0 to thousands of concurrent executions
- High Availability: Built on AWS managed services with 99.9%+ uptime
- Event-Driven: Pay only for actual usage with no idle costs
- CSRF Protection: Cryptographically secure tokens prevent cross-site request forgery attacks
- Input Sanitization: Comprehensive validation and sanitization of all user inputs
- XSS Prevention: HTML entity escaping and content security policies
- AWS KMS Integration: Nobl9 API credentials encrypted at rest and in transit
- Parameter Store: Secure storage of encrypted credentials in AWS Systems Manager
- Runtime Decryption: Credentials decrypted only when needed by Lambda function
- Security Logging: Structured security event logging for monitoring and alerting
- Configurable Enforcement: CSRF protection can be enabled/disabled per environment
- Pay-Per-Use Pricing: Only pay for actual Lambda invocations and API requests
- No Idle Costs: No charges when the application is not being used
- Predictable Billing: Clear cost structure with monthly estimates under $15
- Resource Optimization: Automatic scaling eliminates over-provisioning
- CloudWatch Logs: All Lambda function executions logged with structured data
- Real-Time Metrics: API Gateway requests, Lambda invocations, and error rates
- Automated Alerting: CloudWatch alarms for errors and performance issues
- Custom Dashboards: Centralized view of application health and performance
- Error Tracking: Detailed error logs with stack traces and context
- RESTful Design: Standard HTTP methods and status codes
- JSON Payloads: Consistent request/response formats
- CORS Support: Ready for web and mobile application integration
- Versioning Support: API versioning strategy for future updates
- Documentation: OpenAPI/Swagger specification for API consumers
- Terraform Support: Declarative infrastructure configuration
- CloudFormation Support: AWS-native template format
- Reproducible Deployments: Consistent infrastructure across environments
- Version Control: Infrastructure changes tracked in git
- Rollback Capability: Easy reversion of infrastructure changes
- AWS CLI v2: Configured with appropriate permissions for Lambda, API Gateway, S3, KMS, Parameter Store, and CloudWatch
- Go 1.21+: For Lambda function development and testing
- Node.js 18+: For React frontend development
- Git: For version control and cloning the repository
- Terraform: For infrastructure deployment (recommended)
- CloudFormation: Alternative infrastructure deployment option
- Docker: For local development environment (optional)
Your AWS account needs the following permissions:
- Lambda: Create, update, and manage functions
- API Gateway: Create and manage REST APIs
- S3: Create buckets and manage objects
- KMS: Create and manage encryption keys
- IAM: Create roles and policies
- Cognito: Create and manage Identity Pools
- CloudWatch: Create log groups, metrics, and alarms
- Systems Manager Parameter Store: Store and retrieve parameters
git clone https://github.com/your-org/Nobl9-wizard.git
cd Nobl9-wizardBackend Dependencies:
cd cmd/lambda
go mod tidy
go mod downloadFrontend Dependencies:
cd frontend
npm install# Configure AWS CLI with your credentials
aws configure
# Or set environment variables
export AWS_ACCESS_KEY_ID="your-access-key"
export AWS_SECRET_ACCESS_KEY="your-secret-key"
export AWS_DEFAULT_REGION="us-east-1"Store your Nobl9 API credentials securely in AWS Systems Manager Parameter Store:
# Store encrypted credentials in Parameter Store
aws ssm put-parameter \
--name "/nobl9-onboarding-app/client-id" \
--value "your-nobl9-client-id" \
--type "SecureString" \
--description "Nobl9 API Client ID"
aws ssm put-parameter \
--name "/nobl9-onboarding-app/client-secret" \
--value "your-nobl9-client-secret" \
--type "SecureString" \
--description "Nobl9 API Client Secret"
# Set environment variables for the Lambda function
export NOBL9_CLIENT_ID_PARAM_NAME="/nobl9-onboarding-app/client-id"
export NOBL9_CLIENT_SECRET_PARAM_NAME="/nobl9-onboarding-app/client-secret"Option A: Using Terraform (Recommended)
cd infrastructure/terraform
# Initialize Terraform
terraform init
# Review the deployment plan
terraform plan
# Deploy the infrastructure
terraform apply
# Note the outputs for API Gateway URL, S3 website URL, and Cognito Identity Pool ID
terraform outputOption B: Using CloudFormation
# Deploy the CloudFormation stack
aws cloudformation create-stack \
--stack-name nobl9-onboarding-app \
--template-body file://infrastructure/cloudformation/template.yaml \
--parameters file://infrastructure/cloudformation/parameters.json \
--capabilities CAPABILITY_NAMED_IAM
# Wait for stack creation to complete
aws cloudformation wait stack-create-complete \
--stack-name nobl9-onboarding-app
# Get stack outputs
aws cloudformation describe-stacks \
--stack-name nobl9-onboarding-app \
--query 'Stacks[0].Outputs'# Build and deploy the Lambda function
cd cmd/lambda
./build.sh
# Or manually build and deploy
GOOS=linux GOARCH=amd64 go build -o bootstrap main.go
zip function.zip bootstrap
aws lambda update-function-code --function-name nobl9-onboarding-lambda --zip-file fileb://function.zip# Build and deploy the React application
cd frontend
npm run build
# Deploy to S3 using the provided deployment script
# You'll need the Cognito Identity Pool ID and AWS region from infrastructure outputs
./deploy.sh
# Or manually deploy to S3 (bucket name from infrastructure outputs)
aws s3 sync build/ s3://your-frontend-bucket-name --delete- Frontend: Visit the S3 website URL from infrastructure outputs
- API: Test the API Gateway endpoint with a sample request
- Logs: Check CloudWatch logs for any errors
# Set up CloudWatch alarms
aws cloudwatch put-metric-alarm \
--alarm-name "nobl9-lambda-errors" \
--alarm-description "Lambda function errors" \
--metric-name Errors \
--namespace AWS/Lambda \
--statistic Sum \
--period 300 \
--threshold 1 \
--comparison-operator GreaterThanThreshold-
Access the Application: Navigate to the S3 website URL provided after deployment
-
Create a New Project:
- Enter a unique project name (appID) - only letters, numbers, and hyphens allowed
- Add an optional project description
- Add user groups with their assigned roles
- Review the project details in the confirmation dialog
- Submit to create the project
-
User Management:
- Add up to 8 users per project
- Each user group must specify a role (Owner, Editor, Viewer)
- Support for both email addresses and user IDs
- Comma-separated lists for multiple users in a group
The API uses CSRF protection for security. The frontend automatically handles CSRF token generation and validation.
Endpoint: POST /api/create-project
Headers:
Content-Type: application/json
X-CSRF-Token: <csrf-token>
X-Requested-With: XMLHttpRequest
Request Body:
{
"appID": "my-project",
"description": "Optional project description",
"userGroups": [
{
"userIds": "user@example.com,another@example.com",
"role": "project-owner"
},
{
"userIds": "user123",
"role": "project-viewer"
}
]
}Valid Roles:
project-owner: Full project access and managementproject-editor: Can edit project configurations and dataproject-viewer: Read-only access to project data
Response Format:
{
"success": true,
"message": "Project 'my-project' created successfully with 2 user role assignments"
}Error Response:
{
"success": false,
"message": "Project 'my-project' already exists"
}Using the frontend (recommended): The React frontend automatically handles CSRF token generation and provides a user-friendly interface for project creation.
Using curl with CSRF protection:
# First, get a CSRF token (in a real application, this would be handled by the frontend)
# For testing purposes, you can use a simple token
CSRF_TOKEN="test-csrf-token-$(date +%s)"
# Make the request with CSRF token
curl -X POST https://your-api-gateway-url.execute-api.region.amazonaws.com/prod/api/create-project \
-H "Content-Type: application/json" \
-H "X-CSRF-Token: $CSRF_TOKEN" \
-H "X-Requested-With: XMLHttpRequest" \
-d '{
"appID": "test-project",
"description": "Test project created via API",
"userGroups": [
{ "userIds": "admin@company.com", "role": "project-owner" },
{ "userIds": "viewer@company.com", "role": "project-viewer" }
]
}'Using JavaScript with CSRF protection:
// Generate CSRF token (in a real application, this would be handled by the security utilities)
function generateCSRFToken() {
const array = new Uint8Array(32);
crypto.getRandomValues(array);
return btoa(String.fromCharCode(...array)).replace(/[+/]/g, (char) =>
char === '+' ? '-' : '_'
).replace(/=+$/, '');
}
const csrfToken = generateCSRFToken();
const response = await fetch('https://your-api-gateway-url.execute-api.region.amazonaws.com/prod/api/create-project', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-Token': csrfToken,
'X-Requested-With': 'XMLHttpRequest'
},
body: JSON.stringify({
appID: 'my-project',
description: 'Project created via JavaScript',
userGroups: [
{ userIds: 'user@example.com', role: 'project-owner' }
]
})
});
const result = await response.json();
console.log(result.message);import requests
import json
import secrets
import base64
def generate_csrf_token():
"""Generate a cryptographically secure CSRF token"""
token_bytes = secrets.token_bytes(32)
token = base64.urlsafe_b64encode(token_bytes).decode('ascii').rstrip('=')
return token
def create_nobl9_project(api_url, project_name, description, users):
# Generate CSRF token
csrf_token = generate_csrf_token()
# Prepare the request
payload = {
"appID": project_name,
"description": description,
"userGroups": users
}
# Make the request with CSRF protection
response = requests.post(
f"{api_url}/api/create-project",
headers={
'Content-Type': 'application/json',
'X-CSRF-Token': csrf_token,
'X-Requested-With': 'XMLHttpRequest'
},
data=json.dumps(payload)
)
return response.json()
# Usage
users = [
{"userIds": "admin@company.com", "role": "project-owner"},
{"userIds": "team@company.com", "role": "project-editor"}
]
result = create_nobl9_project(
"https://your-api-gateway-url.execute-api.region.amazonaws.com/prod",
"new-project",
"Project created via Python integration",
users
)
print(result)# Use the API Gateway URL as a data source
data "aws_api_gateway_rest_api" "nobl9_api" {
name = "nobl9-onboarding-api"
}
output "api_url" {
value = "https://${data.aws_api_gateway_rest_api.nobl9_api.id}.execute-api.${var.aws_region}.amazonaws.com/prod"
}- CSRF Protection: Cryptographically secure tokens prevent cross-site request forgery attacks
- Input Sanitization: Comprehensive validation and sanitization of all user inputs
- XSS Prevention: HTML entity escaping and content security policies
- KMS Encryption: All Nobl9 credentials are encrypted using AWS KMS
- Parameter Store: Encrypted credentials stored in AWS Systems Manager Parameter Store
- Security Logging: Structured security event logging for monitoring and alerting
- CORS Configuration: Properly configured for S3-to-API-Gateway communication
- Configurable Enforcement: CSRF protection can be enabled/disabled per environment
- CloudWatch Logs: All Lambda function executions are logged
- CloudWatch Metrics: API Gateway requests, Lambda invocations, and error rates
- CloudWatch Alarms: Automated alerting for errors and performance issues
- CloudWatch Dashboard: Centralized view of application health
Typical monthly costs for moderate usage:
- Lambda: $1-5/month
- API Gateway: $1-3/month
- S3: $0.50-1/month
- CloudWatch: $1-2/month
- KMS: $1/month
- Cognito: $0.50-1/month
- Total: ~$5-13/month
# Backend (Lambda)
cd cmd/lambda
go mod tidy
go mod download
# Test the Lambda function locally
go test -v
# Frontend
cd frontend
npm install
npm startThe Lambda function includes comprehensive unit tests covering validation, health checks, error handling, and response correctness.
Run all tests:
cd cmd/lambda
go test ./...Run tests with verbose output:
go test -vRun tests with coverage:
go test -coverGenerate coverage report:
go test -coverprofile=coverage.out
go tool cover -html=coverage.out -o coverage.htmlTest Results:
- Coverage: 49.5% of statements
- Test Categories:
- Input validation (project names, emails, roles)
- Health check endpoint
- Error handling and response formatting
- Request routing and CORS support
- AWS credential management
Test Files:
main_test.go: Comprehensive unit tests for all Lambda function components
The React frontend uses Jest and React Testing Library for component testing.
Run all tests:
cd frontend
npm testRun tests in watch mode:
npm test -- --watchRun tests with coverage:
npm test -- --coverageTest Scripts Available:
npm test: Run tests in watch modenpm run build: Build for productionnpm start: Start development server
This project provides both Terraform and CloudFormation templates for infrastructure deployment:
- Terraform:
infrastructure/terraform/- Declarative infrastructure configuration - CloudFormation:
infrastructure/cloudformation/- AWS-native template format
Both templates create identical AWS resources including Lambda, API Gateway, S3, KMS, Parameter Store, and CloudWatch resources.
Lambda Function Errors:
- Missing Environment Variables: Ensure
NOBL9_CLIENT_ID_PARAM_NAMEandNOBL9_CLIENT_SECRET_PARAM_NAMEare set - Permission Errors: Verify Lambda execution role has KMS and Parameter Store permissions
- Build Errors: Ensure Go 1.21+ is installed and dependencies are downloaded
Frontend Deployment Issues:
- S3 Bucket Not Found: Verify bucket name and region in deployment script
- CORS Errors: Check API Gateway CORS configuration
- Authentication Errors: Verify Cognito Identity Pool ID and region in config
- Build Failures: Ensure Node.js 18+ and all dependencies are installed
Infrastructure Deployment:
- Terraform Errors: Run
terraform initand verify AWS credentials - CloudFormation Failures: Check IAM permissions and resource limits
- KMS Key Issues: Ensure proper key policy and alias configuration
Check Lambda Logs:
aws logs tail /aws/lambda/nobl9-onboarding-lambda --followTest API Endpoint:
# Test health endpoint (public access)
curl -X GET https://your-api-gateway-url.execute-api.region.amazonaws.com/prod/healthVerify S3 Website:
aws s3 ls s3://your-frontend-bucket-name- Fork the repository
- Create a feature branch
- Make your changes
- Add tests
- Submit a pull request
This project is licensed under the Mozilla Public License 2.0 - see the LICENSE file for details.
For issues and questions:
- Check the troubleshooting section above
- Review the deployment documentation
- Open an issue in the GitHub repository
We welcome contributions! Please follow these steps:
- Fork the repository
- Create a new branch for your feature or bugfix
- Make your changes and ensure tests pass
- Submit a pull request with a clear description of your changes
Please be respectful and inclusive in all interactions. We aim to foster a welcoming and collaborative environment for all contributors.
This project is licensed under the Mozilla Public License 2.0 - see the LICENSE file for details.