Skip to main content

AWS AI Services

Amazon Q Developer: Accelerating Development with AI Code Assistant

Complete guide to Amazon Q Developer for Australian development teams, covering IDE integration, code generation, security scanning, and optimisation strategies.

CloudPoint

CloudPoint Team

Amazon Q Developer transforms how development teams write, review, and maintain code. This AI-powered coding assistant integrates directly into your IDE, providing real-time code suggestions, security scanning, and intelligent refactoring. For Australian development teams, Q Developer offers a productivity boost while maintaining security and compliance standards.

What is Amazon Q Developer?

Amazon Q Developer is an AI-powered coding assistant that helps developers write code faster and more securely. Built on AWS’s foundation models and trained on billions of lines of code, it understands context, generates code, explains complex logic, and identifies security vulnerabilities in real-time.

Key Capabilities

Code Generation:

  • Context-aware code completion
  • Multi-line and full-function generation
  • Framework and library-specific suggestions
  • Natural language to code conversion
  • API implementation assistance

Code Analysis:

  • Security vulnerability detection
  • Code quality assessment
  • Performance optimisation suggestions
  • Best practice recommendations
  • Technical debt identification

Developer Assistance:

  • Code explanations and documentation
  • Unit test generation
  • Code refactoring suggestions
  • Bug fix recommendations
  • Migration assistance

Why Use Amazon Q Developer?

For Australian Development Teams

Productivity Gains: Studies show developers complete tasks 57% faster with AI code assistants.

Security First: Built-in security scanning catches vulnerabilities before deployment, crucial for regulated industries.

Cost Effective: Individual tier free, Professional tier includes advanced security scanning and administrative controls.

AWS Optimised: Deep integration with AWS services, SDK knowledge, and infrastructure as code patterns.

Use Cases

Accelerated Development: Generate boilerplate code, API integrations, and common patterns instantly.

Security Compliance: Identify OWASP Top 10 vulnerabilities and compliance issues during development.

Legacy Modernisation: Understand and refactor legacy code with AI explanations and migration suggestions.

Learning and Onboarding: New team members learn faster with inline explanations and best practices.

Test Coverage: Automatically generate comprehensive unit tests for existing code.

Getting Started

1. IDE Integration

Amazon Q Developer supports major IDEs:

Visual Studio Code:

# Install Amazon Q extension from VS Code marketplace
# Or via command line
code --install-extension amazonwebservices.amazon-q-vscode

JetBrains IDEs (IntelliJ, PyCharm, WebStorm):

# Install from JetBrains marketplace
# Settings → Plugins → Marketplace → Search "Amazon Q"

Visual Studio:

  • Download from Visual Studio Marketplace
  • Install Amazon Q for Visual Studio extension

AWS Cloud9:

  • Built-in, no installation required
  • Enable from Cloud9 preferences

2. Authentication

Connect Q Developer to your AWS account:

# AWS Builder ID (Free tier)
# - Personal email
# - No AWS account required
# - Limited features

# IAM Identity Center (Professional tier)
# - Organisation SSO
# - Full security features
# - Administrative controls

Configure IAM Identity Center:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "q:StartConversation",
        "q:SendMessage",
        "q:GetConversation",
        "q:ListConversations",
        "codewhisperer:GenerateRecommendations",
        "codewhisperer:GetCodeAnalysis"
      ],
      "Resource": "*"
    }
  ]
}

3. First Code Generation

Try Q Developer with a simple example:

Python Example:

# Type a comment describing what you want
# Calculate compound interest for Australian superannuation

# Q Developer generates:
def calculate_superannuation_interest(
    principal: float,
    annual_rate: float,
    years: int,
    contributions: float = 0
) -> dict:
    """
    Calculate compound interest for Australian superannuation.

    Args:
        principal: Initial investment amount
        annual_rate: Annual interest rate (e.g., 0.07 for 7%)
        years: Number of years
        contributions: Annual contributions (default 0)

    Returns:
        Dictionary with year-by-year balance and final amount
    """
    results = []
    balance = principal

    for year in range(1, years + 1):
        interest = balance * annual_rate
        balance = balance + interest + contributions
        results.append({
            'year': year,
            'balance': round(balance, 2),
            'interest_earned': round(interest, 2)
        })

    return {
        'yearly_breakdown': results,
        'final_balance': round(balance, 2),
        'total_interest': round(balance - principal - (contributions * years), 2)
    }

