Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(aws_govcloud): create a AWS Govcloud replica module of AWS #2803

Merged
merged 1 commit into from
Jan 30, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
320 changes: 320 additions & 0 deletions examples/modules/cloud-integrations/aws-govcloud/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,320 @@
data "aws_iam_policy_document" "newrelic_assume_policy" {
statement {
actions = ["sts:AssumeRole"]

principals {
type = "AWS"
// This is the unique identifier for New Relic account on AWS, there is no need to change this
identifiers = [var.new_relic_aws_govcloud_account_id]
}

condition {
test = "StringEquals"
variable = "sts:ExternalId"
values = [var.newrelic_account_id]
}
}
}

resource "aws_iam_role" "newrelic_aws_role" {
name = "NewRelicInfrastructure-Integrations-${var.name}"
description = "New Relic Cloud integration role"
assume_role_policy = data.aws_iam_policy_document.newrelic_assume_policy.json
}

resource "aws_iam_policy" "newrelic_aws_permissions" {
name = "NewRelicCloudStreamReadPermissions-${var.name}"
description = ""
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"budgets:ViewBudget",
"cloudtrail:LookupEvents",
"config:BatchGetResourceConfig",
"config:ListDiscoveredResources",
"ec2:DescribeInternetGateways",
"ec2:DescribeVpcs",
"ec2:DescribeNatGateways",
"ec2:DescribeVpcEndpoints",
"ec2:DescribeSubnets",
"ec2:DescribeNetworkAcls",
"ec2:DescribeVpcAttribute",
"ec2:DescribeRouteTables",
"ec2:DescribeSecurityGroups",
"ec2:DescribeVpcPeeringConnections",
"ec2:DescribeNetworkInterfaces",
"ec2:DescribeVpnConnections",
"health:DescribeAffectedEntities",
"health:DescribeEventDetails",
"health:DescribeEvents",
"tag:GetResources",
"xray:BatchGet*",
"xray:Get*"
],
"Effect": "Allow",
"Resource": "*"
}
]
}
EOF
}

resource "aws_iam_role_policy_attachment" "newrelic_aws_policy_attach" {
role = aws_iam_role.newrelic_aws_role.name
policy_arn = aws_iam_policy.newrelic_aws_permissions.arn
}

resource "newrelic_cloud_aws_govcloud_link_account" "newrelic_cloud_integration_push" {
account_id = var.newrelic_account_id
metric_collection_mode = "PUSH"
name = "${var.name} metric stream"
depends_on = [aws_iam_role_policy_attachment.newrelic_aws_policy_attach]
access_key_id = newrelic_api_access_key.newrelic_aws_access_key.key
secret_access_key = newrelic_api_access_key.newrelic_aws_access_key.key
aws_account_id = var.new_relic_aws_govcloud_account_id
}

resource "newrelic_api_access_key" "newrelic_aws_access_key" {
account_id = var.newrelic_account_id
key_type = "INGEST"
ingest_type = "LICENSE"
name = "Metric Stream Key for ${var.name}"
notes = "AWS Cloud Integrations Metric Stream Key"
}

resource "aws_iam_role" "firehose_newrelic_role" {
name = "firehose_newrelic_role_${var.name}"

assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "firehose.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}

resource "random_string" "s3-bucket-name" {
length = 8
special = false
upper = false
}

resource "aws_s3_bucket" "newrelic_aws_bucket" {
bucket = "newrelic-aws-bucket-${random_string.s3-bucket-name.id}"
force_destroy = true
}

resource "aws_s3_bucket_ownership_controls" "newrelic_ownership_controls" {
bucket = aws_s3_bucket.newrelic_aws_bucket.id
rule {
object_ownership = "BucketOwnerEnforced"
}
}

resource "aws_kinesis_firehose_delivery_stream" "newrelic_firehose_stream" {
name = "newrelic_firehose_stream_${var.name}"
destination = "http_endpoint"
http_endpoint_configuration {
url = "https://gov-aws-api.newrelic.com/cloudwatch-metrics/v1"
name = "New Relic ${var.name}"
access_key = newrelic_api_access_key.newrelic_aws_access_key.key
buffering_size = 1
buffering_interval = 60
role_arn = aws_iam_role.firehose_newrelic_role.arn
s3_backup_mode = "FailedDataOnly"
s3_configuration {
role_arn = aws_iam_role.firehose_newrelic_role.arn
bucket_arn = aws_s3_bucket.newrelic_aws_bucket.arn
buffering_size = 10
buffering_interval = 400
compression_format = "GZIP"
}
request_configuration {
content_encoding = "GZIP"
}
}
}

resource "aws_iam_role" "metric_stream_to_firehose" {
name = "newrelic_metric_stream_to_firehose_role_${var.name}"

assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "streams.metrics.cloudwatch.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}

resource "aws_iam_role_policy" "metric_stream_to_firehose" {
name = "default"
role = aws_iam_role.metric_stream_to_firehose.id

policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"firehose:PutRecord",
"firehose:PutRecordBatch"
],
"Resource": "${aws_kinesis_firehose_delivery_stream.newrelic_firehose_stream.arn}"
}
]
}
EOF
}

