Pub Sub Lite topics with Peak Capacity Throughput option - google-cloud-platform

We are using Pub Sub lite instances along with reservations, we want to deploy it via Terraform, on UI while creating a Pub Sub Lite we get an option to specify Peak Publish Throughput (MiB/s) and Peak Subscribe Throughput (MiB/s) which is not available in the resource "google_pubsub_lite_topic" as per this doc https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/pubsub_lite_topic.
resource "google_pubsub_lite_reservation" "pubsub_lite_reservation" {
name = var.lite_reservation_name
project = var.project
region = var.region
throughput_capacity = var.throughput_capacity
}
resource "google_pubsub_lite_topic" "pubsub_lite_topic" {
name = var.topic_name
project = var.project
region = var.region
zone = var.zone
partition_config {
count = var.partitions_count
capacity {
publish_mib_per_sec = var.publish_mib_per_sec
subscribe_mib_per_sec = var.subscribe_mib_per_sec
}
}
retention_config {
per_partition_bytes = var.per_partition_bytes
period = var.period
}
reservation_config {
throughput_reservation = google_pubsub_lite_reservation.pubsub_lite_reservation.name
}
}
Currently use the above TF script to create pub sub lite instance, the problem here is we are mentioning the throughput capacity instead of setting the peak throughput capacity, and capacity block is a required field. Please help if there is any workaround to it ? we want topic to set throughput dynamically but with peak limit to the throughput, as we are setting a fix value to the lite reservation.

If you check the bottom of your Google Cloud console screenshot, you can see it suggests to have 4 partitions with 4MiB/s publish and subscribe throughput.
Therefore your Terraform partition_config should match this. Count should be 4 for the 4 partitions, with capacity of 4MiB/s publish and 4MiB/s subscribe for each partition.
The "peak throughput" in web UI is just for convenience to help you choose some numbers here. The actual underlying PubSub Lite API doesn't actually have this field, which is why there is no Terraform setting either. You will notice the sample docs require a per-partiton setting just like Terraform.
eg. https://cloud.google.com/pubsub/lite/docs/samples/pubsublite-create-topic
I think the only other alternative would be to create a reservation attached to your topic with enough throughput units for desired capacity. And then completely omit capacity block in Terraform and let the reservation decide.

Related

How do I configure a logs-based metric to sum some values from log messages?

I'm having trouble wrapping my head around GCP Logs Based Metrics. I have the following messages being logged from a cloud function:
insertId: qwerty
jsonPayload:
accountId: 60da91d2-7391-4979-ba3b-4bfb31fa7777
message: Replay beginning. Event tally=1
metric: stashed-events-tally
tally: 5
labels:
execution_id: n2iwj3335agb
What I'd like to do is sum up the values in the tally field. I've looked into logs based metrics and most of the examples I've seen seem to concern themselves with COUNTing the number of log messages that match the given filter. What I need to do is SUM the tally value.
Here's what I have so far (I'm using terraform to deploy the logs based metric):
resource "google_logging_metric" "my_metric" {
name = "mymetric"
filter = "resource.type=cloud_function AND resource.labels.function_name=${google_cloudfunctions_function.function.name} AND jsonPayload.metric=stashed-events-tally"
metric_descriptor {
metric_kind = "DELTA"
value_type = "DISTRIBUTION"
display_name = "mymetric"
}
value_extractor = "EXTRACT(jsonPayload.tally)"
bucket_options {
linear_buckets {
num_finite_buckets = 10
width = 1
}
}
}
Do I have to do something specific to SUM those values up, or is that defined wherever the metric is consumed (e.g. on a monitoring dashboard)?
As I say, I'm having trouble wrapping my head around this.
When you instrument your code, you have 2 steps:
Get the metrics
Visualize/create alert on metrics
The Log-based metric simply converts a log in a metric.
Then, if you want to perform a sum (over a time window of course), you have to ask your dashboarding system to perform that operation, with Cloud Monitoring for instance

unable to create google compute disk using terraform

i want to create a gcloud compute disk so in order to achieve i wrote below code
resource "google_compute_disk" "default2" {
name = "test-disk"
type = "pd-balanced"
zone = "us-central1-a"
image = "centos-7-v20210609"
physical_block_size_bytes = 20480
}
when i run terraform apply it show following error
how can i fix this
As described in the documentation
physical_block_size_bytes - (Optional) Physical block size of the persistent disk, in bytes. If not present in a request, a default value is used. Currently supported sizes are 4096 and 16384, other sizes may be added in the future. If an unsupported value is requested, the error message will list the supported values for the caller's project.

How to not override AWS desired_count with Terraform?

I'm managing an autoscaling cloud infrastructure in AWS.
Every time I run Terraform it wants to override the desired_count, i.e. the number of running instances.
I would like this to not happen. How do I do that?
Constraints: I manage multiple different microservices, each of which set up their running instances with a shared module, where desired_count is specified. I don't want to change the shared module such that desired_count is ignored for all my microservices. Rather, I want to be able to override or not on a service-by-service (i.e caller-by-caller) basis.
This rules out a straightforward use of lifecycle { ignore_changes = ... }. As far as I can tell, the list of changes to ignore cannot be given as arguments (my Terraform complains when I try; feel free to tell me how you succeed at this).
My next idea (if possible) is to read the value from the stored state, if present, and ask for a desired_count equal to its current value, or my chosen initial value if it has no current value. If there are no concurrent Terraform runs (i.e. no races), this should accomplish the same thing. Is this possible?
I'm no expert terraformer. I would appreciate it a lot if you give very detailed answers.
The lifecycle parameters affect how the graph is built, so they can't be parameterized. The terraform team hasn't ruled out that this could be implemented, but they haven't done it with the issue reported over a couple years.
What you could do is create two aws_ecs_service resources, and switch between them:
resource "aws_ecs_service" "service" {
count = var.use_lifecycle ? 0 : 1
...
}
resource "aws_ecs_service" "service_with_lifecycle" {
count = var.use_lifecycle ? 1 : 0
...
lifecycle {
ignore_changes = ["desired_count"]
}
}
Given that, you need a way to reference the service you created. You can do that with a local:
locals {
service = var.use_lifecycle ? aws_ecs_service.service_with_lifecycle[0] : aws_ecs_service.service[0]
}

