Skip to content

Deploying RDAF Platform using Terraform scripts in AWS (Non-Kubernetes environment)

Introduction

This Document provides the steps to install and configure CloudFabrix RDAF Platform using terraform in AWS EC2 environment.

1. Pre-Requisites

1.1 Download & Install Terraform

For detailed information on how to download and install Terraform on different Operating Systems, please Click Here

To install Terraform CLI on Ubuntu Linux OS environment, please run the below commands.

wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg

echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
This command Updates the package and installs Terraform CLI

sudo apt update && sudo apt install terraform

For detailed documentation on installing Terraform for macOS please Click Here

1.2 Download, Install & Configure AWS CLI

Run the below commands to install and configure AWS CLI on Linux OS.

curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install

To configure the AWS CLI, run the command below and enter the AWS API credentials as shown in the example output.

Note

Please make sure the provided API credentials have necessary permissions to perform the below operations on selected AWS region.

  • Copy CloudFabrix Ubuntu AWS AMI Image between Regions
  • Deploy and Configure EC2 instances
  • Deploy and Configure VPCs, Security Groups & Gateways
aws configure
AWS Access Key ID [None]: YOUR_ACCESS_KEY_ID
AWS Secret Access Key [None]: YOUR_SECRET_ACCESS_KEY
Default region name [None]: ap-south-1
Default output format [None]: json

Below are some of the available AWS regions for reference.

  • us-east-1
  • us-east-2
  • us-west-1
  • us-west-2
  • ap-south-1
  • ap-northeast-1
  • ap-northeast-2
  • ap-northeast-3
  • ap-southeast-1
  • ap-southeast-2
  • ca-central-1
  • eu-central-1
  • eu-west-1
  • eu-west-2
  • eu-west-3
  • eu-north-1
  • sa-east-1

Once Terraform and AWS CLI are installed, use the commands below to check their versions.

terraform --version
aws --version

Run the command below to verify which AWS region you are connected to.

aws configure get region
ap-south-1

The CloudFabrix qualified AMI image (ID: ami-0fe0b643dfe74464b) is located in the us-east-1 region. Please ensure that you copy this AMI image to your selected AWS region.

Please refer to the AWS CLI command below as a reference. After successfully copying the AMI image, be sure to note down the new AMI image ID.

aws ec2 copy-image --source-image-id ami-0fe0b643dfe74464b --source-region us-east-1 --region ap-southeast-1 --name "cfx-rdaf-ami-image"
{
  "ImageId": "ami-0645b28f2defbf294"
}

Please run the below command to verify the copied AMI image in the target AWS region

aws ec2 describe-images --image-ids <ami-0b938098543dc9aa4>

2. Configure the Terraform

All the required Terraform and shell scripts are bundled in a tar file.

2.1 Download Terraform Configuration Templates

Please download the tar file by running the command below.

wget https://macaw-amer.s3.amazonaws.com/rdaf-temp/rda-single-or-multi-node-poc-aws-2.0.tar

To extract the contents of the downloaded file, use the command below.

tar -xvf rda-single-or-multi-node-poc-aws-2.0.tar

2.2 Configure dev.tfvars File

Most of the configurable parameters are defined in the dev.tfvars file. Below are brief details of the Terraform files. Please review all parameters in these files and modify the dev.tfvars file to meet the PoC or Production deployment requirements.

To list all of the extracted Terraform files.

cd rda-single-or-multi-node-poc-aws-2.0; ls
README.md         instance-platform-app.tf  network.tf  provider.tf       scripts      terraform.tfstate
cloud-config.xml  instance-rda-worker.tf    outputs.tf  rexec.tf          security.tf  terraform.tfstate.backup
dev.tfvars        loadbalancer.tf           params.tf   routing-table.tf  ssh-key.tf   vpc_peering.tf

Configurable parameters in dev.tfvars

Below are some of the important parameters that need to be reviewed and configured in the dev.tfvars file before using the terraform CLI to deploy the EC2 instances.

  • AWS AMI image ID, AWS region and Mount points for all EC2 instances.

  • Set the number of EC2 instances required for RDAF Platform deployment.

  • CloudFabrix RDAF Platform deployment tags for Infrastructure, Platform, Application, and Worker services also need to be configured before initializing terraform.