TypeScript Example:

// Create a function to validate Australian Business Numbers (ABN)

// Q Developer generates:
export function validateABN(abn: string): boolean {
  /**
   * Validates Australian Business Number (ABN)
   * Uses the weighted checksum algorithm
   *
   * @param abn - The ABN to validate (11 digits)
   * @returns True if valid, false otherwise
   */

  // Remove spaces and hyphens
  const cleanABN = abn.replace(/[\s-]/g, '');

  // Check length
  if (cleanABN.length !== 11 || !/^\d+$/.test(cleanABN)) {
    return false;
  }

  // Convert to array of numbers
  const digits = cleanABN.split('').map(Number);

  // Apply weighting
  const weights = [10, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19];

  // Subtract 1 from first digit
  digits[0] = digits[0] - 1;

  // Calculate weighted sum
  const sum = digits.reduce((acc, digit, index) => {
    return acc + (digit * weights[index]);
  }, 0);

  // Check if divisible by 89
  return sum % 89 === 0;
}

Code Generation Strategies

1. Effective Prompting

Be Specific:

# Vague comment
# Create a function to process data

# Specific comment
# Create a function to process CSV data from S3, validate Australian phone numbers,
# and return records with invalid numbers for review

Provide Context:

// Better: Include context in comments
// For our e-commerce platform handling Australian customers
// Create a function to calculate GST-inclusive price
// Input: base price (AUD), GST rate (default 10%)
// Output: object with base, GST amount, and total

Use Examples:

# Create a function to format Australian addresses
# Example input: {"street": "123 Main St", "suburb": "Sydney", "state": "NSW", "postcode": "2000"}
# Example output: "123 Main St, Sydney NSW 2000"

2. Function Generation

Generate complete functions from descriptions:

# Generate a function to interact with DynamoDB
# Table: users, Key: user_id (string)
# Get user by ID, handle errors, return None if not found

# Q Developer generates:
import boto3
from boto3.dynamodb.conditions import Key
from botocore.exceptions import ClientError
from typing import Optional, Dict, Any

def get_user_by_id(user_id: str, table_name: str = 'users') -> Optional[Dict[str, Any]]:
    """
    Retrieve user from DynamoDB by user ID.

    Args:
        user_id: The user's unique identifier
        table_name: DynamoDB table name (default: 'users')

    Returns:
        User data dictionary if found, None otherwise
    """
    dynamodb = boto3.resource('dynamodb', region_name='ap-southeast-2')
    table = dynamodb.Table(table_name)

    try:
        response = table.get_item(
            Key={'user_id': user_id}
        )

        if 'Item' in response:
            return response['Item']
        else:
            return None

    except ClientError as e:
        error_code = e.response['Error']['Code']

        if error_code == 'ResourceNotFoundException':
            print(f"Table {table_name} not found")
        elif error_code == 'ProvisionedThroughputExceededException':
            print("Request rate too high, implement backoff")
        else:
            print(f"Error retrieving user: {e}")

        return None

3. API Implementation

Generate API client code:

// Create a typed client for Australian weather API
// Endpoint: https://api.weatherapi.com.au/v1/current.json
// Requires API key, accepts location (city or postcode)
// Return typed response with temperature in Celsius, condition, humidity

// Q Developer generates:
interface WeatherResponse {
  location: {
    name: string;
    region: string;
    country: string;
    localtime: string;
  };
  current: {
    temp_c: number;
    condition: {
      text: string;
      icon: string;
    };
    humidity: number;
    wind_kph: number;
    feelslike_c: number;
  };
}

interface WeatherError {
  error: {
    code: number;
    message: string;
  };
}

export class AustralianWeatherClient {
  private apiKey: string;
  private baseURL = 'https://api.weatherapi.com.au/v1';

