How to use same tag multiple time on aws inspector resource group - amazon-web-services

I want to create a resource group in AWS inspector with terraform, that has few tags with key "Name" and different values. I can do this with AWS GUI, but I Want to do it in terraform also. If I do it like in the example below, it will just override the name..
resource "aws_inspector_resource_group" "bar" {
tags = {
Name = "Master"
Name = "UF"
}
}

Could you please try the following:
resource "aws_inspector_resource_group" "bar" {
tags = {
Name = ["Master", "UF"]
}
}
If that doesn't work you could just use the aws_ec2_tag resource:
https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ec2_tag
Should do the job

Related

Tags in Datadog for autoscaling_group when using metrics have changed? (Now aws_autoscaling_groupname)

We have monitors and dashboards templated in Terraform that are used when creating new accounts and have found that ones using queries by "autoscaling_group" now report no data.
Looking in metrics I can see the only option for grouping by ASG is "aws_autoscaling_groupname" but can't seem to find where this is set. AWS Auto Scaling integration documentation also shows that this should be autoscaling_group.
Where can I set this?
If you're generating the Autoscaling group via the Terraform aws_autoscaling_group resource, then there's a name parameter that is distinct from the resource name.
An example that shows the difference:
resource "aws_placement_group" "prod-asg" {
name = "application123"
strategy = "cluster"
}
In this example, when generating dashboards, the ASG name you want to add to widgets would be application123, which should end up as the autoscaling_group name in Datadog.
If using Terraform to build the dashboard widgets, then the reference would be something like this:
resource "datadog_dashboard" "monitoring" {
title = "..."
widget {
type = "timeseries"
title = "..."
request {
q = "avg:aws.autoscaling.desired_capacity{name:${aws_autoscaling_group.prod-asg.name}}.as_count()"
}
}
}
Refs: https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/autoscaling_group

Is it possible to insert a value into a file before it gets used in a terraform resource?

I'm deploying an Amazon Connect instance with an attached contact flow, following this documentation: https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/connect_contact_flow
My contact flow is stored in a file, so I'm using the following:
resource "aws_connect_contact_flow" "general" {
instance_id = aws_connect_instance.dev.id
name = "General"
description = "General Flow routing customers to queues"
filename = "flows/contact_flow.json"
content_hash = filebase64sha256("flows/contact_flow.json")
}
However my contact flow requires me to specify the ARN of an AWS Lambda function in one particular section:
...
"parameters":[
{
"name":"FunctionArn",
"value":"<lambda function arn>",
"namespace":null
},
{
"name":"TimeLimit",
"value":"3"
}
],
</snip>
...
the value I would like to substitute into the json file at <lambda function arn> before the contact flow is created is accessible at
data.terraform_remote_state.remote.outputs.lambda_arn
Is there any way to achieve this? Or will I have to use the 'content = ' method in the documentation linked above to achieve what I need?
Thanks.
If you really want to use filename instead of content, you have to write the rendered template to some temporary file using local_file.
But using content with templatefile directly for that would probably be easier. For that you would have to convert your flows/contact_flow.json into a template format:
"parameters":[
{
"name":"FunctionArn",
"value":"$arn",
"namespace":null
},
{
"name":"TimeLimit",
"value":"3"
}
],
then, for example:
locals {
contact_flow = templatefile("flows/contact_flow.json", {
arn = data.terraform_remote_state.remote.outputs.lambda_arn
})
}
resource "aws_connect_contact_flow" "general" {
instance_id = aws_connect_instance.dev.id
name = "General"
description = "General Flow routing customers to queues"
content = local.contact_flow
}

When using terraform to create aws_ses_domain_identity, how do you add tags?

I have the terraform
resource "aws_ses_domain_identity" "example_co_uk" {
domain = "example.co.uk"
}
Which I can use to create a verified identity in SES. The AWS Console has a tab for adding tags manually but if I add the tags argument, as documented here Tagging:
resource "aws_ses_domain_identity" "example_co_uk" {
domain = "example.co.uk"
tags = {
Squad = "Foobar"
}
}
When running the verification or plan fails with the error:
An argument named "tags" is not expected here
The docs for aws_ses_domain_identity do not mention tags and so I was wondering how I specify them using terraform.

How to associate new "aws_wafregional_rule" with existing WAF ACL

