aws / aws-cdk

The AWS Cloud Development Kit is a framework for defining cloud infrastructure in code
https://aws.amazon.com/cdk
Apache License 2.0
11.66k stars 3.92k forks source link

đź“ŠTracking: AWS CE #8635

Open SomayaB opened 4 years ago

SomayaB commented 4 years ago

Add your +1 đź‘Ť to help us prioritize high-level constructs for this service


Overview:

AWS Docs

Maturity: CloudFormation Resources Only

See the AWS Construct Library Module Lifecycle doc for more information about maturity levels.

Implementation:

See the CDK API Reference for more implementation details.

Issue list:


This is a đź“ŠTracking Issue

seanWLawrence commented 2 years ago

Hey team, even though there are only a few thumbs up, I'd like to take this on if that's alright!

If so, I'll start on the modeling/README file. So far I was thinking something like the following as an idea for the cost category, based on the feedback from #16564.

    const sharedBusinessUnit = CostCategoryRule.regular({
      value: "Shared",
      rule: Expression.dimension({
        key: DimensionValuesKey.LINKED_ACCOUNT,
        matchOptions: [MatchOption.EQUALS],
        values: ["222222222222"],
      }),
    });

    const businessUnit = new CostCategory(this, "BusinessUnit", {
      name: "Business Unit",
      defaultValue: "Other",
      ruleVersion: RuleVersion.COST_CATEGORY_EXPRESSION_V1,
      rules: [
        CostCategoryRule.inheritedValue({
          dimensionName: CostCategoryInheritedValueDimensionName.TAG,
          dimensionKey: "BusinessUnit",
        }),
        CostCategoryRule.regular({
          value: "Amazon.com",
          rule: Expression.dimension({
            key: DimensionValuesKey.LINKED_ACCOUNT,
            matchOptions: [MatchOption.EQUALS],
            values: ["11111111"],
          }),
        }),
        CostCategoryRule.regular({
          value: "Amazon Web Services",
          rule: Expression.tag({
            key: "Application",
            matchOptions: [MatchOption.CONTAINS, MatchOption.CASE_INSENSITIVE],
            values: ["AWS", "Amazon Web Services"],
          }),
        }),
        sharedBusinessUnit,
      ],
    });

    businessUnit.addSplitChargeRule(
      CostCategorySplitChargeRule.proportional({
        source: sharedBusinessUnit,
        targets: businessUnit.rules,
      })
    );
seanWLawrence commented 2 years ago

I'm also thinking we can add a type to model the account numbers and other dimension values so we can add validation. For example: DimensionValue.awsAccount("11111111")) and DimensionValue.dimension("Shared") throw if the account number or string doesn't pass validation for correct length, etc. though I'm not sure if that's overkill. Here's how that could look:

    const sharedBusinessUnit = CostCategoryRule.regular({
      value: ExpressionValue.dimension("Shared"),
      rule: Expression.dimension({
        key: DimensionValuesKey.LINKED_ACCOUNT,
        matchOptions: [MatchOption.EQUALS],
        values: [ExpressionValue.awsAccount("222222222222")],
      }),
    });

    const businessUnit = new CostCategory(this, "BusinessUnit", {
      name: ExpressionValue.costCategory("Business Unit"),
      defaultValue: ExpressionValue.costCategory("Other"),
      ruleVersion: RuleVersion.COST_CATEGORY_EXPRESSION_V1,
      rules: [
        CostCategoryRule.inheritedValue({
          dimensionName: CostCategoryInheritedValueDimensionName.TAG,
          dimensionKey: ExpressionValue.costCategory("BusinessUnit"),
        }),
        CostCategoryRule.regular({
          value: ExpressionValue.costCategory("Amazon.com"),
          rule: Expression.dimension({
            key: DimensionValuesKey.LINKED_ACCOUNT,
            matchOptions: [MatchOption.EQUALS],
            values: [ExpressionValue.awsAccount("111111111111")],
          }),
        }),
        CostCategoryRule.regular({
          value: ExpressionValue.costCategory("Amazon Web Services"),
          rule: Expression.tag({
            key: ExpressionValue.dimension("Application"),
            matchOptions: [MatchOption.CONTAINS, MatchOption.CASE_INSENSITIVE],
            values: [
              ExpressionValue.dimension("AWS"),
              ExpressionValue.dimension("Amazon Web Services"),
            ],
          }),
        }),
        sharedBusinessUnit,
      ],
    });

    businessUnit.addSplitChargeRule(
      CostCategorySplitChargeRule.proportional({
        source: sharedBusinessUnit,
        targets: businessUnit.rules,
      })
    );