  constructor(apiKey: string) {
    this.apiKey = apiKey;
  }

  async getCurrentWeather(location: string): Promise<WeatherResponse> {
    const url = `${this.baseURL}/current.json`;
    const params = new URLSearchParams({
      key: this.apiKey,
      q: location,
      aqi: 'no'
    });

    try {
      const response = await fetch(`${url}?${params}`);

      if (!response.ok) {
        const error: WeatherError = await response.json();
        throw new Error(`Weather API error: ${error.error.message}`);
      }

      const data: WeatherResponse = await response.json();
      return data;

    } catch (error) {
      if (error instanceof Error) {
        throw new Error(`Failed to fetch weather: ${error.message}`);
      }
      throw new Error('Unknown error fetching weather data');
    }
  }

  async getWeatherForAustralianCity(city: string): Promise<{
    temperature: number;
    condition: string;
    humidity: number;
    location: string;
  }> {
    const data = await this.getCurrentWeather(`${city},Australia`);

    return {
      temperature: data.current.temp_c,
      condition: data.current.condition.text,
      humidity: data.current.humidity,
      location: `${data.location.name}, ${data.location.region}`
    };
  }
}

Security Scanning

Automatic Vulnerability Detection

Q Developer scans code for security issues:

Example: SQL Injection Detection:

# Vulnerable code - Q Developer flags this
def get_user(username):
    query = f"SELECT * FROM users WHERE username = '{username}'"
    return execute_query(query)  # ⚠️ Security: SQL Injection vulnerability

# Q Developer suggests:
def get_user_secure(username):
    query = "SELECT * FROM users WHERE username = %s"
    return execute_query(query, (username,))  # ✓ Parameterised query

Example: Hardcoded Credentials:

// Vulnerable code
const config = {
  database: 'production',
  password: 'MyP@ssw0rd123'  // ⚠️ Security: Hardcoded credentials
};

// Q Developer suggests:
const config = {
  database: process.env.DB_NAME,
  password: process.env.DB_PASSWORD  // ✓ Use environment variables
};

Security Scan Features

Detects:

  • SQL injection vulnerabilities
  • Cross-site scripting (XSS)
  • Hardcoded credentials and secrets
  • Insecure cryptography
  • Path traversal vulnerabilities
  • Insecure deserialization
  • XML external entity (XXE) injection
  • Server-side request forgery (SSRF)

Compliance Checks:

  • OWASP Top 10 vulnerabilities
  • CWE (Common Weakness Enumeration)
  • Australian Privacy Act considerations
  • Industry regulations security requirements

Running Security Scans

Full Project Scan:

# In VS Code
# Command Palette → Amazon Q: Run Security Scan

# Scans entire workspace
# Generates report with:
# - Critical, High, Medium, Low severity issues
# - Code locations
# - Remediation suggestions

Real-time Scanning:

  • Enabled by default
  • Flags issues as you type
  • Inline suggestions for fixes
  • Click to see detailed explanation

Code Explanations

Understanding Complex Code

Use Q Developer to explain existing code:

Select code and ask: “Explain this code”

Example:

# Complex algorithm - hard to understand
def luhn_check(card_number):
    def digits_of(n):
        return [int(d) for d in str(n)]
    digits = digits_of(card_number)
    odd_digits = digits[-1::-2]
    even_digits = digits[-2::-2]
    checksum = sum(odd_digits)
    for d in even_digits:
        checksum += sum(digits_of(d*2))
    return checksum % 10 == 0

Q Developer explains:

This function implements the Luhn algorithm to validate credit card numbers:

1. Converts card number to list of digits
2. Separates into odd and even positioned digits (from right)
3. Doubles even position digits
4. Sums all digits (splitting doubled values that are 2 digits)
5. Returns True if sum is divisible by 10

Used by payment processors to catch typos in card numbers before processing.

Documentation Generation

Generate documentation from code:

// Undocumented function
export function processPayment(amount: number, method: string, metadata: Record<string, any>) {
  const fee = calculateFee(amount, method);
  const total = amount + fee;
  return {
    amount,
    fee,
    total,
    currency: 'AUD',
    timestamp: Date.now(),
    ...metadata
  };
}