resource "aws_cloudwatch_metric_stream" "newrelic_metric_stream" {
name = "newrelic-metric-stream-${var.name}"
role_arn = aws_iam_role.metric_stream_to_firehose.arn
firehose_arn = aws_kinesis_firehose_delivery_stream.newrelic_firehose_stream.arn
output_format = "opentelemetry0.7"

dynamic "exclude_filter" {
for_each = var.exclude_metric_filters

content {
namespace = exclude_filter.key
metric_names = exclude_filter.value
}
}

dynamic "include_filter" {
for_each = var.include_metric_filters

content {
namespace = include_filter.key
metric_names = include_filter.value
}
}
}

resource "newrelic_cloud_aws_govcloud_link_account" "newrelic_cloud_integration_pull" {
account_id = var.newrelic_account_id
metric_collection_mode = "PULL"
name = "${var.name} pull"
depends_on = [aws_iam_role_policy_attachment.newrelic_aws_policy_attach]
access_key_id = newrelic_api_access_key.newrelic_aws_access_key.key
secret_access_key = newrelic_api_access_key.newrelic_aws_access_key.key
aws_account_id = var.new_relic_aws_govcloud_account_id
}

resource "newrelic_cloud_aws_govcloud_integrations" "newrelic_cloud_integration_pull" {
account_id = var.newrelic_account_id
linked_account_id = newrelic_cloud_aws_govcloud_link_account.newrelic_cloud_integration_pull.id
cloudtrail {}
s3 {}
sqs {}
ebs {}
alb {}
api_gateway {}
auto_scaling {}
aws_direct_connect {}
aws_states {}
dynamo_db {}
ec2 {}
elastic_search {}
elb {}
emr {}
iam {}
lambda {}
rds {}
red_shift {}
route53 {}
sns {}
}

resource "aws_s3_bucket" "newrelic_configuration_recorder_s3" {
bucket = "newrelic-configuration-recorder-${random_string.s3-bucket-name.id}"
force_destroy = true
}

resource "aws_iam_role" "newrelic_configuration_recorder" {
name = "newrelic_configuration_recorder-${var.name}"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "config.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}

resource "aws_iam_role_policy" "newrelic_configuration_recorder_s3" {
name = "newrelic-configuration-recorder-s3-${var.name}"
role = aws_iam_role.newrelic_configuration_recorder.id

policy = <<POLICY
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:*"
],
"Effect": "Allow",
"Resource": [
"${aws_s3_bucket.newrelic_configuration_recorder_s3.arn}",
"${aws_s3_bucket.newrelic_configuration_recorder_s3.arn}/*"
]
}
]
}
POLICY
}

resource "aws_iam_role_policy_attachment" "newrelic_configuration_recorder" {
role = aws_iam_role.newrelic_configuration_recorder.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AWS_ConfigRole"
}

resource "aws_config_configuration_recorder" "newrelic_recorder" {
name = "newrelic_configuration_recorder-${var.name}"
role_arn = aws_iam_role.newrelic_configuration_recorder.arn
}

resource "aws_config_configuration_recorder_status" "newrelic_recorder_status" {
name = aws_config_configuration_recorder.newrelic_recorder.name
is_enabled = true
depends_on = [aws_config_delivery_channel.newrelic_recorder_delivery]
}

resource "aws_config_delivery_channel" "newrelic_recorder_delivery" {
name = "newrelic_configuration_recorder-${var.name}"
s3_bucket_name = aws_s3_bucket.newrelic_configuration_recorder_s3.bucket
depends_on = [
aws_config_configuration_recorder.newrelic_recorder
]
}
10 changes: 10 additions & 0 deletions examples/modules/cloud-integrations/aws-govcloud/providers.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
}
newrelic = {
source = "newrelic/newrelic"
}
}
}
25 changes: 25 additions & 0 deletions examples/modules/cloud-integrations/aws-govcloud/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
variable "newrelic_account_id" {
type = string
}

variable "name" {
type = string
default = "production"
}

variable "exclude_metric_filters" {
description = "Map of exclusive metric filters. Use the namespace as the key and the list of metric names as the value."
type = map(list(string))
default = {}
}

variable "include_metric_filters" {
description = "Map of inclusive metric filters. Use the namespace as the key and the list of metric names as the value."
type = map(list(string))
default = {}
}

variable "new_relic_aws_govcloud_account_id" {
type = string
default = "266471868085"
}
3 changes: 1 addition & 2 deletions examples/modules/cloud-integrations/aws/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ data "aws_iam_policy_document" "newrelic_assume_policy" {
principals {
type = "AWS"
// This is the unique identifier for New Relic account on AWS, there is no need to change this
identifiers = var.newrelic_account_region == "US_GOV" ? [266471868085] : [754728514883]
identifiers = [754728514883]
}

condition {
Expand Down Expand Up @@ -125,7 +125,6 @@ locals {
newrelic_urls = {
US = "https://aws-api.newrelic.com/cloudwatch-metrics/v1"
EU = "https://aws-api.eu01.nr-data.net/cloudwatch-metrics/v1"
US_GOV = "https://gov-aws-api.newrelic.com/cloudwatch-metrics/v1"
}
}

Expand Down
2 changes: 1 addition & 1 deletion examples/modules/cloud-integrations/aws/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ variable "newrelic_account_region" {
default = "US"

validation {
condition = contains(["US", "EU", "US_GOV"], var.newrelic_account_region)
condition = contains(["US", "EU"], var.newrelic_account_region)
error_message = "Valid values for region are 'US' or 'EU'."
}
}
Expand Down
Loading