From 8d69824cb81379160710011add556317cdeea38c Mon Sep 17 00:00:00 2001 From: Pranav Nandula <127438038+pranav-new-relic@users.noreply.github.com> Date: Thu, 6 Feb 2025 10:14:03 +0530 Subject: [PATCH] feat(aws_govcloud): revamp of the resource to support ARN based authentication (#2809) feat(aws_govcloud): revamp of the resource to support ARN based authentication (#2809) --- ...ewrelic_cloud_aws_govcloud_link_account.go | 50 ++++++++---- ...ewrelic_cloud_aws_govcloud_link_account.go | 77 ++++++++++++------- ...ud_aws_govcloud_link_account.html.markdown | 26 +++---- 3 files changed, 93 insertions(+), 60 deletions(-) diff --git a/newrelic/resource_newrelic_cloud_aws_govcloud_link_account.go b/newrelic/resource_newrelic_cloud_aws_govcloud_link_account.go index 6639ecaae..8f61e1a79 100755 --- a/newrelic/resource_newrelic_cloud_aws_govcloud_link_account.go +++ b/newrelic/resource_newrelic_cloud_aws_govcloud_link_account.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/newrelic/newrelic-client-go/v2/pkg/cloud" ) @@ -25,6 +26,9 @@ func resourceNewRelicAwsGovCloudLinkAccount() *schema.Resource { Optional: true, Computed: true, Description: "The ID of the account in New Relic.", + // since the mutation to update cloud linked accounts does not support "changing" the account ID of a linked account, + // we shall force re-creation of the resource if the account_id is changed after the first apply. + ForceNew: true, }, "name": { Type: schema.TypeString, @@ -32,30 +36,42 @@ func resourceNewRelicAwsGovCloudLinkAccount() *schema.Resource { Required: true, }, "metric_collection_mode": { - Type: schema.TypeString, - Description: "The mode by which metric data is to be collected from the linked AWS GovCloud account. Use 'PUSH' for Metric Streams and 'PULL' for API Polling based metric collection respectively.", - Optional: true, + Type: schema.TypeString, + Description: "The mode by which metric data is to be collected from the linked AWS GovCloud account. Use 'PUSH' for Metric Streams and 'PULL' for API Polling based metric collection respectively.", + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"PULL", "PUSH"}, false), + Default: "PULL", // since the mutation to update cloud linked accounts does not support updating metric collection mode, // we shall force re-creation of the resource if the metric_collection_mode is changed after the first apply. ForceNew: true, }, - "aws_account_id": { - Type: schema.TypeString, - Description: "The ID of the AWS GovCloud account.", - Required: true, - }, - "access_key_id": { + "arn": { Type: schema.TypeString, - Description: "The Access Key used to programmatically access the AWS GovCloud account.", + Description: "The ARN of the identifying AWS GovCloud account.", Required: true, - Sensitive: true, - }, - "secret_access_key": { - Type: schema.TypeString, - Description: "The Secret Access Key used to programmatically access the AWS GovCloud account.", - Required: true, - Sensitive: true, }, + + // NOTE: The following arguments are no longer supported, as the establishment of a connection + // with New Relic from AWS GovCloud is no longer supported with these credentials (an ARN is needed + // to facilitate a working connection. + + //"aws_account_id": { + // Type: schema.TypeString, + // Description: "The ID of the AWS GovCloud account.", + // Required: true, + //}, + //"access_key_id": { + // Type: schema.TypeString, + // Description: "The Access Key used to programmatically access the AWS GovCloud account.", + // Required: true, + // Sensitive: true, + //}, + //"secret_access_key": { + // Type: schema.TypeString, + // Description: "The Secret Access Key used to programmatically access the AWS GovCloud account.", + // Required: true, + // Sensitive: true, + //}, }, } } diff --git a/newrelic/structures_newrelic_cloud_aws_govcloud_link_account.go b/newrelic/structures_newrelic_cloud_aws_govcloud_link_account.go index 7d0a3e6e8..88fa6e369 100755 --- a/newrelic/structures_newrelic_cloud_aws_govcloud_link_account.go +++ b/newrelic/structures_newrelic_cloud_aws_govcloud_link_account.go @@ -10,61 +10,84 @@ import ( ) func expandAwsGovCloudLinkAccountInputForCreate(d *schema.ResourceData) cloud.CloudLinkCloudAccountsInput { - awsGovCloud := cloud.CloudAwsGovCloudLinkAccountInput{} - if accessKeyID, ok := d.GetOk("access_key_id"); ok { - awsGovCloud.AccessKeyId = accessKeyID.(string) - } - if awsAccountID, ok := d.GetOk("aws_account_id"); ok { - awsGovCloud.AwsAccountId = awsAccountID.(string) + // NOTE: The AwsGovCloudLinkAccountInput datatype is no longer supported to facilitate linking an AWS GovCloud + // account to New Relic; AwsLinkAccountInput is intended to be used instead, since a link for AWS/AWS GovCloud + // both can now be facilitated via the "aws" field in the CloudLinkCloudAccountsInput datatype, with the same + // authentication mechanism, i.e. an ARN. + + awsGovCloud := cloud.CloudAwsLinkAccountInput{} + + // NOTE: The following arguments are no longer supported, as the establishment of a connection + // with New Relic from AWS GovCloud is no longer supported with these credentials (an ARN is needed + // to facilitate a working connection. + + //if accessKeyID, ok := d.GetOk("access_key_id"); ok { + // awsGovCloud.AccessKeyId = accessKeyID.(string) + //} + //if awsAccountID, ok := d.GetOk("aws_account_id"); ok { + // awsGovCloud.AwsAccountId = awsAccountID.(string) + //} + //if secretKeyID, ok := d.GetOk("secret_access_key"); ok { + // awsGovCloud.SecretAccessKey = cloud.SecureValue(secretKeyID.(string)) + //} + + if name, ok := d.GetOk("name"); ok { + awsGovCloud.Name = name.(string) } if m, ok := d.GetOk("metric_collection_mode"); ok { awsGovCloud.MetricCollectionMode = cloud.CloudMetricCollectionMode(strings.ToUpper(m.(string))) } - if name, ok := d.GetOk("name"); ok { - awsGovCloud.Name = name.(string) - } - if secretKeyID, ok := d.GetOk("secret_access_key"); ok { - awsGovCloud.SecretAccessKey = cloud.SecureValue(secretKeyID.(string)) + if arn, ok := d.GetOk("arn"); ok { + awsGovCloud.Arn = arn.(string) } createAwsGovCloudLinkAccountInput := cloud.CloudLinkCloudAccountsInput{ - AwsGovcloud: []cloud.CloudAwsGovCloudLinkAccountInput{awsGovCloud}, + Aws: []cloud.CloudAwsLinkAccountInput{awsGovCloud}, } return createAwsGovCloudLinkAccountInput } func expandAwsGovCloudLinkAccountInputForRead(d *schema.ResourceData, result *cloud.CloudLinkedAccount) { - _ = d.Set("metric_collection_mode", result.MetricCollectionMode) - _ = d.Set("name", result.Name) - _ = d.Set("aws_account_id", result.ExternalId) _ = d.Set("account_id", result.NrAccountId) + _ = d.Set("name", result.Name) + _ = d.Set("metric_collection_mode", result.MetricCollectionMode) + _ = d.Set("arn", result.AuthLabel) } func expandAwsGovCloudLinkAccountInputForUpdate(d *schema.ResourceData, linkedAccountID int) cloud.CloudUpdateCloudAccountsInput { - awsGovCloud := cloud.CloudAwsGovCloudUpdateAccountInput{} + awsGovCloud := cloud.CloudAwsUpdateAccountInput{} awsGovCloud.LinkedAccountId = linkedAccountID - if accessKeyID, ok := d.GetOk("access_key_id"); ok { - awsGovCloud.AccessKeyId = accessKeyID.(string) - } - if awsAccountID, ok := d.GetOk("aws_account_id"); ok { - awsGovCloud.AwsAccountId = awsAccountID.(string) + + // NOTE: The following arguments are no longer supported; see `expandAwsGovCloudLinkAccountInputForCreate` to know why + + //if accessKeyID, ok := d.GetOk("access_key_id"); ok { + // awsGovCloud.AccessKeyId = accessKeyID.(string) + //} + //if awsAccountID, ok := d.GetOk("aws_account_id"); ok { + // awsGovCloud.AwsAccountId = awsAccountID.(string) + //} + //if secretKeyID, ok := d.GetOk("secret_access_key"); ok { + // awsGovCloud.SecretAccessKey = cloud.SecureValue(secretKeyID.(string)) + //} + + if name, ok := d.GetOk("name"); ok { + awsGovCloud.Name = name.(string) } // The update mutation does not support updating the metric collection mode + // This is also why a 'ForceNew' constraint has been applied on this argument in the schema + //if m, ok := d.GetOk("metric_collection_mode"); ok { // awsGovCloud.MetricCollectionMode = cloud.CloudMetricCollectionMode(strings.ToUpper(m.(string))) //} - if name, ok := d.GetOk("name"); ok { - awsGovCloud.Name = name.(string) - } - if secretKeyID, ok := d.GetOk("secret_access_key"); ok { - awsGovCloud.SecretAccessKey = cloud.SecureValue(secretKeyID.(string)) + if arn, ok := d.GetOk("arn"); ok { + awsGovCloud.Arn = arn.(string) } updateAwsGovCloudLinkAccountInput := cloud.CloudUpdateCloudAccountsInput{ - AwsGovcloud: []cloud.CloudAwsGovCloudUpdateAccountInput{awsGovCloud}, + Aws: []cloud.CloudAwsUpdateAccountInput{awsGovCloud}, } return updateAwsGovCloudLinkAccountInput diff --git a/website/docs/r/cloud_aws_govcloud_link_account.html.markdown b/website/docs/r/cloud_aws_govcloud_link_account.html.markdown index 713c7285c..fac591783 100755 --- a/website/docs/r/cloud_aws_govcloud_link_account.html.markdown +++ b/website/docs/r/cloud_aws_govcloud_link_account.html.markdown @@ -5,19 +5,15 @@ sidebar_current: "docs-newrelic-cloud-resource-aws-govcloud-link-account" description: |- Link an AWS GovCloud account to New Relic. --- --> **IMPORTANT!** This resource is in alpha state, and could still contain issues and missing functionality. If you encounter any issue please create a ticket on [Github](https://github.com/newrelic/terraform-provider-newrelic/issues/new/choose) with all the required information. - # Resource: newrelic_cloud_aws_govcloud_link_account Use this resource to link an AWS GovCloud account to New Relic. ## Prerequisite -Obtain the AwsGovCloud account designed to address the specific regulatory needs of United States (federal, state, and local agencies), education institutions, and the supporting ecosystem. - -It is an isolated AWS region designed to host sensitive data and regulated workloads in the cloud, helping customers support their US government compliance requirements. +To link an AWS GovCloud account to New Relic, you need an AWS GovCloud account. AWS GovCloud is designed to address the specific regulatory needs of United States federal, state, and local agencies, educational institutions, and their supporting ecosystem. It is an isolated AWS region designed to host sensitive data and regulated workloads in the cloud, helping customers support their US government compliance requirements. -To pull data from AWSGovCloud, complete the [steps outlined here](https://docs.newrelic.com/docs/infrastructure/amazon-integrations/get-started/connect-aws-govcloud-new-relic). +To pull data from AWS GovCloud, follow the [steps outlined here](https://docs.newrelic.com/docs/infrastructure/amazon-integrations/get-started/connect-aws-govcloud-new-relic). ## Example Usage @@ -26,9 +22,7 @@ resource "newrelic_cloud_aws_govcloud_link_account" "foo" { account_id = 1234567 name = "My New Relic - AWS GovCloud Linked Account" metric_collection_mode = "PUSH" - aws_account_id = "" - access_key_id = "" - secret_access_key = "" + arn = "arn:aws:service:region:account-id:resource-id" } ``` @@ -36,13 +30,13 @@ resource "newrelic_cloud_aws_govcloud_link_account" "foo" { The following arguments are supported: -- `account_id` - (Optional) The New Relic account ID to operate on. This allows the user to override the `account_id` attribute set on the provider. Defaults to the environment variable `NEW_RELIC_ACCOUNT_ID`. -- `name` - (Required) - The name/identifier of the AWS GovCloud - New Relic 'linked' account. -- `metric_collection_mode` - (Optional) The mode by which metric data is to be collected from the linked AWS GovCloud account. Use `PUSH` for Metric Streams and `PULL` for API Polling based metric collection respectively. - - Note: Altering the `metric_collection_mode` of an already applied `newrelic_cloud_aws_govcloud_link_account` resource shall trigger a recreation of the resource, instead of an update. -- `aws_account_id` - (Required) The ID of the AWS GovCloud account. -- `access_key_id` - (Required) The Access Key used to programmatically access the AWS GovCloud account. -- `secret_access_key` - (Required) The Secret Access Key used to programmatically access the AWS GovCloud account. +- `account_id` - (Optional) The New Relic account ID to operate on. This allows the user to override the `account_id` attribute set on the provider. Defaults to the environment variable `NEW_RELIC_ACCOUNT_ID`, if not specified in the configuration. +- `name` - (Required) The name/identifier of the AWS GovCloud - New Relic 'linked' account. +- `metric_collection_mode` - (Optional) The mode by which metric data is to be collected from the linked AWS GovCloud account. Defaults to `PULL`, if not specified in the configuration. + - Use `PUSH` for Metric Streams and `PULL` for API Polling based metric collection respectively. +- `arn` - (Required) The Amazon Resource Name (ARN) of the IAM role. + +-> **NOTE:** Altering the `account_id` (or) `metric_collection_mode` of an already applied `newrelic_cloud_aws_govcloud_link_account` resource shall trigger a recreation of the resource, instead of an update. ## Attributes Reference