Skip to content

Instantly share code, notes, and snippets.

@alexjeen
Created June 27, 2023 16:10
Show Gist options
  • Save alexjeen/799c90704ef955f1906d1ada6a69699d to your computer and use it in GitHub Desktop.
Save alexjeen/799c90704ef955f1906d1ada6a69699d to your computer and use it in GitHub Desktop.
Using the EventBridge modules multiple times
variable "env_level" {
description = "Environment level"
default = "dev"
}
module "eventbridge_price" {
source = "terraform-aws-modules/eventbridge/aws"
create_bus = false
create_connections = true
create_api_destinations = true
attach_api_destination_policy = true
rules = {
"test_room_price_${var.env_level}" = {
description = "Trigger test room price cron"
schedule_expression = "cron(20 4 * * ? *)"
enabled = true
event_pattern = null
}
}
targets = {
"test_room_price_${var.env_level}" = [
{
name = "send-request-to-test-room-price-${var.env_level}"
destination = "test_room_price_${var.env_level}"
attach_role_arn = true
}
]
}
connections = {
"test_room_price_${var.env_level}" = {
authorization_type = "API_KEY"
auth_parameters = {
api_key = {
key = "Authorization"
value = "Bearer testtoken"
}
}
}
}
api_destinations = {
"test_room_price_${var.env_level}" = {
description = "my test room price endpoint"
invocation_endpoint = "https://example.com/generate_cts/*"
http_method = "POST"
invocation_rate_limit_per_second = 10
}
}
}
module "eventbridge_details" {
source = "terraform-aws-modules/eventbridge/aws"
create_bus = false
create_connections = true
create_api_destinations = true
attach_api_destination_policy = true
rules = {
"test_room_details_${var.env_level}" = {
description = "Trigger test room details cron"
schedule_expression = "cron(50 3 * * ? *)"
enabled = true
event_pattern = null
}
}
targets = {
"test_room_details_${var.env_level}" = [
{
name = "send-request-to-test-room-details-${var.env_level}"
destination = "test_room_details_${var.env_level}"
attach_role_arn = true
}
]
}
connections = {
"test_room_details_${var.env_level}" = {
authorization_type = "API_KEY"
auth_parameters = {
api_key = {
key = "Authorization"
value = "Bearer testtoken"
}
}
}
}
api_destinations = {
"test_room_details_${var.env_level}" = {
description = "XXX"
invocation_endpoint = "http://example.com/generate_cts/*"
http_method = "POST"
invocation_rate_limit_per_second = 10
}
}
}
@sany2k8
Copy link

sany2k8 commented Jun 28, 2023

This is currently what I have after splitting the changes on env.tfvars, variables.tf and eventbridge.tf, I am still using module from the git repo. What I have uncertain right now

  1. How to consolidate the connection into one instead of using two?
  2. Is my current approach OK, because I didn't apply it yet? just used terraform validate and terraform plan
  3. Will my approach be scalable if I add new property_id and cron_time in the future on the test_info variable?

env.tfvars

test_info = [
  {
    property_id        = "9a9c422",
    cron_time          = "cron(50 4 * * ? *)"
  },
  {
    property_id        = "746f704",
    cron_time          = "cron(40 4 * * ? *)"
  }
]

price_invocation_url = "https://example.com/generate_cts/*"
details_invocation_url = "https://example.com/generate_csts/*"
test = "test_key"

variables.tf

variable "test_info" {
  type = list(object({
    property_id = string
    cron_time = string
  }))
}

variable "price_invocation_url" {
  type = string
}

variable "details_invocation_url" {
  type = string
}

variable "test" {
  type = string
}

eventbridge.tf

locals {
  rule_info = {
    for index, info in var.test_info : 
    "test_room_price_${index}_${var.env_level}" => {
      description           = "Trigger test room price cron"
      schedule_expression   = info.cron_time
      enabled               = true
    }
  }

  target_info = {
    for index, info in var.test_info : 
    "test_room_price_${index}_${var.env_level}" => [
      {
        name              = "send-request-to-test-room-price-${index}-${var.env_level}"
        destination       = "test_room_price_${var.env_level}"
        attach_role_arn   = true
        input_path        = info.property_id
      }
    ]
  }
}

module "eventbridge" {
  source = "./modules/eventbridge"

  create_bus              = false
  create_connections      = true
  create_api_destinations = true

  attach_api_destination_policy = true

  rules = merge({
      "test_room_details_${var.env_level}" = {
        description           = "Trigger test room details cron"
        schedule_expression   = "cron(50 3 * * ? *)"
        enabled               = true
      }
    }, local.rule_info)