2.2.1 Configure EC2 RDAF Infrastructure/Platform Services Instance

The parameters in dev.tfvars are set to meet the majority of PoC requirements by default. If your requirements differ for a PoC or for Production deployments, please adjust the AMI shape, disk sizes, instance count as needed.

vi dev.tfvars

Below EC2 instance is used to install RDAF Infrastructure or Infrastructure and Platform services.

# Set ec2 Platform image AMI and shape
Platformami =  "ami-0c2a9937b3301f9c8" # public cfx ubuntu ami in us-east-1
PlatformamiShape = "r5.xlarge" #4vcpu/32gb
PlatformRootSize = 75  # root partition size in GB
PlatformSDBSize =  50  # sdb partition size in GB #/opt
PlatformSDCSize =  50  # sdc partition size in GB #/var/lib/docker
PlatformXVDDSize = 50  # xvdd partition size in GB #/minio-data
PlatformXVDESize = 50 # xvde partition size in GB #/var/mysql
PlatformXVDFSize = 50 # xvdf partition size in GB #/opensearch
PlatformXVDGSize = 25  # xvdg partition size in GB # /kafka-logs
PlatformXVDHSize = 50  # xvdh partition size in GB # /graphdb

2.2.2 Configure EC2 RDAF Application Services Instance

Below EC2 instance is used to install either the RDAF Platform, the Application, or both services.

Serviceami = "ami-0fe0b643dfe74464b" # Cloudfabrix AMI in us-east-1
ServiceamiShape = "r5.xlarge"
ServiceRootSize = 50  # root partition size in GB
ServiceSDBSize = 50   # sdb partition size in GB #/opt
ServiceSDCSize = 50   # sdc partition size in GB #/var/lib/docker

2.2.3 Configure EC2 RDAF Worker Services Instance

Below EC2 instance is used to install RDAF Worker services.

RDAWorkerami = "ami-0fe0b643dfe74464b" # Cloudfabrix AMI in us-east-1
RDAWorkeramiShape = "r5.xlarge"
RDAWorkerRootSize = 50  # root partition size in GB
RDAWorkerSDBSize = 20   # sdb partition size in GB #/opt
RDAWorkerSDCSize = 50   # sdc partition size in GB #/var/lib/docker

2.2.4 Configure EC2 instance count for each RDAF Platform Service

Configure the number of EC2 instances for each RDAF Platform service (Infrastructure, Platform, Application and Worker) required for the PoC or Production environment in the dev.tfvars file.

# Set number of instance for Platform
PlatformVMCount = 1

# Set number of instance for ServiceVM
ServiceVMCount = 1

# Set number of instance for RDAWorkerVM
RDAWorkerVMCount = 1

2.2.5 Set the AWS Region

For deploying the RDAF Platform in a specific AWS region, please set the AWS region appropriately in the dev.tfvars file as shown below. Please make sure the region is same as AMI image's location.

#### region
aws_region = "ap-south-1" #"AWS region to launch servers."

Note

Please verify the changes made to the dev.tfvars file. As mentioned above, double-check the AMI ID, AWS region, VM count, and disk sizes to ensure they suit the PoC or Production deployment.

Warning

This Terraform script supports only Nitro-based AWS instance types and may not work with non-Nitro instance types.

Below are the other Terraform configuration files for reference. In most cases, the default settings will work, but please modify them if necessary.

  • instance-platform-app.tf: RDAF Platform's infrastructure and application service's instance disk configuration.
  • instance-rda-worker.tf RDAF Platform's worker service's instance disk configuration.
  • network.tf: RDAF Platform service's network configuration
  • params.tf AWS AMI image, region, additional filesystem information, raw devices, RDA user, application settings, and more.
  • rexec.tf: Post-provisioning configuration for EC2 instances within the Ubuntu OS environment.
  • routing-table.tf VPC subnet and routing configuration information.
  • security.tf Allowed Ports to access RDAF Platform EC2 instances.

