,

Deploy AWS FinOps Agent: A Hands-On Tutorial

Illustration: deploying the AWS FinOps Agent, hands-on tutorial

If you’ve ever gotten a Slack ping at 6 AM because someone spun up a fleet of instances and forgot about them, you already know why FinOps teams are excited about a managed way to deploy AWS FinOps Agent instead of waiting for next month’s invoice to break the news. This is a managed agent built on Amazon Bedrock that sits on top of your Cost Explorer and Cost and Usage Report data, watches for anomalies around the clock, answers plain-English questions about spend, and pushes scheduled reports to whoever needs to see them. No cron job held together with duct tape, no Lambda function you wrote in 2022 and are now scared to touch. Let’s build it properly, with permissions scoped the way they should be — read-only, boring, and impossible to abuse.

Prerequisites Before You Deploy AWS FinOps Agent

  • An AWS account (or AWS Organizations management account) with billing access enabled for the IAM principal you’re using.
  • Cost Explorer enabled — it’s a one-time toggle, and it takes roughly 24 hours to backfill historical data, so flip it on before you do anything else.
  • Amazon Bedrock model access enabled in your target region (Bedrock console > Model access).
  • Permissions to create IAM roles and policies. See the IAM roles documentation if you need a refresher on trust policies.
  • AWS CLI v2 configured with credentials that can call ce:*, compute-optimizer:*, cur:*, and bedrock:* APIs for setup.
  • An AWS Cost and Usage Report (CUR) export configured if you want line-item detail behind the agent’s answers — see the CUR documentation.