Google alert policy triggers issues based on cloud storage bucket object count

I have been trying to setup alert policies(thru stack-driver) to get email notifications whenever there is new object in the cloud storage bucket.
But the issue here is, it works sometimes after a while and most of the other times, it wont.
How do we make the alerts triggered immediately as in when there is a new file in the bucket(multiple times per day).
Below is the code:
resource "google_monitoring_alert_policy" "alert_policy" {
display_name = "File notification"
combiner = "OR"
notification_channels = ["${google_monitoring_notification_channel.email.name}"]
conditions {
display_name = "File Notification"
condition_threshold {
comparison = "COMPARISON_LT"
duration = "60s"
filter = "metric.type=\"storage.googleapis.com/storage/object_count\" resource.type=\"gcs_bucket\" resource.label.\"bucket_name\"=\"realbucketname\""
threshold_value = 1
aggregations {
alignment_period = "60s"
per_series_aligner = "ALIGN_COUNT"
}
trigger {
count = 1
}
}
}
documentation {
content = "There is a new file"
}
}
Appreciate your inputs!
Thank you
The object count metric is measured once per day, so it is possible that the condition will only trigger once per day. This is most likely why your alerts are not consistent.
If possible the recommend solution to view changes to objects in your bucket is through pub/sub notifications.
Using pub/sub notifications you can get notified when many different events occur inside your bucket.
Here is an example of the gsutil command you would use to be notified when an object is created in your bucket. The -e specifies that I only want the notification to occur when a specific event takes place, in this case it is when a file is uploaded to the bucket.
gsutil notification create -t [TOPIC_NAME] -f json gs://[BUCKET_NAME] -e OBJECT_FINALIZE
You would then create a subscriber to receive the notification.
Here is a tutorial on managing notifications on buckets via App Engine.
You can also look into using cloud functions that make use of stand-alone functions in response to events (adding files to bucket). To send emails via functions you can make use of third party services such as Mailgun. You can also follow this third-party tutorial on using SMTP and nodemailer to send emails.
Thank you. I had it fixed by removing aggregations in my scripts,
It worked as expected now !!!
condition_threshold {
comparison = "COMPARISON_GT"
duration = "60s"
filter = "metric.type=\"storage.googleapis.com/storage/object_count\" resource.type=\"gcs_bucket\" resource.label.\"bucket_name\"=\"realbucketname\""
threshold_value = 1

Terraform looping a module

I have a module with in my terraform file that created some Database servers that does a few things.
First, it creates an auto scaling group to use a specific image, then it creates some EBS volumes and attaches them and then adds some lambda code so on launch the instances get registered to route 53. So in all about 80 lines of text.
Extract
module "systemt-sql-db01" {
source = "localmodules/tf-aws-asg"
name = "${var.envname}-sys-db01"
envname = "${var.envname}"
service = "dbpx"
ami_id = "${data.aws_ami.app_sqlproxy.id}"
user_data = "${data.template_cloudinit_config.config-enforcement-sqlproxy.rendered}"
#subnets = ["${module.subnets-enforcement.web_private_subnets}"]
subnets = ["${element(module.subnets-enforcement.web_private_subnets, 1)}"]
security_groups = ["${aws_security_group.unfiltered-egress-sg.id}", "${aws_security_group.sysopssg.id}", "${aws_security_group.system-sqlproxy.id}"]
key_name = "${var.keypair}"
load_balancers = ["${var.envname}-enf-dbpx-int-elb"]
iam_instance_profile = "${module.iam_profile_generic.profile_arn}"
instance_type = "${var.enforcement_instancesize_dbpx}"
min = 0
max = 0
}
And I then have two parameter files one that I call when launching to pre production and one called when launching to production. I don't want these to contain anything other than variables.
The problem is that for production I need to call the module twice, but for production I need it called three times.
People talk about a count function for modules but I don't think this is possible as yet. Can anyone suggest any other ways to do this? What I would like is to be able in my parameter file to set a list variable of all the DB ASG names, and then loop through this calling the module each time.
I hope that makes sense?
thank you
EDIT Looping in modules is in beta for Terraform 0.13 (https://discuss.hashicorp.com/t/terraform-0-13-beta-released/9555).
This is a highly requested feature in Terraform and as mentioned it is not yet supported. Later releases of Terraform v0.12 will introduce this feature (https://www.hashicorp.com/blog/hashicorp-terraform-0-12-preview-for-and-for-each).
I had a similar problem where I had to create multiple KMS keys for multiple accounts from a base KMS module. I ended up creating a second module that uses the core KMS module, this second module had many instances of the core module, but only required me to input the account details once.
This is still not ideal, but it worked well enough without over complicating things.