AWS AI Services
Amazon Q Business: Complete Implementation Guide for Australian Enterprises
Comprehensive guide to implementing Amazon Q Business for Australian organisations, covering setup, integration with enterprise systems, security configuration, and optimisation strategies.
CloudPoint Team
Amazon Q Business is an AI-powered assistant that connects to your enterprise data sources, enabling employees to ask questions and get answers grounded in your organisation’s knowledge. For Australian businesses, Q Business offers a secure, compliant way to democratise access to institutional knowledge.
What is Amazon Q Business?
Amazon Q Business is a fully managed generative AI assistant designed for enterprise use. It connects to your existing data sources—SharePoint, S3, Confluence, Salesforce, and more—allowing employees to query organizational knowledge through natural language.
Key Capabilities
Enterprise Connectivity:
- 40+ native data connectors
- SharePoint, Confluence, S3, Salesforce
- Microsoft Teams, Slack integration
- Custom data sources via API
Intelligent Search:
- Semantic search across all sources
- Context-aware responses
- Source citations
- Permission-aware results
Security & Compliance:
- User-level access controls
- Data encryption
- Audit logging
- Industry regulations alignment
Customisation:
- Brand customisation
- Topic-specific applications
- Admin controls
- Usage analytics
Use Cases
Knowledge Management
Problem: Information scattered across systems, hard to find Solution: Single interface to search all company knowledge
Employee: "What is our expense approval process for international travel?"
Q Business: Based on your Finance Policy v3.2, international travel
expenses over $2,000 require CFO approval. Submit requests through
the Expense Portal at least 2 weeks in advance...
Sources: Finance Policy (SharePoint), Travel Guidelines (Confluence)
Customer Support
Problem: Support teams spend time searching for answers Solution: Instant access to product docs, policies, troubleshooting
Support Agent: "How do I troubleshoot API timeout errors in v2.1?"
Q Business: API timeout errors in v2.1 are commonly caused by:
1. Rate limiting (check X-RateLimit headers)
2. Database connection pool exhaustion
3. Downstream service unavailability
Troubleshooting steps: [detailed steps from technical documentation]
Sources: API Documentation v2.1, Known Issues Database
Sales Enablement
Problem: Sales team needs quick access to proposals, pricing, case studies Solution: Instant retrieval of relevant sales materials
Sales Rep: "Do we have case studies for fintech companies in Australia?"
Q Business: Yes, we have 3 case studies:
1. Payment processor - 60% cost reduction
2. Digital bank - PCI DSS compliance implementation
3. Wealth management - Cloud migration
[Provides summaries and links]
Sources: Sales Collateral (S3), Customer Success Stories (Salesforce)
Architecture
Components
Data Sources:
- Corporate SharePoint
- Confluence spaces
- S3 document repositories
- Salesforce knowledge base
- Microsoft Teams channels
Amazon Q Business Application:
- Indexes and embeddings
- Retriever
- Foundation model
- Response generator
Access Layer:
- Web interface
- Slack/Teams integration
- API access
- Mobile app
Security:
- IAM Identity Center
- Permission synchronisation
- Audit logs
- Encryption
Implementation Steps
1. Prerequisites
IAM Identity Center: Must be enabled for user authentication
# Check if Identity Center is enabled
aws sso-admin list-instances --region ap-southeast-2
# If not enabled, enable through AWS Console
# Organizations → Services → IAM Identity Center → Enable
Required Permissions:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"qbusiness:*",
"iam:PassRole"
],
"Resource": "*"
}
]
}
2. Create Q Business Application
Using AWS Console or IaC:
# CloudFormation
Resources:
QBusinessApplication:
Type: AWS::QBusiness::Application
Properties:
DisplayName: Company Knowledge Assistant
Description: Enterprise AI assistant for company knowledge
RoleArn: !GetAtt QBusinessRole.Arn
IdentityCenterInstanceArn: !Ref IdentityCenterArn
AttachmentsConfiguration:
AttachmentsControlMode: ENABLED
QBusinessRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: qbusiness.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AmazonQBusinessFullAccess
3. Configure Data Sources
SharePoint Connector
import boto3
qbusiness = boto3.client('qbusiness', region_name='ap-southeast-2')
# Create SharePoint data source
response = qbusiness.create_data_source(
applicationId='APP_ID',
indexId='INDEX_ID',
displayName='Company SharePoint',
configuration={
'type': 'SHAREPOINTONLINE',
'connectionConfiguration': {
'repositoryEndpointMetadata': {
'siteUrls': [
'https://company.sharepoint.com/sites/policies',
'https://company.sharepoint.com/sites/hr'
]
}
},
'repositoryConfigurations': {
'document': {
'fieldMappings': [
{
'dataSourceFieldName': 'title',
'indexFieldName': 'title',
'indexFieldType': 'STRING'
},
{
'dataSourceFieldName': 'created',
'indexFieldName': 'created_date',
'indexFieldType': 'DATE'
}
]
}
},
'syncConfiguration': {
'syncMode': 'FULL_CRAWL'
},
'vpcConfiguration': {
'subnetIds': ['subnet-xxx'],
'securityGroupIds': ['sg-xxx']
}
},
roleArn='arn:aws:iam::ACCOUNT_ID:role/QBusinessDataSourceRole'
)
S3 Connector
# Create S3 data source
response = qbusiness.create_data_source(
applicationId='APP_ID',
indexId='INDEX_ID',
displayName='Document Repository',
configuration={
'type': 'S3',
'connectionConfiguration': {
'repositoryEndpointMetadata': {
'bucketName': 'company-documents-ap-southeast-2'
}
},
'documentEnrichmentConfiguration': {
'inlineConfigurations': [
{
'condition': {
'conditionOnValue': {
'key': '_file_type',
'value': {
'stringValue': 'pdf'
},
'operator': 'EQUALS'
}
},
'target': {
'key': 'department',
'value': {
'stringValue': 'extracted_from_filename'
}
}
}
]
}
},
roleArn='arn:aws:iam::ACCOUNT_ID:role/QBusinessDataSourceRole'
)
Confluence Connector
# Create Confluence data source
response = qbusiness.create_data_source(
applicationId='APP_ID',
indexId='INDEX_ID',
displayName='Engineering Wiki',
configuration={
'type': 'CONFLUENCECLOUD',
'connectionConfiguration': {
'repositoryEndpointMetadata': {
'hostUrl': 'https://company.atlassian.net'
},
'authenticationConfiguration': {
'basicAuthentication': {
'secretArn': 'arn:aws:secretsmanager:ap-southeast-2:ACCOUNT:secret:confluence-creds'
}
}
},
'repositoryConfigurations': {
'page': {
'fieldMappings': [
{
'dataSourceFieldName': 'space',
'indexFieldName': 'confluence_space',
'indexFieldType': 'STRING'
}
]
}
},
'additionalProperties': {
'inclusionPatterns': ['Engineering/*', 'Product/*'],
'exclusionPatterns': ['Archive/*']
}
},
roleArn='arn:aws:iam::ACCOUNT_ID:role/QBusinessDataSourceRole'
)
4. Start Data Sync
# Trigger synchronisation
sync_response = qbusiness.start_data_source_sync_job(
applicationId='APP_ID',
indexId='INDEX_ID',
dataSourceId='DATA_SOURCE_ID'
)
job_id = sync_response['executionId']
# Monitor sync progress
import time
while True:
status = qbusiness.get_data_source_sync_job(
applicationId='APP_ID',
indexId='INDEX_ID',
dataSourceId='DATA_SOURCE_ID',
executionId=job_id
)
state = status['status']
print(f"Sync status: {state}")
if state in ['SUCCEEDED', 'FAILED', 'STOPPED']:
break
time.sleep(30)
if state == 'SUCCEEDED':
stats = status['metrics']
print(f"Documents added: {stats.get('documentsAdded', 0)}")
print(f"Documents modified: {stats.get('documentsModified', 0)}")
print(f"Documents deleted: {stats.get('documentsDeleted', 0)}")
Access Control
User Permissions
Q Business respects source system permissions:
# Configure permission sync
qbusiness.update_data_source(
applicationId='APP_ID',
indexId='INDEX_ID',
dataSourceId='DATA_SOURCE_ID',
configuration={
'accessControlListConfiguration': {
'keyPath': 's3://permissions-bucket/acl-data/'
}
}
)
ACL File Format (JSON):
{
"documentId": "document-123",
"accessControlList": [
{
"name": "john.smith@company.com",
"type": "USER",
"access": "ALLOW"
},
{
"name": "engineering-team",
"type": "GROUP",
"access": "ALLOW"
}
]
}
Admin Controls
# Create admin control topic
qbusiness.create_admin_control(
applicationId='APP_ID',
topicConfiguration={
'name': 'Blocked Topics',
'description': 'Topics Q Business should not answer',
'exampleChatMessages': [
"What are employee salaries?",
"Show me confidential financial data"
],
'rules': [
{
'includedUsersAndGroups': {
'userIds': ['*'] # All users
},
'ruleType': 'CONTENT_BLOCKER_RULE',
'ruleConfiguration': {
'blockedPhrases': [
'salary',
'compensation',
'confidential financial'
]
}
}
]
}
)
Integration
Slack Integration
# Configure Slack integration
qbusiness.create_web_experience(
applicationId='APP_ID',
title='Company Q Assistant',
subtitle='Ask questions about company knowledge',
samplePromptsControlMode='ENABLED',
roleArn='arn:aws:iam::ACCOUNT:role/QBusinessWebExperienceRole'
)
# Enable Slack channel
# This is done through AWS Console:
# Q Business → Applications → [App] → Integrations → Slack
# Follow OAuth flow to authorize
Microsoft Teams
Similar process through Teams admin center.
Custom API Integration
import boto3
from typing import List, Dict
class QBusinessClient:
def __init__(self, application_id: str, region: str = 'ap-southeast-2'):
self.app_id = application_id
self.client = boto3.client('qbusiness', region_name=region)
def chat(
self,
user_id: str,
message: str,
conversation_id: str = None,
attachments: List[Dict] = None
) -> Dict:
"""Send message to Q Business"""
request = {
'applicationId': self.app_id,
'userId': user_id,
'userMessage': message
}
if conversation_id:
request['conversationId'] = conversation_id
if attachments:
request['attachments'] = attachments
response = self.client.chat(**request)
return {
'conversationId': response['conversationId'],
'answer': response['systemMessage'],
'sources': response.get('sourceAttributions', [])
}
# Usage
q_client = QBusinessClient(application_id='APP_ID')
response = q_client.chat(
user_id='john.smith@company.com',
message='What is our remote work policy?'
)
print(response['answer'])
Web Application
import { QBusinessClient, ChatCommand } from "@aws-sdk/client-qbusiness";
interface ChatMessage {
role: 'user' | 'assistant';
content: string;
sources?: Source[];
}
interface Source {
title: string;
uri: string;
excerpt: string;
}
class QBusinessChat {
private client: QBusinessClient;
private applicationId: string;
private conversationId?: string;
constructor(applicationId: string, region: string = 'ap-southeast-2') {
this.applicationId = applicationId;
this.client = new QBusinessClient({ region });
}
async sendMessage(userId: string, message: string): Promise<ChatMessage> {
const command = new ChatCommand({
applicationId: this.applicationId,
userId: userId,
userMessage: message,
conversationId: this.conversationId
});
const response = await this.client.send(command);
// Store conversation ID for follow-ups
this.conversationId = response.conversationId;
return {
role: 'assistant',
content: response.systemMessage || '',
sources: this.extractSources(response)
};
}
private extractSources(response: any): Source[] {
return (response.sourceAttributions || []).map((attr: any) => ({
title: attr.title || '',
uri: attr.url || '',
excerpt: attr.snippet || ''
}));
}
resetConversation() {
this.conversationId = undefined;
}
}
// React component
import React, { useState } from 'react';
export function QBusinessInterface() {
const [messages, setMessages] = useState<ChatMessage[]>([]);
const [input, setInput] = useState('');
const qClient = new QBusinessChat(process.env.QBUSINESS_APP_ID!);
const sendMessage = async () => {
const userMessage = { role: 'user' as const, content: input };
setMessages([...messages, userMessage]);
setInput('');
const response = await qClient.sendMessage(
'user@company.com',
input
);
setMessages(prev => [...prev, response]);
};
return (
<div>
<div className="messages">
{messages.map((msg, i) => (
<div key={i} className={`message ${msg.role}`}>
<p>{msg.content}</p>
{msg.sources && (
<div className="sources">
{msg.sources.map((src, j) => (
<a key={j} href={src.uri}>{src.title}</a>
))}
</div>
)}
</div>
))}
</div>
<input
value={input}
onChange={(e) => setInput(e.target.value)}
onKeyPress={(e) => e.key === 'Enter' && sendMessage()}
/>
</div>
);
}
Monitoring
CloudWatch Metrics
import boto3
from datetime import datetime, timedelta
cloudwatch = boto3.client('cloudwatch', region_name='ap-southeast-2')
def get_q_business_metrics(application_id: str):
"""Retrieve Q Business usage metrics"""
end_time = datetime.utcnow()
start_time = end_time - timedelta(days=7)
# User queries
queries_response = cloudwatch.get_metric_statistics(
Namespace='AWS/QBusiness',
MetricName='UserQueries',
Dimensions=[
{'Name': 'ApplicationId', 'Value': application_id}
],
StartTime=start_time,
EndTime=end_time,
Period=86400, # Daily
Statistics=['Sum']
)
# Average response time
latency_response = cloudwatch.get_metric_statistics(
Namespace='AWS/QBusiness',
MetricName='ResponseLatency',
Dimensions=[
{'Name': 'ApplicationId', 'Value': application_id}
],
StartTime=start_time,
EndTime=end_time,
Period=86400,
Statistics=['Average']
)
return {
'total_queries': sum(dp['Sum'] for dp in queries_response['Datapoints']),
'avg_latency_ms': sum(dp['Average'] for dp in latency_response['Datapoints']) / len(latency_response['Datapoints'])
}
Usage Analytics
# Get conversation analytics
def get_conversation_analytics(application_id: str):
qbusiness = boto3.client('qbusiness', region_name='ap-southeast-2')
# List recent conversations
conversations = qbusiness.list_conversations(
applicationId=application_id,
maxResults=100
)
analytics = {
'total_conversations': len(conversations['conversations']),
'active_users': set(),
'common_topics': {}
}
for conv in conversations['conversations']:
analytics['active_users'].add(conv['userId'])
analytics['unique_users'] = len(analytics['active_users'])
return analytics
Cost Optimisation
Pricing Components
Message Units:
- $0.50 per 1,000 messages
- Message = user question + Q Business response
Data Source Indexing:
- $0.25 per 1,000 documents per month
- Syncs included
User Subscriptions (for Power Users):
- $20 per user per month
- Unlimited messages
Optimisation Strategies
1. Right-size Data Sources: Only index necessary documents
# Exclude archived/old content
configuration = {
'additionalProperties': {
'exclusionPatterns': [
'*/archive/*',
'*/old/*',
'*/deprecated/*'
],
'inclusionFileTypePatterns': [
'*.pdf',
'*.docx',
'*.md'
]
}
}
2. Implement Caching: Cache common queries
3. User Subscription Model: For heavy users, subscriptions more cost-effective
4. Monitor Usage: Track and optimise based on metrics
Best Practices
Document Preparation
- Clean Metadata: Ensure accurate titles, authors, dates
- Remove Duplicates: Deduplicate before indexing
- Update Regularly: Keep content current
- Structure: Use clear headings and formatting
Query Optimisation
Guide users with sample prompts:
qbusiness.update_web_experience(
applicationId='APP_ID',
webExperienceId='WEB_EXP_ID',
samplePromptsControlMode='ENABLED'
)
# Configure sample prompts
sample_prompts = [
"What is our expense policy?",
"How do I request annual leave?",
"Where can I find sales templates?"
]
Security
- Regular Access Reviews: Audit user permissions
- Data Classification: Tag sensitive documents
- Monitoring: Enable CloudTrail logging
- Testing: Verify permission inheritance
Conclusion
Amazon Q Business enables Australian organisations to unlock the value of their enterprise knowledge through secure, intelligent AI assistance. By following these implementation patterns and best practices, you can deploy Q Business quickly while maintaining security and compliance.
CloudPoint specialises in implementing Amazon Q Business for Australian enterprises and regulated industries. We can help you connect your data sources, configure security controls, and optimise for your specific use cases.
Contact us for an Amazon Q Business implementation consultation.
Ready to Implement Amazon Q Business?
CloudPoint helps Australian businesses deploy Amazon Q Business—connecting AI to your company data securely. Get in touch to discuss your requirements.