3. SSH Key Generation

Run the command below to generate SSH public and private keys. If a passphrase is not needed, press Enter twice when prompted.

ssh-keygen -t rsa -b 4096 -f ~/.ssh/rdafkey

4. Initialize, Plan and Apply Terraform

4.1 Initialize Terraform

Please make sure the working directory is rda-single-or-multi-node-poc-aws-2.0

cd rda-single-or-multi-node-poc-aws-2.0

Please run the below command to Initialize terraform

terraform init
Initializing the backend...
Initializing provider plugins...
- Reusing previous version of hashicorp/cloudinit from the dependency lock file
- Reusing previous version of hashicorp/aws from the dependency lock file
- Reusing previous version of hashicorp/null from the dependency lock file
- Using previously-installed hashicorp/cloudinit v2.3.4
- Using previously-installed hashicorp/aws v5.57.0
- Using previously-installed hashicorp/null v3.2.2

Terraform has been successfully initialized!

4.2 Initialize Terraform Plan

Please run the command below to validate and initialize the configuration settings applied in the dev.tfvars file.

terraform plan -var-file=dev.tfvars
Plan: 13 to add, 0 to change, 0 to destroy.

Changes to Outputs:
  + Platform_instance_ip_z1 = [
      + (known after apply),
    ]
...
...
Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.

4.3 Apply Terraform Plan

Please run the command below to deploy the configuration based on the settings in the dev.tfvars file

terraform apply -var-file=dev.tfvars

Note

Enter yes when its prompted

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.
  Enter a value: yes
null_resource.platform_provisioner1[0] (remote-exec):  ⠿ Network deployment-scripts_default         Created 0.1s2s
null_resource.platform_provisioner1[0] (remote-exec):  ⠿ Container deployment-scripts-rda_worker-1  Started 13.8ss
null_resource.platform_provisioner1[0] (remote-exec):
null_resource.platform_provisioner1[0]: Still creating... [19m10s elapsed]
null_resource.platform_provisioner1[0]: Creation complete after 19m12s [id=5901124922365241491]

Apply complete! Resources: 13 added, 0 changed, 0 destroyed.

Outputs:

Platform_instance_ip_z1 = [
  "Platform_Instance_IP",
]

Note

As shown above in the Example Output please use the actual "Platform_Instance_IP" for SSH

Please keep a note of the above RDAF Platform Instance's private IP address from the AWS Console which is required during RDAF Setup

Please check the AWS console to verify that the CloudFabrix RDAF Platform's EC2 instances have been provisioned correctly.

Each EC2 instance for the RDAF Platform will have a private subnet IP address. Make a note of these addresses, as they will be needed when running the rdaf setup command.

The default username and password for the provisioned RDAF EC2 instances are: (unless these are changed in dev.tfvars file)

  • Username: rdauser
  • Password: rdauser1234

5. SSH to RDAF Platform VMs

Once the RDAF Platform's EC2 instances are created, you can connect to them via SSH using either the username/password or an SSH key.

ssh -i ~/.ssh/rdafkey rdauser@Platform_Instance_IP

or

ssh rdauser@Platform_Instance_IP
ssh -i ~/.ssh/rdafkey rdauser@Platform_Instance_IP

Welcome to Ubuntu 22.04.2 LTS (GNU/Linux 5.19.0-1029-aws x86_64)
rdauser@ip-10-91-1-10:~$

Note

Please use the actual "Platform_Instance_IP"

6. RDAF Setup & Installation

Please refer the below instructions to download and install RDAF deployment CLI.

  • Download the RDAF Deployment CLI's newer version 1.5.0 bundle
wget https://macaw-amer.s3.us-east-1.amazonaws.com/releases/rdaf-platform/1.5.0/rdafcli-1.5.0.tar.gz 
  • Upgrade the rdaf CLI to version 1.5.0
pip install --user rdafcli-1.5.0.tar.gz
  • Verify the installed rdaf CLI version is upgraded to 1.5.0