// Ask Q: "Generate JSDoc for this function"

// Q Developer generates:
/**
 * Processes a payment by calculating fees and creating a payment record.
 *
 * @param amount - The base payment amount in AUD (excluding fees)
 * @param method - Payment method identifier (e.g., 'card', 'bank_transfer')
 * @param metadata - Additional payment metadata to include in the response
 *
 * @returns Payment record containing:
 *   - amount: Original payment amount
 *   - fee: Calculated processing fee
 *   - total: Final amount (amount + fee)
 *   - currency: Always 'AUD'
 *   - timestamp: Unix timestamp of processing time
 *   - Additional metadata fields
 *
 * @example
 * ```typescript
 * const payment = processPayment(100.00, 'card', {
 *   orderId: '12345',
 *   customerId: 'cust_abc'
 * });
 * // Returns: { amount: 100, fee: 1.75, total: 101.75, currency: 'AUD', ... }
 * ```
 */

Unit Test Generation

Automatic Test Creation

Generate comprehensive unit tests:

Python Example:

# Original function
def calculate_gst(amount: float, rate: float = 0.1) -> dict:
    """Calculate GST for Australian prices."""
    gst_amount = amount * rate
    total = amount + gst_amount
    return {
        'base_amount': round(amount, 2),
        'gst_amount': round(gst_amount, 2),
        'total_amount': round(total, 2),
        'rate': rate
    }

# Select function, ask Q: "Generate unit tests"

# Q Developer generates:
import pytest
from decimal import Decimal

def test_calculate_gst_standard_rate():
    """Test GST calculation with standard 10% rate."""
    result = calculate_gst(100.00)

    assert result['base_amount'] == 100.00
    assert result['gst_amount'] == 10.00
    assert result['total_amount'] == 110.00
    assert result['rate'] == 0.1

def test_calculate_gst_custom_rate():
    """Test GST calculation with custom rate."""
    result = calculate_gst(100.00, rate=0.15)

    assert result['base_amount'] == 100.00
    assert result['gst_amount'] == 15.00
    assert result['total_amount'] == 115.00
    assert result['rate'] == 0.15

def test_calculate_gst_zero_amount():
    """Test GST calculation with zero amount."""
    result = calculate_gst(0.00)

    assert result['base_amount'] == 0.00
    assert result['gst_amount'] == 0.00
    assert result['total_amount'] == 0.00

def test_calculate_gst_decimal_precision():
    """Test rounding to 2 decimal places."""
    result = calculate_gst(33.33)

    assert result['base_amount'] == 33.33
    assert result['gst_amount'] == 3.33
    assert result['total_amount'] == 36.66

def test_calculate_gst_large_amount():
    """Test GST calculation with large amount."""
    result = calculate_gst(1000000.00)

    assert result['base_amount'] == 1000000.00
    assert result['gst_amount'] == 100000.00
    assert result['total_amount'] == 1100000.00

def test_calculate_gst_negative_amount():
    """Test GST calculation with negative amount (refund scenario)."""
    result = calculate_gst(-50.00)

    assert result['base_amount'] == -50.00
    assert result['gst_amount'] == -5.00
    assert result['total_amount'] == -55.00

@pytest.mark.parametrize("amount,expected_gst,expected_total", [
    (100.00, 10.00, 110.00),
    (50.00, 5.00, 55.00),
    (33.33, 3.33, 36.66),
    (99.99, 10.00, 109.99),
])
def test_calculate_gst_various_amounts(amount, expected_gst, expected_total):
    """Test GST calculation with various amounts."""
    result = calculate_gst(amount)

    assert result['base_amount'] == amount
    assert result['gst_amount'] == expected_gst
    assert result['total_amount'] == expected_total

TypeScript Example:

// Original function
export function validateAustralianMobile(phone: string): boolean {
  const cleaned = phone.replace(/[\s()-]/g, '');
  const mobileRegex = /^(\+61|0)4\d{8}$/;
  return mobileRegex.test(cleaned);
}

