hashicorp / terraform-provider-aws

The AWS Provider enables Terraform to manage AWS resources.
https://registry.terraform.io/providers/hashicorp/aws
Mozilla Public License 2.0
9.82k stars 9.17k forks source link

aws_budget_budgets not creating alerts after deleting them in the aws console #26547

Open jonasschoko opened 2 years ago

jonasschoko commented 2 years ago

Community Note

Description

When the budget alert that has been created with terraform will be deleted manually in the aws console, terraform won't create a new one with terraform refresh

Terraform CLI and Terraform AWS Provider Version

Terraform v1.2.8 on linux_amd64 +provider registry.terraform.io/hashicorp/aws v4.28.0

Affected Resource(s)

Terraform Configuration Files

CDK for Terraform

main.py:

from imports.aws import AwsProvider
from imports.aws.budgets import (
    BudgetsBudget,
    BudgetsBudgetCostTypes,
    BudgetsBudgetNotification,
)
from constructs import Construct
from cdktf import App, TerraformStack

mails = ["mail@address.com"]

accounts = [{'id': 'accountId', 'shortName': 'short', 'amount': 100, 'mails': mails}]

class MyStack(TerraformStack):
    def __init__(self, scope: Construct, ns: str):
        super().__init__(scope, ns)
        # define resources here
        AwsProvider(self, "Aws", region="eu-central-1")

        for account in accounts:
            print(account)
            BudgetsBudget(
                self,
                "forecasted_"+account["id"],
                name="forecasted_"+ account["shortName"] + "_" + account["id"],
                budget_type="COST",
                limit_amount=str(account["amount"]),
                limit_unit="USD",
                time_unit="MONTHLY",
                notification=[
                    BudgetsBudgetNotification(
                        comparison_operator="GREATER_THAN",
                        threshold=95,
                        threshold_type="PERCENTAGE",
                        notification_type="FORECASTED",
                        subscriber_email_addresses=account["mails"],
                    )
                ],
            )

app = App()
MyStack(app, "cdktftest")

app.synth()

Expected Behavior

Create budget alert after manual deletion of it in the aws console.

Actual Behavior

Terraform does not recognize any changes and does not recreate the deleted budget alert.

Steps to Reproduce

  1. cdktf synth
  2. terraform apply
  3. go to budgets in aws console and click the budget that was created by terraform
  4. press Alerts and delete it by hand
  5. terraform refresh

Important Factoids

No

mithra-mkrk commented 2 years ago

do a refresh and check the desired state and current state .

if not you can use ignore _changes and try.

jonasschoko commented 2 years ago

refresh sadly didn't solve the issue. As well as it won't show anything about desired state or the current state. It just says: _awsbudgets.budget.name: Refreshing state... [id=id.name]

I didn't try the ignore_changes because of my lack of knowledge. Is it possible to do this with cdktf as well because I am using this instead of terraform.

justinretzolk commented 2 years ago

Hey @jonasschoko 👋 Thank you for taking the time to raise this! So that we have all of the necessary information in order to look into this, can you update the issue description to include all of the information requested in the bug report template?

jonasschoko commented 2 years ago

Hey, I have edited the issue description. If there is any more needed please just let me know and I will try to add it. Thanks in advance :)

srgoni commented 1 year ago

This is still an issue with terraform-aws-provider 5.15.0.

Here's another way to reproduce the issue that doesn't need cdktf:

cat >main.tf <<EOF
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
    }
  }
}

provider "aws" {
  region = "eu-central-1"
}

resource "aws_budgets_budget" "test" {
  name         = "test-terraform-aws-provider-bug-26547"
  budget_type  = "COST"
  limit_amount = 99
  limit_unit   = "USD"
  time_unit    = "MONTHLY"
  notification {
    comparison_operator        = "GREATER_THAN"
    threshold                  = 50
    threshold_type             = "PERCENTAGE"
    notification_type          = "ACTUAL"
    subscriber_email_addresses = ["user@example.com"]
  }
}
EOF
terraform init
terraform apply
ACCOUNT=$(aws sts get-caller-identity | jq -r .Account)
aws budgets delete-notification --account-id ${ACCOUNT} --budget-name test-terraform-aws-provider-bug-26547 --notification NotificationType=ACTUAL,ComparisonOperator=GREATER_THAN,Threshold=50.0
# this should detect that the notification was deleted and try to create it again, but it doesn't detect any changes
terraform apply

Furthermore, if the notification is deleted and a change is made to the Terraform script, Terraform will then try to delete the existing (deleted!) notification before recreating it. This will lead to the following error:

│ Error: updating Budget (:test-terraform-aws-provider-bug-26547) notifications: deleting Budget (:test-terraform-aws-provider-bug-26547) notification: NotFoundException: Unable to delete notification: { notificationType: ACTUAL, comparisionOperator: GREATER_THAN, threshold: 50.0 } for budget: test-terraform-aws-provider-bug-26547 - it doesn't exist.

To fix this issue, the provider must send a budgets:DescribeNotificationsForBudget API call in addition to budgets:DescribeBudget and compare the output with all configured notifications in the state and/or the script.

Interestingly, there already seems to be some plumbing for this in the code, but it doesn't work correctly: https://github.com/hashicorp/terraform-provider-aws/blob/main/internal/service/budgets/budget.go#L557