I have created a WAF ACL using AWS Console. Now I need to create WAF Rule using Terraform, so I have implemented below rule.
resource "aws_wafregional_byte_match_set" "blocked_path_match_set" {
name = format("%s-%s-blocked-path", local.name, var.module)
dynamic "byte_match_tuples" {
for_each = length(var.blocked_path_prefixes) > 0 ? var.blocked_path_prefixes : []
content {
field_to_match {
type = lookup(byte_match_tuples.value, "type", null)
}
target_string = lookup(byte_match_tuples.value, "target_string", null)
positional_constraint = lookup(byte_match_tuples.value, "positional_constraint", null)
text_transformation = lookup(byte_match_tuples.value, "text_transformation", null)
}
}
}
resource "aws_wafregional_rule" "blocked_path_allowed_ipaccess" {
metric_name = format("%s%s%sBlockedPathIpaccess", var.application, var.environment, var.module)
name = format("%s%s%sBlockedPathIpaccessRule", var.application, var.environment, var.module)
predicate {
type = "ByteMatch"
data_id = aws_wafregional_byte_match_set.blocked_path_match_set.id
negated = false
}
}
But how do I map this new rule to existing "web_acl" which was created through AWS Console. As per documentation I can use "aws_wafregional_web_acl" to create new web_acl, but is there a way to associate rule created through terraform with existing waf_acl ? I have a gitlab pipeline which deploys terraform code to aws, so eventually I will pass id/arn of existing web_acl and through pipeline just add/update new rule without impacting existing rules which were created through console.
Please share your valuable feedback.
Thank you.
As per the WAF documentation you associate the rule via an AWS WAF resource, see the example below for a code snippet.
resource "aws_wafregional_web_acl" "foo" {
name = "foo"
metric_name = "foo"
default_action {
type = "ALLOW"
}
rule {
action {
type = "BLOCK"
}
priority = 1
rule_id = aws_wafregional_rule.blocked_path_allowed_ipaccess.id
}
}
However, as you said you have created the resource already in the AWS console. Terraform does support the import of an AWS resource, so you would need to go with this method if you would like to manage it via Terraform.

Define tags in central section in TerraForm

I'm playing around with Terraform for a bit and I was wondering if this is possible. It's best practice to assign tags to each resource you create on AWS (for example). So, what you do first is come up with a tagging strategy (for example, which business unit, a name of the app, a team responsible for it, ...).
However, in Terraform, this means that you have to repeat each tags-block for each resource. This isn't very convenient and if you want to update 1 of the tag names, you have to update each resource that you created.
For example:
resource "aws_vpc" "vpc" {
cidr_block = "${var.cidr}"
tags {
Name = "${var.name}"
Project = "${var.projectname}"
Environment = "${var.environment}"
}
}
If I want to create a Subnet and EC2 in that VPC with the same tags, I have to repeat that tags-block. If I want to update 1 of the tag names later on, I have to update each resource individually, which is very time consuming and tedious.
Is there a possibility to create a block of tags in a centralized location and refer to that? I was thinking of Modules, but that doesn't seem to fit the definition of a module.
You can also try local values from version 0.10.3. It allows you to assign a symbolic local name to an expression so it can be used multiple times in configuration without repetition.
# Define the common tags for all resources
locals {
common_tags = {
Component = "awesome-app"
Environment = "production"
}
}
# Create a resource that blends the common tags with instance-specific tags.
resource "aws_instance" "server" {
ami = "ami-123456"
instance_type = "t2.micro"
tags = "${merge(
local.common_tags,
map(
"Name", "awesome-app-server",
"Role", "server"
)
)}"
}
Terraform version .12 onwords,
This is the variable
variable "sns_topic_name" {
type = string
default = "VpnTopic"
description = "Name of the sns topic"
}
This is the code
locals {
common_tags = {
Terraform = true
}
}
# Create a Resource
resource "aws_sns_topic" "sns_topic" {
name = var.sns_topic_name
tags = merge(
local.common_tags,
{
"Name" = var.sns_topic_name
}
)
}
Output will be
+ tags = {
+ "Name" = "VpnTopic"
+ "Terraform" = "true"
}
Terraform now natively support it for AWS provider.
Check out here
As of version 3.38.0 of the Terraform AWS Provider, the Terraform Configuration language also enables provider-level tagging. Reference Link
# Terraform 0.12 and later syntax
provider "aws" {
# ... other configuration ...
default_tags {
tags = {
Environment = "Production"
Owner = "Ops"
}
}
}
resource "aws_vpc" "example" {
# ... other configuration ...
# This configuration by default will internally combine tags defined
# within the provider configuration block and those defined here
tags = {
Name = "MyVPC"
}
}
For "aws_vpc.example" resouce below tags will be assigned, which is combination of tags defined under provider and tags defined under aws_vps section:
+ tags = {
+ "Environment" = "Production"
+ "Owner" = "Ops"
+ "Name" = "MyVPC"
}