rdaf --version
RDAF CLI version: 1.5.0
  • Download the RDAF Deployment CLI's newer version 1.5.0 bundle and copy it to RDAF management VM on which rdaf & rdafk8s deployment CLI was installed.
wget https://macaw-amer.s3.us-east-1.amazonaws.com/releases/rdaf-platform/1.5.0/offline-ubuntu-1.5.0.tar.gz 
  • Extract the rdaf CLI software bundle contents
tar -xvzf offline-ubuntu-1.5.0.tar.gz
  • Change the directory to the extracted directory
cd offline-ubuntu-1.5.0
  • Upgrade the rdafCLI to version 1.5.0
pip install --user rdafcli-1.5.0.tar.gz -f ./ --no-index
  • Verify the installed rdaf CLI version
rdaf --version
RDAF CLI version: 1.5.0

For further details and next steps on RDAF setup, configuration and installation, refer RDAF Setup & Installation documentation.

7. Destroy Terraform

To destroy the deployed RDAF Platform's EC2 instances and the corresponding AWS configuration, run the following terraform command.

Danger

Running the command below will destroy the RDAF Platform's EC2 instances and their corresponding AWS configuration, resulting in data loss. Please ensure you want to proceed before executing it.

terraform destroy -var-file=dev.tfvars

Note

Enter yes for confirmation

aws_security_group.administration: Destruction complete after 3s
aws_security_group.loadbalancer_alb: Destroying... [id=sg-04addb3b4a5a4d641]
aws_internet_gateway.gw: Destruction complete after 1s
aws_security_group.loadbalancer_alb: Destruction complete after 1s
aws_vpc.rdavpc: Destroying... [id=vpc-04a1c776f47df9484]
aws_vpc.rdavpc: Destruction complete after 1s

Destroy complete! Resources: 13 destroyed.

8. Dynamic IP Address to Static IP for EC2 Instances

To make the public IPs of EC2 instances static (Elastic IPs) from the AWS Command Line Interface (CLI), Please follow the below mentioned steps

8.1 Allocate an Elastic IP Address

Run the below command to allocate an Elastic IP address, which will generate the static IP.

aws ec2 allocate-address --domain vpc

The above mentioned command will return an AllocationId, which should be used in the next step.

Please note down the AllocationId.

aws ec2 allocate-address --domain vpc
{
    "PublicIp": "65.2.89.187",
    "AllocationId": "eipalloc-08c3e4687b35447f0",
    "PublicIpv4Pool": "amazon",
    "NetworkBorderGroup": "ap-south-1",
    "Domain": "vpc"
}

8.2 Associate the Elastic IP Address with the EC2 Instance

Run the below command to Associate the Elastic IP Address with the EC2 Instance

aws ec2 associate-address --instance-id i-xxxxxxxx --allocation-id eipalloc-xxxxxxxx

Replace i-xxxxxxxx with the EC2 instance ID and eipalloc-xxxxxxxx with the AllocationId returned from the previous command.

Enter the instance ID of EC2 instance with the above AllocationId

aws ec2 associate-address --instance-id i-039936dc25e7ca1f4 --allocation-id eipalloc-08c3e4687b35447f0
{
    "AssociationId": "eipassoc-09adc6d0f691ac87b"
}

8.3 Release the Existing Dynamic Public IP

The dynamic public IP address assigned to instance will automatically be released when user associates the Elastic IP with the instance. There's no need to manually release it.

Important

Please verify the same static IP address gets reflected in AWS Console

8.4 Verify the Association

User can verify that the Elastic IP is correctly associated with the instance by running the below command

aws ec2 describe-instances --instance-ids i-xxxxxxxx
aws ec2 describe-instances --instance-ids i-0d3944c624242a5ce
{
    "Reservations": [
        {
            "Groups": [],
            "Instances": [
                {
                    "AmiLaunchIndex": 0,
                    "ImageId": "ami-0c2a9937b3301f9c8",
                    "InstanceId": "i-0d3944c624242a5ce",
                    "InstanceType": "r5.xlarge",
                    "KeyName": "pod001-AiOPS-key",
                    "LaunchTime": "2024-08-27T12:12:42+00:00",
                    "Monitoring": {
                        "State": "disabled"
                    },
                    "Placement": {
                        "AvailabilityZone": "ap-south-1a",
                        "GroupName": "",
                        "Tenancy": "default"
                    },
                    "PrivateDnsName": "ip-10-91-1-10.ap-south-1.compute.internal",
                    "PrivateIpAddress": "10.91.1.10",
                    "ProductCodes": [],
                    "PublicDnsName": "ec2-13-233-111-144.ap-south-1.compute.amazonaws.com",
                    "PublicIpAddress": "13.233.111.144",
                    "State": {
                        "Code": 16,
                        "Name": "running"
                    },
                    "StateTransitionReason": "",
                    "SubnetId": "subnet-08474edffc22ee1ef",
                    "VpcId": "vpc-08cabe8a7f3bcc5ed",
                    "Architecture": "x86_64",
                    "BlockDeviceMappings": [
                        {
                            "DeviceName": "/dev/sda1",
                            "Ebs": {
                                "AttachTime": "2024-08-27T12:12:43+00:00",
                                "DeleteOnTermination": true,
                                "Status": "attached",
                                "VolumeId": "vol-00f1ea34669044083"
                            }
                        },
                        {
                            "DeviceName": "/dev/sdb",
                            "Ebs": {
                                "AttachTime": "2024-08-27T12:12:43+00:00",
                                "DeleteOnTermination": true,
                                "Status": "attached",
                                "VolumeId": "vol-0ad5ab1468efc6e03"
                            }
                        },
                        {
                            "DeviceName": "/dev/sdc",
                            "Ebs": {
                                "AttachTime": "2024-08-27T12:12:43+00:00",
                                "DeleteOnTermination": true,
                                "Status": "attached",
                                "VolumeId": "vol-0ca607ef4000a9c81"
                            }
                        },
                        {
                            "DeviceName": "/dev/xvdd",
                            "Ebs": {
                                "AttachTime": "2024-08-27T12:12:43+00:00",
                                "DeleteOnTermination": true,
                                "Status": "attached",
                                "VolumeId": "vol-0e2360621930843c5"
                            }
                        },
                        {
                            "DeviceName": "/dev/xvde",
                            "Ebs": {
                                "AttachTime": "2024-08-27T12:12:43+00:00",
                                "DeleteOnTermination": true,
                                "Status": "attached",
                                "VolumeId": "vol-0f25edc8ab3c0e27e"
                            }
                        },
                        {
                            "DeviceName": "/dev/xvdf",
                            "Ebs": {
                                "AttachTime": "2024-08-27T12:12:43+00:00",
                                "DeleteOnTermination": true,
                                "Status": "attached",
                                "VolumeId": "vol-03a780a3e7db7c450"
                            }
                        },
                        {
                            "DeviceName": "/dev/xvdg",
                            "Ebs": {
                                "AttachTime": "2024-08-27T12:12:43+00:00",
                                "DeleteOnTermination": true,
                                "Status": "attached",
                                "VolumeId": "vol-0719c272ab234586c"
                            }
                        },
                        {
                            "DeviceName": "/dev/xvdh",
                            "Ebs": {
                                "AttachTime": "2024-08-27T12:12:43+00:00",
                                "DeleteOnTermination": true,
                                "Status": "attached",
                                "VolumeId": "vol-0332a0d1781954ba9"
                            }
                        }
                    ],
                    "ClientToken": "terraform-20240827121241135300000004",
                    "EbsOptimized": false,
                    "EnaSupport": true,
                    "Hypervisor": "xen",
                    "NetworkInterfaces": [
                        {
                            "Association": {
                                "IpOwnerId": "amazon",
                                "PublicDnsName": "ec2-13-233-111-144.ap-south-1.compute.amazonaws.com",
                                "PublicIp": "13.233.111.144"
                            },
                            "Attachment": {
                                "AttachTime": "2024-08-27T12:12:42+00:00",
                                "AttachmentId": "eni-attach-09dae4c94d5de20fc",
                                "DeleteOnTermination": true,
                                "DeviceIndex": 0,
                                "Status": "attached",
                                "NetworkCardIndex": 0
                            },
                            "Description": "",
                            "Groups": [
                                {
                                    "GroupName": "pod001.AiOPS.loadbalancer_alb.sg",
                                    "GroupId": "sg-09101f69cc93966d3"
                                },
                                {
                                    "GroupName": "pod001.AiOPS.infra.sg",
                                    "GroupId": "sg-0763be4378699c03a"
                                }
                            ],
                            "Ipv6Addresses": [],
                            "MacAddress": "02:76:fd:54:c6:99",
                            "NetworkInterfaceId": "eni-058fd77442abe13fe",
                            "OwnerId": "168952226705",
                            "PrivateDnsName": "ip-10-91-1-10.ap-south-1.compute.internal",
                            "PrivateIpAddress": "10.91.1.10",
                            "PrivateIpAddresses": [
                                {
                                    "Association": {
                                        "IpOwnerId": "amazon",
                                        "PublicDnsName": "ec2-13-233-111-144.ap-south-1.compute.amazonaws.com",
                                        "PublicIp": "13.233.111.144"
                                    },
                                    "Primary": true,
                                    "PrivateDnsName": "ip-10-91-1-10.ap-south-1.compute.internal",
                                    "PrivateIpAddress": "10.91.1.10"
                                }
                            ],
                            "SourceDestCheck": true,
                            "Status": "in-use",
                            "SubnetId": "subnet-08474edffc22ee1ef",
                            "VpcId": "vpc-08cabe8a7f3bcc5ed",
                            "InterfaceType": "interface"
                        }
                    ],
                    "RootDeviceName": "/dev/sda1",
                    "RootDeviceType": "ebs",
                    "SecurityGroups": [
                        {
                            "GroupName": "pod001.AiOPS.loadbalancer_alb.sg",
                            "GroupId": "sg-09101f69cc93966d3"
                        },
                        {
                            "GroupName": "pod001.AiOPS.infra.sg",
                            "GroupId": "sg-0763be4378699c03a"
                        }
                    ],
                    "SourceDestCheck": true,
                    "Tags": [
                        {
                            "Key": "Name",
                            "Value": "pod001.AiOPS.PlatformVM.0.Zone1"
                        },
                        {
                            "Key": "Product",
                            "Value": "AiOPS"
                        },
                        {
                            "Key": "Pod",
                            "Value": "pod001"
                        }
                    ],
                    "VirtualizationType": "hvm",
                    "CpuOptions": {
                        "CoreCount": 2,
                        "ThreadsPerCore": 2
                    },
                    "CapacityReservationSpecification": {
                        "CapacityReservationPreference": "open"
                    },
                    "HibernationOptions": {
                        "Configured": false
                    },
                    "MetadataOptions": {
                        "State": "applied",
                        "HttpTokens": "optional",
                        "HttpPutResponseHopLimit": 1,
                        "HttpEndpoint": "enabled",
                        "HttpProtocolIpv6": "disabled",
                        "InstanceMetadataTags": "disabled"
                    },
                    "EnclaveOptions": {
                        "Enabled": false
                    },
                    "PlatformDetails": "Linux/UNIX",
                    "UsageOperation": "RunInstances",
                    "UsageOperationUpdateTime": "2024-08-27T12:12:42+00:00",
                    "PrivateDnsNameOptions": {
                        "HostnameType": "ip-name",
                        "EnableResourceNameDnsARecord": false,
                        "EnableResourceNameDnsAAAARecord": false
                    },
                    "MaintenanceOptions": {
                        "AutoRecovery": "default"
                    },
                    "CurrentInstanceBootMode": "legacy-bios"
                }
            ],
            "OwnerId": "168952226705",
            "ReservationId": "r-0905870b72baa5794"
        }
    ]
}

Check the output to ensure the PublicIp matches the Elastic IP which is associated

Note

User needs to follow the above steps for Service VM and worker VM as well