Skip to main content
  1. Posts/

Let Your Finance Team Track AWS Spend

·2 mins·

Need to delegate access to your AWS billing dashboard to folks in your finance team? Here’s how you can define the necessary policies using Pulumi for your Infrastructure As Code (IaC).

First, create an IAM Group:

const group = new aws.iam.Group("finance", { path });

Next, define the policy:

function billingFullPolicy() {
  const policyDefn: aws.iam.PolicyDocument = {
    Version: "2012-10-17",
    Statement: [
      {
        Action: [
          "aws-portal:*Billing",
          "aws-portal:*PaymentMethods",
          "aws-portal:ViewUsage",
          "billing:ListBillingViews",
          "ce:*",
          "cur:*",
          "pricing:*",
          "purchase-orders:*",
          "support:AddAttachmentsToSet",
          "support:CreateCase",
          "sustainability:GetCarbonFootprintSummary",
          "tax:*",
        ],
        Resource: "*",
        Effect: "Allow",
        Sid: "FullBillingAndReporting",
      },
    ],
  };

  return new aws.iam.Policy("GrantFullAccessToBilling", {
    description: `Allow manage billing`,
    policy: policyDefn,
  });
}

Note this is quite a permissive policy, and you might want to reserve it only for financial ‘administrators’.

A Read-only billing policy might be better suited for reporting users, which might exclude creating Cost and Usage reports (cur:*) or accessing account settings:

function billingReadOnlyPolicy() {
  const policyDefn: aws.iam.PolicyDocument = {
    Version: '2012-10-17',
    Statement: [
      {
        Action: [
          'aws-portal:ViewBilling',
          'aws-portal:ViewUsage',
          'billing:ListBillingViews',
          'ce:GetCostAndUsage'
          'cur:DescribeReportDefinitions',
          'pricing:*',
          'purchase-orders:View*',
          'support:AddAttachmentsToSet',
          'support:CreateCase',
          'sustainability:GetCarbonFootprintSummary',
          'tax:Get*',
        ],
        Resource: '*',
        Effect: 'Allow',
        Sid: 'FullBillingAndReporting',
      },
      {
        Effect: 'Deny',
        Action: 'aws-portal:*Account',
        Resource: '*',
        Sid: ''
      }
    ],
  }

  return new aws.iam.Policy('GrantReadAccessToBilling', {
    description: 'Allow read-only access to billing',
    policy: policyDefn,
  })
}

Attach the desired policy to the Finance group you created.

new aws.iam.GroupPolicyAttachment("attach-full-billing", {
  group: group.name,
  policyArn: billingFullPolicy().arn,
});

Now all the IAM users you add to this group will be able to access the these billing permissions.

AWS provides plenty of billing examples, and it’s a simple matter of copying the JSON policy into your Pulumi definitions, using the typescript template above. As an added bonus, if you’re using Typescript, your editor should autoformat the JSON definition for you.

IaC gives you a number of benefits. You have an excellent audit trail, since all policy versions are in a git repository. Your infrastructure is expressed using a familiar, Turing-complete programming language. You manage and deploy code using the same toolchains your DevOps team uses daily.

When you add IaC to your CI/CD pipeline, your cloud infrastructure stays in sync with your definitions. With a tool like Pulumi you also get a web-based dashboard a history of all updates applied to your cloud infrastructure.

(While it sounds like I’m affiliated with Pulumi, I’m not. I am however happy user of their product!)