// Ask Q: "Generate Jest tests"

// Q Developer generates:
describe('validateAustralianMobile', () => {
  describe('valid phone numbers', () => {
    it('should validate mobile with 04 prefix', () => {
      expect(validateAustralianMobile('0412345678')).toBe(true);
    });

    it('should validate mobile with +61 prefix', () => {
      expect(validateAustralianMobile('+61412345678')).toBe(true);
    });

    it('should validate mobile with spaces', () => {
      expect(validateAustralianMobile('0412 345 678')).toBe(true);
    });

    it('should validate mobile with dashes', () => {
      expect(validateAustralianMobile('0412-345-678')).toBe(true);
    });

    it('should validate mobile with parentheses', () => {
      expect(validateAustralianMobile('(04) 1234 5678')).toBe(true);
    });

    it('should validate mobile with mixed formatting', () => {
      expect(validateAustralianMobile('+61 (4) 1234-5678')).toBe(true);
    });
  });

  describe('invalid phone numbers', () => {
    it('should reject mobile with wrong prefix', () => {
      expect(validateAustralianMobile('0312345678')).toBe(false);
    });

    it('should reject landline number', () => {
      expect(validateAustralianMobile('0298765432')).toBe(false);
    });

    it('should reject too short number', () => {
      expect(validateAustralianMobile('041234567')).toBe(false);
    });

    it('should reject too long number', () => {
      expect(validateAustralianMobile('04123456789')).toBe(false);
    });

    it('should reject number with letters', () => {
      expect(validateAustralianMobile('041234567a')).toBe(false);
    });

    it('should reject empty string', () => {
      expect(validateAustralianMobile('')).toBe(false);
    });

    it('should reject international non-Australian mobile', () => {
      expect(validateAustralianMobile('+1234567890')).toBe(false);
    });
  });
});

Code Refactoring

Optimisation Suggestions

Q Developer identifies performance improvements:

Example: Inefficient Loop:

# Inefficient code
def calculate_totals(items):
    totals = []
    for item in items:
        total = 0
        for price in item['prices']:
            total += price
        totals.append(total)
    return totals

# Q Developer suggests:
def calculate_totals_optimised(items):
    """More efficient using list comprehension and sum()."""
    return [sum(item['prices']) for item in items]

Example: Database Query Optimisation:

# N+1 query problem
def get_users_with_orders():
    users = User.query.all()
    for user in users:
        user.order_count = Order.query.filter_by(user_id=user.id).count()
    return users

# Q Developer suggests:
from sqlalchemy.orm import joinedload
from sqlalchemy import func

def get_users_with_orders_optimised():
    """Single query with join and aggregation."""
    return User.query.outerjoin(Order).group_by(User.id).with_entities(
        User,
        func.count(Order.id).label('order_count')
    ).all()

Modernisation Patterns

Upgrade legacy code patterns:

// Legacy callback pattern
function fetchUserData(userId, callback) {
  api.getUser(userId, function(error, user) {
    if (error) {
      callback(error, null);
    } else {
      api.getOrders(userId, function(error, orders) {
        if (error) {
          callback(error, null);
        } else {
          callback(null, { user, orders });
        }
      });
    }
  });
}

// Ask Q: "Convert to async/await"

// Q Developer suggests:
async function fetchUserData(userId) {
  try {
    const user = await api.getUser(userId);
    const orders = await api.getOrders(userId);
    return { user, orders };
  } catch (error) {
    throw new Error(`Failed to fetch user data: ${error.message}`);
  }
}

AWS Integration

Infrastructure as Code

Generate AWS CDK code:

// Comment: Create CDK stack for serverless API with DynamoDB in Sydney region
// - API Gateway REST API
// - Lambda function (Node.js 18)
// - DynamoDB table with on-demand billing
// - Appropriate IAM permissions

// Q Developer generates:
import * as cdk from 'aws-cdk-lib';
import * as apigateway from 'aws-cdk-lib/aws-apigateway';
import * as dynamodb from 'aws-cdk-lib/aws-dynamodb';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as iam from 'aws-cdk-lib/aws-iam';
import { Construct } from 'constructs';

