// Module included in the following assemblies:
//
// * installing/installing_aws/installing-aws-user-infra.adoc
// * installing/installing_aws/installing-restricted-networks-aws.adoc

:_mod-docs-content-type: PROCEDURE
[id="installation-creating-aws-dns_{context}"]
= Creating networking and load balancing components in AWS

You must configure networking and classic or network load balancing in Amazon Web Services (AWS) that your {product-title} cluster can use.

You can use the provided CloudFormation template and a custom parameter file to create a stack of AWS resources. The stack represents the networking and load balancing components that your {product-title} cluster requires. The template also creates a hosted zone and subnet tags.

You can run the template multiple times within a single Virtual Private Cloud (VPC).

[NOTE]
====
If you do not use the provided CloudFormation template to create your AWS
infrastructure, you must review the provided information and manually create
the infrastructure. If your cluster does not initialize correctly, you might
have to contact Red Hat support with your installation logs.
====

.Prerequisites

* You created and configured a VPC and associated subnets in AWS.

.Procedure

. Obtain the hosted zone ID for the Route 53 base domain that you specified in the
`install-config.yaml` file for your cluster. You can obtain details about your hosted zone by running the following command:
+
[source,terminal]
----
$ aws route53 list-hosted-zones-by-name --dns-name <route53_domain> <1>
----
<1> For the `<route53_domain>`, specify the Route 53 base domain that you used
when you generated the `install-config.yaml` file for the cluster.
+
.Example output
[source,terminal]
----
mycluster.example.com.	False	100
HOSTEDZONES	65F8F38E-2268-B835-E15C-AB55336FCBFA	/hostedzone/Z21IXYZABCZ2A4	mycluster.example.com.	10
----
+
In the example output, the hosted zone ID is `Z21IXYZABCZ2A4`.

. Create a JSON file that contains the parameter values that the template
requires:
+
[source,json]
----
[
  {
    "ParameterKey": "ClusterName", <1>
    "ParameterValue": "mycluster" <2>
  },
  {
    "ParameterKey": "InfrastructureName", <3>
    "ParameterValue": "mycluster-<random_string>" <4>
  },
  {
    "ParameterKey": "HostedZoneId", <5>
    "ParameterValue": "<random_string>" <6>
  },
  {
    "ParameterKey": "HostedZoneName", <7>
    "ParameterValue": "example.com" <8>
  },
  {
    "ParameterKey": "PublicSubnets", <9>
    "ParameterValue": "subnet-<random_string>" <10>
  },
  {
    "ParameterKey": "PrivateSubnets", <11>
    "ParameterValue": "subnet-<random_string>" <12>
  },
  {
    "ParameterKey": "VpcId", <13>
    "ParameterValue": "vpc-<random_string>" <14>
  }
]
----
<1> A short, representative cluster name to use for hostnames, etc.
<2> Specify the cluster name that you used when you generated the
`install-config.yaml` file for the cluster.
<3> The name for your cluster infrastructure that is encoded in your Ignition
config files for the cluster.
<4> Specify the infrastructure name that you extracted from the Ignition config
file metadata, which has the format `<cluster-name>-<random-string>`.
<5> The Route 53 public zone ID to register the targets with.
<6> Specify the Route 53 public zone ID, which has a format similar to
`Z21IXYZABCZ2A4`. You can obtain this value from the AWS console.
<7> The Route 53 zone to register the targets with.
<8> Specify the Route 53 base domain that you used when you generated the
`install-config.yaml` file for the cluster. Do not include the trailing period
(.) that is displayed in the AWS console.
<9> The public subnets that you created for your VPC.
<10> Specify the `PublicSubnetIds` value from the output of the CloudFormation
template for the VPC.
<11> The private subnets that you created for your VPC.
<12> Specify the `PrivateSubnetIds` value from the output of the CloudFormation
template for the VPC.
<13> The VPC that you created for the cluster.
<14> Specify the `VpcId` value from the output of the CloudFormation template
for the VPC.

. Copy the template from the *CloudFormation template for the network and load balancers*
section of this topic and save it as a YAML file on your computer. This template
describes the networking and load balancing objects that your cluster requires.
+
[IMPORTANT]
====
If you are deploying your cluster to an AWS government or secret region, you must update the `InternalApiServerRecord` in the CloudFormation template to use `CNAME` records. Records of type `ALIAS` are not supported for AWS government regions.
====

. Launch the CloudFormation template to create a stack of AWS resources that provide the networking and load balancing components:
+
[IMPORTANT]
====
You must enter the command on a single line.
====
+
[source,terminal]
----
$ aws cloudformation create-stack --stack-name <name> <1>
     --template-body file://<template>.yaml <2>
     --parameters file://<parameters>.json <3>
     --capabilities CAPABILITY_NAMED_IAM <4>
----
<1> `<name>` is the name for the CloudFormation stack, such as `cluster-dns`.
You need the name of this stack if you remove the cluster.
<2> `<template>` is the relative path to and name of the CloudFormation template
YAML file that you saved.
<3> `<parameters>` is the relative path to and name of the CloudFormation
parameters JSON file.
<4> You must explicitly declare the `CAPABILITY_NAMED_IAM` capability because the provided template creates some `AWS::IAM::Role` resources.
+
.Example output
[source,terminal]
----
arn:aws:cloudformation:us-east-1:269333783861:stack/cluster-dns/cd3e5de0-2fd4-11eb-5cf0-12be5c33a183
----

. Confirm that the template components exist:
+
[source,terminal]
----
$ aws cloudformation describe-stacks --stack-name <name>
----
+
After the `StackStatus` displays `CREATE_COMPLETE`, the output displays values
for the following parameters. You must provide these parameter values to
the other CloudFormation templates that you run to create your cluster:
[horizontal]
`PrivateHostedZoneId`:: Hosted zone ID for the private DNS.
`ExternalApiLoadBalancerName`:: Full name of the external API load balancer.
`InternalApiLoadBalancerName`:: Full name of the internal API load balancer.
`ApiServerDnsName`:: Full hostname of the API server.
`RegisterNlbIpTargetsLambda`:: Lambda ARN useful to help register/deregister IP
targets for these load balancers.
`ExternalApiTargetGroupArn`:: ARN of external API target group.
`InternalApiTargetGroupArn`:: ARN of internal API target group.
`InternalServiceTargetGroupArn`:: ARN of internal service target group.
