πŸ€– Project 8: AWS CLI Helper - Code Browser

Project 8 Architecture

πŸ“‹ Infrastructure as Code

πŸ“„ cloudformation-template.yaml - Complete Infrastructure
Serverless infrastructure with API Gateway, Lambda, and Bedrock integration
AWSTemplateFormatVersion: '2010-09-09'
Description: 'Project 8: AWS CLI Helper - Natural language to AWS CLI via Amazon Bedrock'

Parameters:
  ModelId:
    Type: String
    Default: 'amazon.nova-micro-v1:0'
    Description: Bedrock model ID
  BedrockRegion:
    Type: String
    Default: 'us-east-1'
    Description: Region where Bedrock model is enabled

Resources:
  # IAM Role for Lambda
  LambdaExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: 'project-8-cli-copilot-lambda-role'
      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: BedrockAccess
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - bedrock:InvokeModel
                  - bedrock:Converse
                  - bedrock:InvokeModelWithResponseStream
                Resource: '*'

  # Lambda Function with embedded Python code
  CliAgentFunction:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: 'project-8-cli-copilot'
      Runtime: python3.12
      Handler: index.lambda_handler
      Role: !GetAtt LambdaExecutionRole.Arn
      Timeout: 20
      MemorySize: 512
      Environment:
        Variables:
          MODEL_ID: !Ref ModelId
          BEDROCK_REGION: !Ref BedrockRegion

  # API Gateway HTTP API
  ApiGateway:
    Type: AWS::ApiGatewayV2::Api
    Properties:
      Name: 'project-8-cli-copilot-api'
      ProtocolType: HTTP
      CorsConfiguration:
        AllowMethods: [OPTIONS, POST]
        AllowOrigins: ['*']
        AllowHeaders: [Content-Type]

Outputs:
  ApiUrl:
    Description: 'API Gateway URL for CLI Helper'
    Value: !Sub 'https://${ApiGateway}.execute-api.${AWS::Region}.amazonaws.com/prod'
🐍 Lambda Function Code - AI Processing Engine
Python function that processes natural language and generates AWS CLI commands using Bedrock
import os
import json
import boto3
import logging
from botocore.config import Config

logger = logging.getLogger()
logger.setLevel(logging.INFO)

SYSTEM_PROMPT = """You are an expert AWS CLI command generator.
Given a user's natural-language goal, respond with a single JSON object with these fields:
- command: string (the best single command; multiline only if unavoidable)
- explanation: string (why this command, notable flags, alternatives)
- prerequisites: string[] (IAM permissions, resources, assumptions)
- safety: string[] (non-destructive variants such as --dry-run; caution about side effects)

Rules:
- Prefer safe commands and idempotent operations.
- If destructive, include warnings in safety.
- Do NOT include markdown fences or any text outside the JSON.
- Do not hallucinate account-specific values.
"""

MODEL_ID = os.environ.get("MODEL_ID", "amazon.nova-micro-v1:0")
BEDROCK_REGION = os.environ.get("BEDROCK_REGION", "us-east-1")

br_cfg = Config(retries={"max_attempts": 3, "mode": "standard"})
bedrock = boto3.client("bedrock-runtime", region_name=BEDROCK_REGION, config=br_cfg)

def _converse(goal: str) -> str:
    """Call Bedrock Converse API to generate CLI command"""
    resp = bedrock.converse(
        modelId=MODEL_ID,
        system=[{"text": SYSTEM_PROMPT}],
        messages=[{"role": "user", "content": [{"text": goal}]}],
        inferenceConfig={"maxTokens": 600, "temperature": 0.2, "topP": 0.9},
    )
    content_blocks = resp.get("output", {}).get("message", {}).get("content", [])
    texts = [b.get("text") for b in content_blocks if "text" in b]
    return "".join(texts) if texts else ""

def _safe_json_parse(s: str):
    """Safely parse JSON response from AI model"""
    try:
        return json.loads(s)
    except Exception:
        start = s.find("{")
        end = s.rfind("}")
        if start != -1 and end != -1 and end > start:
            try:
                return json.loads(s[start:end+1])
            except Exception:
                pass
    return {
        "command": "",
        "explanation": "The model returned an unexpected format. Please refine your request.",
        "prerequisites": [],
        "safety": ["Re-run with a more specific resource name or region."]
    }

def lambda_handler(event, context):
    """Main Lambda handler function"""
    logger.info("Event: %s", json.dumps(event))
    
    try:
        body = json.loads(event.get("body", "{}"))
    except Exception:
        body = {}

    goal = (body.get("goal") or "").strip()
    if not goal:
        return {
            "statusCode": 400,
            "headers": {"Content-Type": "application/json", "Access-Control-Allow-Origin": "*"},
            "body": json.dumps({"error": "Missing 'goal' in request body."})
        }

    try:
        text = _converse(goal)
        result = _safe_json_parse(text)
        
        # Ensure all required fields exist
        for key in ("command", "explanation", "prerequisites", "safety"):
            result.setdefault(key, "" if key in ("command", "explanation") else [])

        return {
            "statusCode": 200,
            "headers": {
                "Content-Type": "application/json",
                "Access-Control-Allow-Origin": "*",
                "Access-Control-Allow-Headers": "Content-Type",
                "Access-Control-Allow-Methods": "OPTIONS,POST"
            },
            "body": json.dumps(result)
        }
    except Exception as e:
        logger.error("Error: %s", str(e))
        return {
            "statusCode": 500,
            "headers": {"Content-Type": "application/json", "Access-Control-Allow-Origin": "*"},
            "body": json.dumps({"error": str(e)})
        }
🌐 Frontend Web Interface - Professional UI
Modern web interface with gradient styling and responsive design



  
  
  AWS CLI Helper (Bedrock)
  


  

AWS CLI Helper

⚠️ Always review commands before running. Add --dry-run to test safely without making changes (when supported).

πŸš€ Deployment Commands

πŸ“œ Deployment Process
CloudFormation deployment and S3 website setup commands
# Deploy the serverless backend
aws cloudformation deploy \
  --template-file cloudformation-template.yaml \
  --stack-name project-8-cli-copilot \
  --capabilities CAPABILITY_NAMED_IAM \
  --parameter-overrides ModelId=amazon.nova-micro-v1:0 \
  --region us-east-1

# Create S3 bucket for frontend
aws s3 mb s3://project-8-cli-copilot --region us-east-1

# Configure static website hosting
aws s3 website s3://project-8-cli-copilot \
  --index-document index.html \
  --region us-east-1

# Upload web interface
aws s3 cp index.html s3://project-8-cli-copilot/ --region us-east-1

# Configure public access
aws s3api put-public-access-block \
  --bucket project-8-cli-copilot \
  --public-access-block-configuration \
  "BlockPublicAcls=false,IgnorePublicAcls=false,BlockPublicPolicy=false,RestrictPublicBuckets=false"

# Apply bucket policy for public read
aws s3api put-bucket-policy \
  --bucket project-8-cli-copilot \
  --policy file://bucket-policy.json

echo "βœ… Project 8 CLI Helper deployed successfully!"

πŸ“Š Key Technical Features

← Back to Portfolio