export class ServerlessApiStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, {
      ...props,
      env: {
        region: 'ap-southeast-2', // Sydney region
      },
    });

    // DynamoDB table
    const table = new dynamodb.Table(this, 'DataTable', {
      partitionKey: {
        name: 'id',
        type: dynamodb.AttributeType.STRING,
      },
      billingMode: dynamodb.BillingMode.PAY_PER_REQUEST,
      encryption: dynamodb.TableEncryption.AWS_MANAGED,
      pointInTimeRecovery: true,
      removalPolicy: cdk.RemovalPolicy.RETAIN,
    });

    // Lambda function
    const apiFunction = new lambda.Function(this, 'ApiFunction', {
      runtime: lambda.Runtime.NODEJS_18_X,
      handler: 'index.handler',
      code: lambda.Code.fromAsset('lambda'),
      environment: {
        TABLE_NAME: table.tableName,
      },
      timeout: cdk.Duration.seconds(30),
      memorySize: 256,
    });

    // Grant Lambda permissions to DynamoDB
    table.grantReadWriteData(apiFunction);

    // API Gateway
    const api = new apigateway.RestApi(this, 'ServerlessApi', {
      restApiName: 'Serverless API',
      description: 'Serverless API with Lambda and DynamoDB',
      deployOptions: {
        stageName: 'prod',
        throttlingRateLimit: 100,
        throttlingBurstLimit: 200,
      },
    });

    // API integration
    const integration = new apigateway.LambdaIntegration(apiFunction);

    const items = api.root.addResource('items');
    items.addMethod('GET', integration);
    items.addMethod('POST', integration);

    const item = items.addResource('{id}');
    item.addMethod('GET', integration);
    item.addMethod('PUT', integration);
    item.addMethod('DELETE', integration);

    // Outputs
    new cdk.CfnOutput(this, 'ApiUrl', {
      value: api.url,
      description: 'API Gateway URL',
    });

    new cdk.CfnOutput(this, 'TableName', {
      value: table.tableName,
      description: 'DynamoDB table name',
    });
  }
}

AWS SDK Usage

Generate AWS SDK code:

# Comment: Create a function to upload file to S3 with server-side encryption
# Use Sydney region, add metadata, handle errors, return S3 URL

# Q Developer generates:
import boto3
from botocore.exceptions import ClientError
from typing import Optional
import os

def upload_to_s3(
    file_path: str,
    bucket_name: str,
    object_key: Optional[str] = None,
    metadata: Optional[dict] = None
) -> Optional[str]:
    """
    Upload file to S3 with encryption and metadata.

    Args:
        file_path: Local path to file
        bucket_name: S3 bucket name
        object_key: S3 object key (defaults to filename)
        metadata: Additional metadata to attach

    Returns:
        S3 URL if successful, None otherwise
    """
    s3_client = boto3.client('s3', region_name='ap-southeast-2')

    if object_key is None:
        object_key = os.path.basename(file_path)

    try:
        # Upload file with encryption
        extra_args = {
            'ServerSideEncryption': 'AES256',
            'Metadata': metadata or {}
        }

        s3_client.upload_file(
            file_path,
            bucket_name,
            object_key,
            ExtraArgs=extra_args
        )

        # Generate S3 URL
        url = f"https://{bucket_name}.s3.ap-southeast-2.amazonaws.com/{object_key}"
        return url

    except ClientError as e:
        error_code = e.response['Error']['Code']

        if error_code == 'NoSuchBucket':
            print(f"Bucket {bucket_name} does not exist")
        elif error_code == 'AccessDenied':
            print("Access denied. Check IAM permissions")
        else:
            print(f"Error uploading to S3: {e}")

        return None

    except FileNotFoundError:
        print(f"File not found: {file_path}")
        return None

Best Practices

1. Review Generated Code

Always review suggestions before accepting:

Check for:

  • Security implications
  • Performance considerations
  • Edge cases
  • Error handling
  • Australian-specific requirements (dates, currency, regulations)

2. Customise for Your Context