Got all that? Good. Here’s the part where we actually do the thing.

  1. Lock down a least-privilege IAM role first

    Don’t let anyone hand this agent an AdministratorAccess policy “just to get it working.” It never needs to touch anything except read-only cost, billing, and recommendation APIs. Start with a trust policy so only Bedrock can assume the role:

    cat > trust-policy.json << 'EOF'
    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Principal": { "Service": "bedrock.amazonaws.com" },
          "Action": "sts:AssumeRole",
          "Condition": {
            "StringEquals": { "aws:SourceAccount": "123456789012" }
          }
        }
      ]
    }
    EOF
    
    aws iam create-role \
      --role-name FinOpsAgentReadOnlyRole \
      --assume-role-policy-document file://trust-policy.json \
      --description "Least-privilege execution role for AWS FinOps Agent - read-only cost and recommendation access"

    Now attach a permission policy scoped to exactly the APIs the agent needs — nothing that can spin up, terminate, or resize anything:

    cat > finops-agent-policy.json << 'EOF'
    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Sid": "CostExplorerReadOnly",
          "Effect": "Allow",
          "Action": [
            "ce:GetCostAndUsage",
            "ce:GetAnomalies",
            "ce:GetAnomalyMonitors",
            "ce:GetAnomalySubscriptions"
          ],
          "Resource": "*"
        },
        {
          "Sid": "ComputeOptimizerReadOnly",
          "Effect": "Allow",
          "Action": [
            "compute-optimizer:GetEC2InstanceRecommendations",
            "compute-optimizer:GetEBSVolumeRecommendations"
          ],
          "Resource": "*"
        },
        {
          "Sid": "CURReadOnly",
          "Effect": "Allow",
          "Action": [ "cur:DescribeReportDefinitions" ],
          "Resource": "*"
        },
        {
          "Sid": "InvokeAgentSelf",
          "Effect": "Allow",
          "Action": [ "bedrock:InvokeAgent" ],
          "Resource": "arn:aws:bedrock:*:123456789012:agent/*"
        }
      ]
    }
    EOF
    
    aws iam put-role-policy \
      --role-name FinOpsAgentReadOnlyRole \
      --policy-name FinOpsAgentReadOnlyPolicy \
      --policy-document file://finops-agent-policy.json

    Notice what's missing: no ec2:TerminateInstances, no ce:* write actions, nothing from Cost Optimization Hub that could apply a recommendation automatically. This agent looks, it doesn't touch.

  2. Enable Bedrock model access in-region

    Model access toggles are console-only per region — head to Bedrock > Model access > Manage model access, enable the Claude model family you plan to use, and confirm. Then verify from the CLI so you're not guessing:

    aws bedrock list-foundation-models \
      --region us-east-1 \
      --query "modelSummaries[?contains(modelId,'anthropic')].modelId" \
      --output table

    If that returns an empty table, the toggle didn't take. Go back and check the box again — yes, really.

  3. Stand up a cost anomaly monitor

    The agent needs something to watch. Create a dimensional anomaly monitor scoped to service-level spend so it has a baseline to compare against:

    aws ce create-anomaly-monitor \
      --anomaly-monitor '{
        "MonitorName": "finops-agent-monitor",
        "MonitorType": "DIMENSIONAL",
        "MonitorDimension": "SERVICE"
      }'

    Give it a day or two to build a baseline before you expect meaningful anomaly output — statistics need history, even AI-flavored ones.

  4. Create and configure the FinOps Agent

    With the role and monitor in place, create the agent itself and point it at your read-only execution role:

    aws bedrock-agent create-agent \
      --agent-name "finops-cost-agent" \
      --agent-resource-role-arn arn:aws:iam::123456789012:role/FinOpsAgentReadOnlyRole \
      --foundation-model anthropic.claude-sonnet-4-5-v1:0 \
      --instruction "You are a read-only FinOps analyst. Answer cost questions using Cost Explorer and CUR data, investigate anomalies flagged by AWS Cost Anomaly Detection, and surface Cost Optimization Hub and Compute Optimizer recommendations. Never take any action that modifies infrastructure, budgets, or spend." \
      --idle-session-ttl-in-seconds 1800
    
    aws bedrock-agent prepare-agent --agent-id ABCD1234EF
    
    aws bedrock-agent create-agent-alias \
      --agent-id ABCD1234EF \
      --agent-alias-name prod

    Full setup and configuration reference lives in the Amazon Bedrock Agents user guide if you want to tune session behavior or add knowledge bases later.

  5. Illustration: deploying the AWS FinOps Agent, hands-on tutorial
  6. Ask it a natural-language cost question

    This is the payoff. Invoke the agent like you'd message a colleague, not like you're filing a support ticket:

    aws bedrock-agent-runtime invoke-agent \
      --agent-id ABCD1234EF \
      --agent-alias-id prod \
      --session-id session-001 \
      --input-text "Why did our EC2 spend jump last week, and what's driving it?" \
      response.json
    
    cat response.json

    Expect a plain-English breakdown, not a wall of JSON: something like "EC2 spend rose 18% week-over-week, driven mostly by an r7g family scale-out in us-east-1 tied to a batch job that didn't scale back down. Recommend reviewing the auto scaling policy for the 'batch-processing' ASG." That's the whole point — it reads the raw usage data so you don't have to.

  7. Trigger an anomaly investigation

    Don't wait for a real anomaly to test this. Pull recent anomalies and hand one directly to the agent for a deeper look:

    aws ce get-anomalies \
      --date-interval StartDate=2026-09-01,EndDate=2026-09-14 \
      --monitor-arn arn:aws:ce::123456789012:anomalymonitor/finops-agent-monitor
    
    aws bedrock-agent-runtime invoke-agent \
      --agent-id ABCD1234EF \
      --agent-alias-id prod \
      --session-id session-002 \
      --input-text "Investigate anomaly ID a1b2c3d4 and tell me the root cause and dollar impact." \
      investigation.json

    The agent correlates the anomaly against CUR line items and Compute Optimizer output, then returns root cause, blast radius, and a remediation suggestion — for example, flagging an idle EBS volume for cleanup, or pointing at a right-sizing opportunity onto the new R9g/R9gd Graviton5 memory-optimized instances. It won't touch anything — it just tells you what to fix and how much it's costing you to not fix it.

  8. Schedule your first automated report

    Set a cadence with EventBridge Scheduler instead of babysitting a manual export every Monday:

    aws scheduler create-schedule \
      --name "finops-agent-weekly-report" \
      --schedule-expression "rate(7 days)" \
      --flexible-time-window '{"Mode":"OFF"}' \
      --target '{
        "Arn": "arn:aws:lambda:us-east-1:123456789012:function:finops-agent-report-dispatcher",
        "RoleArn": "arn:aws:iam::123456789012:role/FinOpsSchedulerInvokeRole",
        "Input": "{\"agentId\":\"ABCD1234EF\",\"agentAliasId\":\"prod\",\"reportType\":\"weekly-summary\"}"
      }'

    Wire the dispatcher's output to an SNS topic so the report lands wherever your team already lives:

    aws sns create-topic --name finops-agent-reports
    
    aws sns subscribe \
      --topic-arn arn:aws:sns:us-east-1:123456789012:finops-agent-reports \
      --protocol email \
      --notification-endpoint finops-team@yourcompany.com

    Details on schedule expressions and flexible time windows are in the EventBridge Scheduler documentation. Confirm the SNS subscription, wait for the first cycle, and you'll get a report summarizing week-over-week spend, any anomalies investigated, and outstanding recommendations pulled from Cost Optimization Hub and Compute Optimizer — Graviton5 right-sizing candidates included, if you've got workloads that qualify.

What you built: a scoped, read-only IAM role that can't touch a single running resource; a Bedrock-based FinOps Agent wired to Cost Explorer, cost anomaly detection, and Compute Optimizer; a working natural-language interface for cost questions; a tested anomaly-investigation workflow; and a recurring scheduled report landing in your team's inbox without anyone remembering to run it manually. That's a real cost governance loop, not a slide from a re:Invent keynote.

At Enkompass (enkompass.net), this is our home turf. We've clawed back six figures in annual spend for clients who thought their bill was "already optimized." If you'd rather have seasoned cloud people handle it instead of learning the hard way at 2 AM, let's talk. Reach out through our contact page or call us directly at +1-828-436-5667 — we'll help you turn this from a someday-project into a done-deal.

Ready when you are

Let’s map your route to AWS

A free 60-minute architecture review with a senior engineer. No slides, no SDR, just a plan.