Skip to content

Using AWS & AWSCC Provider Together

\~> NOTE: The awscc provider is currently in technical preview. This means some aspects of its design and implementation are not yet considered stable for production use. We are actively looking for community feedback in order to identify needed improvements.

The HashiCorp Terraform AWS Cloud Control Provider aims to bring Amazon Web Services (AWS) resources to Terraform users faster. The new provider is automatically generated, which means new features and services on AWS can be supported right away. The AWS Cloud Control provider supports hundreds of AWS resources, with more support being added as AWS service teams adopt the Cloud Control API standard.

For Terraform users managing infrastructure on AWS, we expect the AWSCC provider will be used alongside the existing AWS provider. This guide is provided to show guidance and an example of using the providers together to deploy an AWS Cloud WAN Core Network.

For more information about the AWSCC provider, please see the provider documentation in Terraform Registry

AWS Cloud Wan

In this guide we will deploy AWS Cloud WAN to demonstrate how both AWS & AWSCC can work togther. Cloud WAN is a wide area networking (WAN) service that helps you build, manage, and monitor a unified global network that manages traffic running between resources in your cloud and on-premises environments.

With Cloud WAN, you define network policies that are used to create a global network that spans multiple locations and networks—eliminating the need to configure and manage different networks individually using different technologies. Your network policies can be used to specify which of your Amazon Virtual Private Clouds (VPCs) and on-premises locations you wish to connect through AWS VPN or third-party software-defined WAN (SD-WAN) products, and the Cloud WAN central dashboard generates a complete view of the network to monitor network health, security, and performance. Cloud WAN automatically creates a global network across AWS Regions using Border Gateway Protocol (BGP), so you can easily exchange routes around the world.

For more information on AWS Cloud WAN see the documentation.

Specifying Multiple Providers

Terraform can use many providers at once, as long as they are specified in your terraform configuration block:

terraform {
  required_version = ">= 1.0.7"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = ">= 4.9.0"
    }
    awscc = {
      source  = "hashicorp/awscc"
      version = ">= 0.25.0"
    }
  }
}

The code snippet above informs terraform to download 2 providers as plugins for the current root module, the AWS and AWSCC provider. You can tell which provider is being use by looking at the resource or data source name-prefix. Resources that start with aws use the AWS provider, resources that start with awscc are using the AWSCC provider.

First look at AWSCC resources

Lets start by building our global network which will house our core network.

/*Provider bindings are generated by running cdktf get.
See https://cdk.tf/provider-generation for more details.*/
import * as awscc from "./.gen/providers/awscc";
/*The following providers are missing schema information and might need manual adjustments to synthesize correctly: awscc.
For a more precise conversion please use the --provider flag in convert.*/
new awscc.networkmanagerGlobalNetwork.NetworkmanagerGlobalNetwork(
  this,
  "main",
  {
    description: "My Global Network",
    tags: '${concat(local.terraform_tag,\n    [{\n      key   = "Name"\n      value = "My Global Network"\n    }]\n  )}',
  }
);

Above, we define a awsccNetworkmanagerGlobalNetwork with 2 tags and a description. AWSCC resources use the standard AWS tag format which is expressed in HCL as a list of maps with 2 keys. We want to reuse the terraform =True tag so we define it as a local then we use concat to join the list of tags together.

Using AWS and AWSCC providers together

Next we will create a core network using an AWSCC resource awsccNetworkmanagerCoreNetwork and an AWS data source dataAwsNetworkmanagerCoreNetworkPolicyDocument which allows users to write HCL to generate the json policy used as the core policy network.

/*Provider bindings are generated by running cdktf get.
See https://cdk.tf/provider-generation for more details.*/
import * as awscc from "./.gen/providers/awscc";
import * as aws from "./.gen/providers/aws";
/*The following providers are missing schema information and might need manual adjustments to synthesize correctly: awscc.
For a more precise conversion please use the --provider flag in convert.*/
const dataAwsNetworkmanagerCoreNetworkPolicyDocumentMain =
  new aws.dataAwsNetworkmanagerCoreNetworkPolicyDocument.DataAwsNetworkmanagerCoreNetworkPolicyDocument(
    this,
    "main",
    {
      attachmentPolicies: [
        {
          action: {
            associationMethod: "constant",
            segment: "shared",
          },
          conditionLogic: "or",
          conditions: [
            {
              key: "segment",
              operator: "equals",
              type: "tag-value",
              value: "shared",
            },
          ],
          ruleNumber: 1,
        },
      ],
      coreNetworkConfiguration: [
        {
          asnRanges: ["64512-64555"],
          edgeLocations: [
            {
              asn: 64512,
              location: "us-east-1",
            },
          ],
          vpnEcmpSupport: false,
        },
      ],
      segmentActions: [
        {
          action: "share",
          mode: "attachment-route",
          segment: "shared",
          shareWith: ["*"],
        },
      ],
      segments: [
        {
          description: "SegmentForSharedServices",
          name: "shared",
          requireAttachmentAcceptance: true,
        },
      ],
    }
  );
const awsccNetworkmanagerCoreNetworkMain =
  new awscc.networkmanagerCoreNetwork.NetworkmanagerCoreNetwork(
    this,
    "main_1",
    {
      description: "My Core Network",
      global_network_id: "${awscc_networkmanager_global_network.main.id}",
      policy_document: `\${jsonencode(jsondecode(${dataAwsNetworkmanagerCoreNetworkPolicyDocumentMain.json}))}`,
      tags: "${local.terraform_tag}",
    }
  );
/*This allows the Terraform resource name to match the original name. You can remove the call if you don't need them to match.*/
awsccNetworkmanagerCoreNetworkMain.overrideLogicalId("main");

Thanks to Terraform's plugin design, the providers work together seemlessly!