Provide context for better suggestions:

# Include context in your codebase
# config.py
REGION = 'ap-southeast-2'
CURRENCY = 'AUD'
DATE_FORMAT = 'DD/MM/YYYY'  # Australian format
GST_RATE = 0.1

# Q Developer uses this context in suggestions

3. Iterative Refinement

Use follow-up prompts to refine:

Initial: "Create a function to process payments"
Refine: "Add error handling for network failures"
Refine: "Add logging for audit trail"
Refine: "Add retry logic with exponential backoff"

4. Security-First Approach

Enable security scanning and address findings:

# Regular security scans
# Schedule weekly full project scans
# Address critical and high severity issues immediately
# Document decisions for medium/low severity items

Cost Optimisation

Pricing Tiers

Free Tier (AWS Builder ID):

  • Code completions
  • Basic security scanning
  • Code explanations
  • Individual use only

Professional Tier ($19/user/month):

  • All Free tier features
  • Enhanced security scanning
  • Admin controls and SSO
  • Usage analytics
  • Priority support

Maximising Value

1. Use for High-Value Tasks:

  • Complex algorithm implementation
  • Security-critical code
  • Integration with unfamiliar APIs
  • Legacy code understanding

2. Team Adoption:

  • Train developers on effective usage
  • Share best practices
  • Create internal prompt libraries
  • Measure productivity improvements

3. Security Scanning ROI:

  • Catch vulnerabilities early
  • Reduce security review time
  • Lower cost of fixing production issues
  • Meet compliance requirements faster

Monitoring and Metrics

Track Productivity

Measure:

  • Code completion acceptance rate
  • Time saved on common tasks
  • Security issues caught
  • Test coverage improvements
  • Documentation completeness

VS Code Extension Metrics:

View → Output → Amazon Q
- Suggestions shown
- Suggestions accepted
- Security findings
- Chat interactions

Administrative Controls

For Professional tier organisations:

# Admin dashboard shows:
# - User adoption rates
# - Feature usage
# - Security scan statistics
# - Cost per user
# - License utilisation

Australian Compliance

Privacy Considerations

Data Handling:

  • Code snippets sent to AWS for processing
  • No long-term storage of code
  • Processed in Australian region where available
  • Not used for model training

Privacy Act Compliance:

  • Document AI tool usage in privacy policies
  • Inform developers about code analysis
  • Establish acceptable use guidelines
  • Regular privacy impact assessments

Security Requirements

industry regulations:

  • Use security scanning for information security
  • Document vulnerability findings
  • Track remediation efforts
  • Include in security testing evidence

Essential Eight:

  • Regular security patching (via suggestions)
  • Application control (review before accepting)
  • Restrict administrative privileges (Professional tier)
  • Multi-factor authentication (IAM Identity Center)

Common Pitfalls

1. Over-Reliance on Suggestions

Don’t accept blindly. Understand what the code does and verify it meets requirements.

2. Ignoring Security Findings

Security scan findings are critical. Address or document decisions for all findings.

3. Incomplete Context

Provide sufficient context in comments and surrounding code for better suggestions.

4. Missing Edge Cases

Generated code may not cover all edge cases. Add tests and validate thoroughly.

5. Copy-Paste Without Understanding

Always understand generated code before using. This is especially important for security-critical code.

Conclusion

Amazon Q Developer accelerates development while maintaining security and quality standards. For Australian development teams, it offers productivity gains, built-in security scanning, and AWS service expertise without compromising compliance requirements.

By integrating Q Developer into your development workflow, reviewing suggestions critically, and leveraging security scanning features, you can deliver secure, high-quality code faster than ever before.

CloudPoint helps Australian businesses adopt Amazon Q Developer with team training, security policy development, and integration with existing development workflows. We ensure your team maximises productivity while maintaining security and compliance standards.

Contact us for an Amazon Q Developer implementation consultation and transform your development process.


Want to Accelerate Development with AI?

CloudPoint helps development teams implement Amazon Q Developer for AI-powered coding assistance. Get in touch to discuss your requirements.

Learn more about our AI Services →