AWS Cost Optimisation
AWS FinOps: Building a Cost-Conscious Cloud Culture
Establish FinOps practices for sustainable cloud cost management, including governance, accountability, and continuous optimisation for Australian businesses.
CloudPoint Team
Technology alone cannot solve cloud cost challenges. Sustainable cost optimisation requires cultural change - this is FinOps: Financial Operations for cloud. This guide covers building a FinOps practice for Australian businesses.
What is FinOps?
FinOps is a cultural practice bringing together technology, business, and finance to make data-driven spending decisions.
Core Principles:
- Teams collaborate
- Everyone takes ownership
- Decisions are driven by business value
- FinOps teams enable
- Take advantage of variable cost model
- Reports are accessible and timely
Not: Centralised cost policing Is: Distributed accountability with central enablement
FinOps Maturity Stages
Stage 1: Crawl (Reactive)
Characteristics:
- Basic cost visibility
- Manual processes
- Reactive to unexpected bills
- Limited accountability
- Monthly reviews (if any)
Focus: Build visibility and basic controls
Stage 2: Walk (Proactive)
Characteristics:
- Detailed cost visibility
- Some automation
- Regular optimisation
- Team-level budgets
- Weekly reviews
Focus: Establish processes and accountability
Stage 3: Run (Continuous)
Characteristics:
- Real-time visibility
- Extensive automation
- Continuous optimisation
- Cultural integration
- Daily monitoring
Focus: Optimisation and innovation
Most Australian businesses start at Crawl, progress to Walk, few reach Run.
Building Visibility
Can’t optimise what you can’t measure.
Cost Allocation Strategy
Tag Everything:
{
"Environment": "production",
"Application": "customer-portal",
"Owner": "platform-team",
"CostCenter": "engineering",
"Project": "portal-rewrite",
"BusinessUnit": "digital"
}
Enforce tagging with Service Control Policies:
{
"Version": "2012-10-17",
"Statement": [{
"Sid": "RequireTags",
"Effect": "Deny",
"Action": [
"ec2:RunInstances",
"rds:CreateDBInstance"
],
"Resource": "*",
"Condition": {
"StringNotLike": {
"aws:RequestTag/Application": "*",
"aws:RequestTag/Environment": "*",
"aws:RequestTag/Owner": "*"
}
}
}]
}
Cost and Usage Reports (CUR)
Most detailed billing data:
aws cur put-report-definition \
--report-definition '{
"ReportName": "daily-cost-usage-report",
"TimeUnit": "DAILY",
"Format": "Parquet",
"Compression": "Parquet",
"AdditionalSchemaElements": ["RESOURCES"],
"S3Bucket": "cost-reports-bucket",
"S3Prefix": "cur/",
"S3Region": "ap-southeast-2",
"AdditionalArtifacts": ["ATHENA"],
"RefreshClosedReports": true,
"ReportVersioning": "OVERWRITE_REPORT"
}'
Query with Athena for detailed analysis.
Cost Dashboards
Build visibility for all stakeholders:
Executive Dashboard:
- Total monthly spend
- Trend vs previous months
- Budget vs actual
- Top cost drivers
Team Dashboard:
- Team/application spending
- Service breakdown
- Optimisation opportunities
- Savings from optimisations
Finance Dashboard:
- Cost allocation by cost center
- Showback/chargeback reporting
- Budget tracking
- Forecast accuracy
Tools: QuickSight, Grafana, or custom dashboards
Establishing Accountability
Distributed responsibility, central enablement.
Team Ownership Model
Each team owns:
- Their resource costs
- Optimisation within budget
- Cleanup of unused resources
- Tagging compliance
Central FinOps team provides:
- Tools and dashboards
- Best practices guidance
- Optimisation recommendations
- Reserved Instance management
- Budget oversight
Budget Structure
Hierarchical budgets:
Company Budget ($500k/month)
├── Business Unit: Digital ($300k)
│ ├── Product: Customer Portal ($150k)
│ │ ├── Production ($100k)
│ │ ├── Staging ($30k)
│ │ └── Development ($20k)
│ └── Product: Mobile App ($150k)
└── Business Unit: Data Platform ($200k)
Budget alerts:
- 50% consumed - Notification
- 80% consumed - Warning to team
- 100% consumed - Alert to leadership
- 120% consumed - Escalation
Cost Attribution
Map costs to business value:
Customer Portal:
├── Infrastructure: $100k/month
├── Customers served: 50,000
├── Cost per customer: $2/month
└── Revenue per customer: $49/month
Margin after infrastructure: $47/month
Enables business value conversations.
Optimisation Practices
Continuous improvement, not one-time projects.
Regular Review Cadence
Daily (Automated):
- Anomaly detection
- Budget tracking
- Critical alerts
Weekly (Team Leads):
- Team spending review
- Quick wins identification
- Upcoming changes planning
Monthly (FinOps Team):
- Comprehensive cost review
- Optimisation pipeline progress
- Reserved Instance recommendations
- Executive reporting
Quarterly (Executive):
- Strategic planning
- Budget reallocation
- Major initiatives
- Commitment purchases (RIs/SPs)
Optimisation Pipeline
Track and prioritize opportunities:
| Opportunity | Monthly Savings | Effort | Priority | Owner | Status |
|---|---|---|---|---|---|
| Stop unused dev instances | $5,000 | Low | High | DevOps | Done |
| Right-size prod RDS | $8,000 | Medium | High | Platform | In Progress |
| Purchase EC2 Savings Plan | $15,000 | Low | High | FinOps | Planned |
| Migrate to Graviton | $12,000 | High | Medium | Engineering | Backlog |
Prioritization criteria:
- Savings potential
- Implementation effort
- Risk level
- Business impact
Reserved Capacity Strategy
Centralised management with distributed benefit:
FinOps team manages:
- Coverage analysis
- Purchase recommendations
- Procurement
- Modification and exchanges
- Marketplace sales
Teams provide:
- Forecast of steady-state usage
- Long-term plans
- Feedback on coverage
Target coverage: 70-80% of baseline usage
Automation and Tooling
Manual processes don’t scale.
Automated Cleanup
# Lambda function for resource cleanup
import boto3
from datetime import datetime, timedelta
ec2 = boto3.client('ec2')
def cleanup_unused_volumes():
"""Delete unattached EBS volumes older than 7 days"""
volumes = ec2.describe_volumes(
Filters=[{'Name': 'status', 'Values': ['available']}]
)
for volume in volumes['Volumes']:
create_time = volume['CreateTime'].replace(tzinfo=None)
age = (datetime.now() - create_time).days
if age > 7:
# Check for DoNotDelete tag
tags = {t['Key']: t['Value'] for t in volume.get('Tags', [])}
if tags.get('DoNotDelete') != 'true':
print(f"Deleting volume {volume['VolumeId']}")
ec2.delete_volume(VolumeId=volume['VolumeId'])
def cleanup_old_snapshots():
"""Delete snapshots older than 90 days"""
snapshots = ec2.describe_snapshots(OwnerIds=['self'])
cutoff = datetime.now() - timedelta(days=90)
for snapshot in snapshots['Snapshots']:
start_time = snapshot['StartTime'].replace(tzinfo=None)
if start_time < cutoff:
print(f"Deleting snapshot {snapshot['SnapshotId']}")
ec2.delete_snapshot(SnapshotId=snapshot['SnapshotId'])
def lambda_handler(event, context):
cleanup_unused_volumes()
cleanup_old_snapshots()
Schedule weekly with EventBridge.
Cost Anomaly Detection
AWS service detecting unusual spending:
aws ce create-anomaly-monitor \
--anomaly-monitor '{
"MonitorName": "ServiceSpendingMonitor",
"MonitorType": "DIMENSIONAL",
"MonitorDimension": "SERVICE"
}'
aws ce create-anomaly-subscription \
--anomaly-subscription '{
"SubscriptionName": "DailyAnomalyAlerts",
"Threshold": 100,
"Frequency": "DAILY",
"MonitorArnList": ["arn:aws:ce::123456789012:anomalymonitor/abc123"],
"Subscribers": [{
"Type": "SNS",
"Address": "arn:aws:sns:ap-southeast-2:123456789012:cost-alerts"
}]
}'
Automated Optimisation
# Right-sizing automation
import boto3
compute_optimizer = boto3.client('compute-optimizer')
ec2 = boto3.client('ec2')
def auto_rightsize(dry_run=True):
"""Automatically right-size instances with low utilization"""
recommendations = compute_optimizer.get_ec2_instance_recommendations()
for recommendation in recommendations['instanceRecommendations']:
instance_id = recommendation['instanceArn'].split('/')[-1]
current_type = recommendation['currentInstanceType']
recommended_type = recommendation['recommendationOptions'][0]['instanceType']
savings = recommendation['recommendationOptions'][0]['savingsOpportunity']
# Only proceed if savings > 20%
if savings['savingsOpportunityPercentage'] > 20:
print(f"Right-sizing {instance_id}: {current_type} → {recommended_type}")
print(f"Estimated savings: {savings['estimatedMonthlySavings']['value']}")
if not dry_run:
# Stop instance
ec2.stop_instances(InstanceIds=[instance_id])
# Wait for stopped state
waiter = ec2.get_waiter('instance_stopped')
waiter.wait(InstanceIds=[instance_id])
# Modify instance type
ec2.modify_instance_attribute(
InstanceId=instance_id,
InstanceType={'Value': recommended_type}
)
# Start instance
ec2.start_instances(InstanceIds=[instance_id])
Governance and Controls
Guardrails prevent runaway costs.
Service Control Policies
Prevent expensive resource types:
{
"Version": "2012-10-17",
"Statement": [{
"Sid": "DenyExpensiveInstanceTypes",
"Effect": "Deny",
"Action": "ec2:RunInstances",
"Resource": "arn:aws:ec2:*:*:instance/*",
"Condition": {
"StringLike": {
"ec2:InstanceType": [
"*.32xlarge",
"*.24xlarge",
"*.16xlarge"
]
}
}
}]
}
Budget Actions
Automatic responses to budget thresholds:
aws budgets create-budget-action \
--account-id 123456789012 \
--budget-name development-budget \
--action-type APPLY_IAM_POLICY \
--action-threshold ActionThresholdValue=100,ActionThresholdType=PERCENTAGE \
--definition IamActionDefinition={PolicyArn=arn:aws:iam::aws:policy/AWSDenyAll,Roles=[arn:aws:iam::123456789012:role/DeveloperRole]}
Actions:
- Apply restrictive IAM policy
- Disable EC2 launch
- SNS notification
- Custom Lambda function
Cost Allocation Tags Enforcement
Require tags on resource creation:
# Lambda function to enforce tagging
import boto3
ec2 = boto3.client('ec2')
def lambda_handler(event, context):
# Triggered by EC2 RunInstances event
instance_id = event['detail']['responseElements']['instancesSet']['items'][0]['instanceId']
# Get instance tags
instance = ec2.describe_instances(InstanceIds=[instance_id])
tags = instance['Reservations'][0]['Instances'][0].get('Tags', [])
tag_keys = {tag['Key'] for tag in tags}
required_tags = {'Application', 'Environment', 'Owner'}
if not required_tags.issubset(tag_keys):
print(f"Instance {instance_id} missing required tags - terminating")
ec2.terminate_instances(InstanceIds=[instance_id])
# Notify user
# Send SNS notification to instance creator
Reporting and Communication
Stakeholder-appropriate reporting.
Executive Report (Monthly)
Include:
- Total spend vs budget
- Month-over-month trend
- Top 5 cost drivers
- Optimisation savings achieved
- Forecast for next quarter
Format: 1-page summary with visualizations
Team Report (Weekly)
Include:
- Team spending breakdown
- Service-level costs
- Optimisation opportunities
- Action items
Format: Dashboard + Slack/email summary
Finance Report (Monthly)
Include:
- Detailed cost allocation
- Showback/chargeback details
- Budget variance analysis
- Accruals and reservations
Format: Detailed spreadsheet + supporting docs
Incentives and Culture
Make cost optimisation rewarding.
Team Incentives
Celebrate wins:
- Recognize optimisation achievements
- Share savings across organization
- Include in performance reviews
Gamification:
- Leaderboard of cost optimisation
- Monthly “cost hero” award
- Team competitions
Education and Enablement
Training:
- AWS pricing fundamentals
- Cost optimisation techniques
- Tools and dashboards
- FinOps best practices
Office hours:
- Weekly drop-in sessions
- Q&A with FinOps team
- Pair programming on optimisations
Documentation:
- Internal wiki
- Runbooks
- Decision trees
- Case studies
FinOps Team Structure
Small Organization (< 50 people)
Part-time FinOps lead (20-40%):
- Sets up tooling
- Monthly reviews
- Optimisation recommendations
- Ad-hoc support
Medium Organization (50-200 people)
Dedicated FinOps engineer:
- Tooling and automation
- Weekly reviews
- Optimisation pipeline
- Training and enablement
Finance partner (part-time):
- Budgeting
- Forecasting
- Reporting
Large Organization (200+ people)
FinOps team:
- FinOps lead
- 2-3 FinOps engineers
- Finance analyst
- Embedded liaisons in engineering teams
Success Metrics
Track FinOps maturity and impact.
Cost Metrics:
- Cost per customer/transaction
- Unit economics trends
- Budget variance
- Forecast accuracy
Optimisation Metrics:
- Savings realized
- Number of optimisations implemented
- Coverage rates (RI/SP)
- Waste percentage
Operational Metrics:
- Tagging compliance
- Time to resolve cost anomalies
- Team engagement (reviews, training)
- Automation coverage
Conclusion
FinOps is not a one-time cost-cutting exercise but an ongoing cultural practice. For Australian businesses, sustainable cloud cost management requires collaboration between technology, finance, and business teams.
Start small - build visibility, establish accountability, implement quick wins. Progress to automation, governance, and cultural integration. The result: sustainable cost optimisation aligned with business value.
CloudPoint helps Australian businesses establish FinOps practices - from initial assessment through implementation and ongoing optimisation. Contact us to start your FinOps journey.
Ready to Implement FinOps?
CloudPoint helps Australian businesses implement FinOps practices that deliver ongoing cost visibility and savings. Get in touch to discuss your cost management needs.