    targets = merge({
      "test_room_details_${var.env_level}" = [
        {
          name              = "send-request-to-test-room-details-${var.env_level}"
          destination       = "test_room_details_${var.env_level}"
          attach_role_arn   = true
          input_path        = "all"
        }
      ]
    }, local.target_info)

  connections = {
    "test_room_price_${var.env_level}" = {
      authorization_type = "API_KEY"
      auth_parameters = {
        api_key = {
          key   = "Authorization"
          value = "Bearer ${var.test}"
        }
      }
    }
    "test_room_details_${var.env_level}" = {
      authorization_type = "API_KEY"
      auth_parameters = {
        api_key = {
          key   = "Authorization"
          value = "Bearer ${var.test}"
        }
      }
    }
  }

  api_destinations = {
    "test_room_price_${var.env_level}" = {
      description                      = "my test room price endpoint"
      invocation_endpoint              = var.price_invocation_url
      http_method                      = "POST"
      invocation_rate_limit_per_second = 10
    }
    "test_room_details_${var.env_level}" = {
      description                      = "my test room details endpoint"
      invocation_endpoint              = var.details_invocation_url
      http_method                      = "POST"
      invocation_rate_limit_per_second = 10
    }
  }
}

resource "random_pet" "this" {
  length = 2
}

resource "aws_iam_role" "eventbridge" {
  name               = "${random_pet.this.id}-role"
  assume_role_policy = data.aws_iam_policy_document.assume_role.json
}

data "aws_iam_policy_document" "assume_role" {
  statement {
    effect  = "Allow"
    actions = ["sts:AssumeRole"]

    principals {
      type        = "Service"
      identifiers = ["events.amazonaws.com"]
    }
  }
}

@alexjeen
Copy link
Author

You shouldnt really use the module from the GIT repo like that. It will cause issues later on (with your statefile) its best to use it like I mentioned:

module "eventbridge_details" {
    source = "terraform-aws-modules/eventbridge/aws"

You can use a variable for the connection, like this, you can then just re-use it for the connections part so you can manage it in a central place (because how this module works, it maps by name, it needs to be there for the connection):

variable "env_level" {
  description = "Environment level"
  default     = "dev"
}

locals {
  connection = {
	authorization_type = "API_KEY"
	auth_parameters = {
	  api_key = {
		key   = "Authorization"
		value = "Bearer testtoken"
	  }
	}
  }
}

module "eventbridge" {
  source = "terraform-aws-modules/eventbridge/aws"

  create_bus              = false
  create_connections      = true
  create_api_destinations = true

  attach_api_destination_policy = true

  rules = {
	// you have two rules here, you can see the rules point at the targets below
	"test_room_price_${var.env_level}" = {
	  description         = "Trigger test room price cron"
	  schedule_expression = "cron(20 4 * * ? *)"
	  enabled             = true
	  event_pattern       = null
	}
	"test_room_details_${var.env_level}" = {
	  description         = "Trigger test room details cron"
	  schedule_expression = "cron(50 3 * * ? *)"
	  enabled             = true
	  event_pattern       = null
	}
  }

  targets = {
	// you have two targets here, you can see the targets point at the api_destinations below
	"test_room_price_${var.env_level}" = [
	  {
		name            = "send-request-to-test-room-price-${var.env_level}"
		destination     = "test_room_price_${var.env_level}"
		attach_role_arn = true
	  }
	]
	"test_room_details_${var.env_level}" = [
	  {
		name            = "send-request-to-test-room-details-${var.env_level}"
		destination     = "test_room_details_${var.env_level}"
		attach_role_arn = true
	  }
	]
  }

  connections = {
	"test_room_price_${var.env_level}"   = local.connection
	"test_room_details_${var.env_level}" = local.connection
  }

  api_destinations = {
	// you need two destinations here, so we add two destinations
	"test_room_price_${var.env_level}" = {
	  description                      = "my test room price endpoint"
	  invocation_endpoint              = "https://example.com/generate_cts/*"
	  http_method                      = "POST"
	  invocation_rate_limit_per_second = 10
	},
	"test_room_details_${var.env_level}" = {
	  description                      = "XXX"
	  invocation_endpoint              = "https://example.com/generate_cts/*"
	  http_method                      = "POST"
	  invocation_rate_limit_per_second = 10
	}
  }
}

The solution should be scalable.

@sany2k8
Copy link

sany2k8 commented Jul 1, 2023

I really appreciate your effort, sir. Thanks a lot 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment