Setup AWS Costs
env0 will assume an AWS IAM Role in your account, in order to query AWS's billing API.
Read more about cross account role delegation.
To begin, log in to your AWS Console, and select the Identity and Access Management (IAM) service.
Create an AWS IAM Policy
- Click on Policies -> Create Policy
- Select the Cost Explorer Service
- Select the
GetCostAndUsage
Action - Choose a name for your policy and save it.
Create an AWS IAM Role
- Click on Roles -> Create Role
- Under type of trusted entity select
Another AWS Account
- Under Account ID enter
913128560467
- Select
**Require external ID**
- Enter an External ID. The value Must be equal to your organization ID.
- Click Next:Permissions
- Select the policy you created in step 2.
- Click Next:Tags
- Click Next:Review
- Enter a name for the role, and click Create Role
- Click on the Role you just created - We will need the
Role ARN
in subsequent steps.
Adding your Cost Role via IaC
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
RoleName:
Type: String
Default: "env0-cost-role"
ExternalId:
Type: String
Default: replace-with-your-org-id
Resources:
CostAssumeRole:
Type: "AWS::IAM::Role"
Properties:
Path: "/"
MaxSessionDuration: 3600
RoleName: !Ref RoleName
Description: "Used by env0 to provide cost-monitoring features."
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Condition:
StringEquals:
sts:ExternalId: !Ref ExternalId
Action: "sts:AssumeRole"
Effect: "Allow"
Principal:
AWS: "arn:aws:iam::913128560467:root"
CostPolicy:
Type: "AWS::IAM::ManagedPolicy"
DependsOn: "CostAssumeRole"
Properties:
ManagedPolicyName:
!Join
- ""
- - !Ref RoleName
- "-policy"
Path: "/"
Description: "Used by env0 to provide cost-monitoring features."
PolicyDocument:
Version: "2012-10-17"
Statement:
- Resource: "*"
Action: "ce:GetCostAndUsage"
Effect: "Allow"
Roles:
- !Ref RoleName
Outputs:
ExternalId:
Value: !Ref ExternalId
Description: "ExternalID for Env0"
AssumeRoleArn:
Value: !GetAtt CostAssumeRole.Arn
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.49"
}
env0 = {
source = "env0/env0"
version = ">= 1.15"
}
}
}
# provider "env0" {
# # env0 Provider expects to find the environment variables defined.
# # to create an API key see: https://docs.env0.com/docs/api-keys
# # ENV0_API_KEY
# # ENV0_API_SECRET
# # or using tf provider variables
# # api_key = ""
# # api_secret = ""
# }
provider "aws" {
region = var.region
}
### VARIABLES
variable "region" {
type = string
default = "us-east-1"
}
variable "assume_role_name" {
type = string
default = "env0-cost-role"
description = "name used for both env0 and AWS"
}
variable "organization_id" {
type = string
description = "env0 org id found under Organization > Settings"
}
### RESOURCES
resource "aws_iam_role" "env0_cost_role" {
name = var.assume_role_name
max_session_duration = 3600 # env0 requirement, 5 hours for SaaS
# 913128560466 is env0's AWS Account ID
# see: https://docs.env0.com/docs/connect-your-cloud-account#using-aws-assume-role
assume_role_policy = jsonencode({
"Version" : "2012-10-17",
"Statement" : [
{
"Effect" : "Allow",
"Principal" : {
"AWS" : "arn:aws:iam::913128560467:root"
},
"Action" : "sts:AssumeRole",
"Condition" : {
"StringEquals" : {
"sts:ExternalId" : "${var.organization_id}"
}
}
}
]
})
tags = {
note = "Created through env0 Bootstrap"
purpose = "Allow env0 Cost Management features"
}
}
resource "aws_iam_role_policy" "test_policy" {
name = "${var.assume_role_name}-cost-policy"
role = aws_iam_role.env0_cost_role.id
# Terraform's "jsonencode" function converts a
# Terraform expression result to valid JSON syntax.
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Resource = "*"
Action = "ce:GetCostAndUsage"
Effect = "Allow"
},
]
})
}
# resource "env0_aws_cost_credentials" "aws_cost_credentials" {
# name = aws_iam_role.env0_cost_role.arn
# arn = aws_iam_role.env0_cost_role.arn
# duration = 3600
# }
output "role_arn" {
value = aws_iam_role.env0_cost_role.arn
}
Enable User Defined Cost Allocation Tags
- Add the Tags called
env0_environment_id
andenv0_project_id
to some resource in your AWS account - Make sure that you add those tags to a resource that has some cost to it, for example an EC2 instance. - Go to the "Billing" Service (Billing & Cost Management). You'll need to log into to the parent account, if you are using sub-accounts.
- Under the left side menu, click Cost allocation tags.
- Under the User-Defined Cost Allocation Tags section, check the checkboxes for the tag-keys
env0_environment_id
andenv0_project_id
. Pay attention that those tags might be available in Cost Allocation Tags only after a few days, usually it's 24 hours but we've seen cases where it took a week for them to show up. - Click Activate
Note
After this step, it can take up to 24 hours to see actual cost values in your environments.
Enable Hourly and Resource Level Data
- Go to the "Billing" Service (Billing & Cost Management). You'll need to log into to the parent account, if you are using sub-accounts.
- Under the left side menu, click Cost Explorer.
- Click on the Launch Cost Explorer button.
- In the Cost Explorer page on the left side menu click on Preferences.
- Under the Hourly and Resource Level Data enable the Hourly and Resource Level Data checkbox and save the changes.
Add Credentials to your Organization
- Under your Organization Settings, Select the Credentials tab
- Under Cost Credentials, click Add Credential
- Select the AWS Assumed Role type, and enter the
Role ARN
from the previous step. The External ID cannot be edited. - Click Add
- Re-run the environments to apply the necessary tags.
Drift after re-running environments
Note that enabling costing introduces drift as new tags will be injected into your resources
Enable cost monitoring
- Go to the Project Settings of the desired project.
- Select the Credentials tab.
- Check the appropriate cloud provider checkbox, and select the credential you created in the steps above.
- Click Save.
Data visibility
Please note that after the configuration of cost monitoring is complete, a redeploy to the environments is needed, and once redeployed it can take 24-48 hours for data to show, depending on the cloud providerâs cost exploration capabilities.
Updated 7 months ago