Skip to main content
Version: Next

Appendix: Install Infrastructure with Terraform


Table of Contents

  1. Setup Deployment Environment
  2. Register AWS Account and Install AWS CLI
  3. Setup AWS Infra
  4. Setup Route53 DNS
  5. Setup Certificate Manager
  6. Install Terraform
  7. Additional Route53 Hosted Zones Configuration
  8. Setup Environment Variables with Terraform
  9. Create RDS User and Grant Permissions


Detailed Steps

{For detailed explanations of variables, refer to the Terminology page}


1. Setup Deployment Environment

  • Install Docker Environment

    • It is recommended to use a Docker Container (Ubuntu) to ensure the installation environment is configured independently.

      export DOCKER_NAME=
      # Download Docker
      docker pull ubuntu:20.04

      # Run Docker
      docker container run -id -w /home/mellerikat --name ${DOCKER_NAME} ubuntu:20.04

      # Execute bash
      docker exec -it ${DOCKER_NAME} /bin/bash

      # Install necessary tools
      sudo apt update
      sudo apt install git curl unzip tar make sudo vim wget mysql-server jq lsb-release gpg -y

  • Install kubectl - kubectl is a command-line tool for controlling Kubernetes clusters.

    • The version should be the same as or up to one minor version earlier or later than the Kubernetes cluster version.

      • (If the cluster version is 1.30, the kubectl version should be 1.29, 1.30, or 1.31)
    • To install or upgrade kubectl, refer to the Install or Update kubectl section. - Configure it to communicate with the cluster from your installation environment.

      export INFRA_NAME=
      export DEPLOY_ENV=
      export AWS_CLUSTER_VERSION=
      export AWS_CLUSTER_VERSION_STR=`echo ${AWS_CLUSTER_VERSION} | tr '.' '-'`
      export AWS_DEFAULT_REGION_ALIAS=
      export AWS_CLUSTER_NAME=eks-${AWS_DEFAULT_REGION_ALIAS}-${INFRA_NAME}-${DEPLOY_ENV}-${AWS_CLUSTER_VERSION_STR}-eks-master

      aws eks update-kubeconfig \
      --region ${AWS_DEFAULT_REGION} --name ${AWS_CLUSTER_NAME} --alias ${INFRA_NAME}


2. Register AWS Account and Install AWS CLI

  • If you already have an AWS account with admin privileges, skip this step.
  • If you do not have an account, follow the instructions on the Sign Up for AWS page to create an account.
  • Verify AWS account information
    • Refer to the Find Your AWS Account ID page to find your 12-digit account identifier.
      export AWS_ACCOUNT_ID=
    • Obtain the ACCESS KEY and SECRET ACCESS KEY for the AWS account. For the process, refer to Managing Access Keys for IAM Users.
    • Register the issued ACCESS KEY and SECRET ACCESS KEY, along with the account's region information, as variables.
      export AWS_ACCESS_KEY_ID=
      export AWS_SECRET_ACCESS_KEY=
      export AWS_DEFAULT_REGION=
      export AWS_OUTPUT_FORMAT=json
  • Install AWS CLI
    • Configure the AWS CLI in your installation environment. For detailed installation instructions, refer to the Install the AWS CLI section.


3. Setup AWS Infra

  • The configured name will be used for all resources, including the infrastructure. Multiple projects can be included in one infrastructure. It is recommended to avoid duplicating the infrastructure name ({INFRA_NAME}) and the project name ({PROJECT_NAME}).

    export INFRA_NAME=
    # Choose between dev or prod for DEPLOY_ENV
    export DEPLOY_ENV=
  • Configure AWS PROFILE with the set INFRA_NAME.

    {
    echo "${AWS_ACCESS_KEY_ID}"
    echo "${AWS_SECRET_ACCESS_KEY}"
    echo "${AWS_DEFAULT_REGION}"
    echo "${AWS_OUTPUT_FORMAT}"
    } | aws configure --profile=${INFRA_NAME}

    export AWS_PROFILE=${INFRA_NAME}


4. Setup Route53 DNS

When a domain is registered, a Hosted Zone is automatically registered. If you already have a Hosted Zone, move to 5. Setup Certificate Manager.


  • Domain Registration

    • Go to the AWS Route53 Console.

    • In the left menu, click Registered domains under Domains.

    • Click Register domains.

    • In the Search for domain section, enter the desired {DOMAIN_NAME} (example.com) and click Search.

    • If the entered domain is available, click Select in the Search Result.

    • Click Proceed to checkout.

    • Select Duration and Auto-renew options, then click Next.

    • Enter the Contact information and click Next.

      • A domain email verification will be sent to the email entered in Contact Information.

        [Expand Verify Domain e-mail]
    • Check I have read and agree to the Amazon Route 53 Domain Name Registration End User Agreement.

    • Click Submit.

    • Domain registration may take approximately 10 minutes (up to 1 day).

    • Once domain registration is complete, an email will be sent to the email entered in Contact Information.

      [Expand Registration Domain e-mail]

  • Register Hosted Zone
    • Go to the AWS Route53 Console.
    • In the left menu, click Hosted zones.
    • Click Create hosted zone.
    • Step 1: Hosted zone configuration - Domain name: Enter the desired {DOMAIN_NAME}.
      • Click Create hosted zone to create the Hosted zone.


5. Setup Certificate Manager

Please input the {variables} directly

  • Create a certificate for TLS communication using Certificate Manager.
  • If you already have a Certificate Manager, move to 6. Install Terraform.
  • Go to the AWS Certificate Manager Console.
  • In the left menu, click Request certificate.
  • Select Request a public certificate and click Next.
  • Step 1: Domain names
    • Fully qualified domain name: Enter the above {DOMAIN_NAME}.
    • Click Add another name to this certificate.
      • Enter *.{DOMAIN_NAME}
  • Step 2: Validation method
    • Select DNS validation.
  • Step 3: Key algorithm
    • Select RSA 2048.
  • Click Request.
  • Click the Certificate ID of the created certificate.
  • Click Create records in Route 53.
  • Click Create records to create records in Route53.
  • Verify that the Status of the created certificate in the Certificates list changes to Issued. This process may take some time.


6. Install Terraform

  • Install the Terraform CLI to create infrastructure with Terraform.

    # path : ${TOP}

    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

    sudo apt update && sudo apt install terraform
  • Clone Mellerikat Terraform Repository.

    # path : ${TOP}

    git clone https://github.com/mellerikat/infra.git
    cd infra
  • Use Terraform Init to initialize the directory containing the configuration file.

    # path : ${TOP}/infra

    terraform init
  • Prepare to create infra through terraform.tfvars modification. ( For workspace_vars, you can reduce or increase the number. )


    # path : ${TOP}/infra/terraform.tfvars

    _region = {
    full = "ap-northeast-2" # Region {AWS_DEFAULT_REGION}
    acronym = "an2" # Region acronym
    }
    _project = "infra" # Infra Name {INFRA_NAME}
    _phase = "dev" # Choose dev or prod {DEPLOY_ENV}
    _revision = "tf" # revision

    workspace_vars = {
    poc-ws-low = {
    PROJECT_NAME = "poc", # PROJECT_NAME
    PROJECT_NODEGROUP_SPEC = "low", # Workspace spec(low, standard, high)
    PROJECT_NODEGROUP_EC2_NAME = "r6i.large", # Instance type
    PROJECT_NODEGROUP_EC2_AMI = "AL2_x86_64", # AMI
    PROJECT_NODEGROUP_MAX = 10 # Max Node Size
    }
    poc-ws-standard = {
    PROJECT_NAME = "poc", # PROJECT_NAME
    PROJECT_NODEGROUP_SPEC = "standard", # Workspace spec(low, standard, high)
    PROJECT_NODEGROUP_EC2_NAME = "r6i.xlarge", # Instance type
    PROJECT_NODEGROUP_EC2_AMI = "AL2_x86_64", # AMI
    PROJECT_NODEGROUP_MAX = 10 # Max Node Size
    }
    }

  • Validates the infrastructure resources that will be created through the Terraform Plan.

    # path : ${TOP}/infra

    terraform plan \
    -var 'db_password=${DB_APP_PASSWORD}' -var 'db_user=${DB_APP_USERNAME}' \
    -var 'my_ip='${MY_NAT_IP}'' -var 'domain='${DOMAIN_NAME}''
  • Create infrastructure resources with Terraform Apply.

    # path : ${TOP}/infra

    terraform apply \
    -var 'db_password=${DB_APP_PASSWORD}' -var 'db_user=${DB_APP_USERNAME}' \
    -var 'my_ip='${MY_NAT_IP}'' -var 'domain='${DOMAIN_NAME}''
  • Destroy infrastructure resources with Terraform Destroy.

    # path : ${TOP}/infra

    terraform destroy \
    -var 'db_password=${DB_APP_PASSWORD}' -var 'db_user=${DB_APP_USERNAME}' \
    -var 'my_ip='${MY_NAT_IP}'' -var 'domain='${DOMAIN_NAME}''


7. Additional Route53 Hosted Zones Configuration

Please input the {variables} directly

  • Go to the AWS Route53 Console.

  • In the left menu, click Hosted zones.

  • Click {DOMAIN_NAME}.

  • Click Create record.

  • Record name: *

  • Record type: Select A - Routes traffic to an IPv4 address and some AWS resources.

  • Enable Alias.

  • Route traffic to

    • Choose endpoint: Select Alias to Application and Classic Load Balancer.
      • Choose Region: Select {AWS_DEFAULT_REGION}.
      • Choose load balancer: Select dualstack.{AWS_ALB_DNS_NAME}.
  • Routing policy: Select Simple routing.

  • Click Create records.



8. Setup Environment Variables with Terraform

# path : ${TOP}/infra

export AWS_DEFAULT_REGION=$(terraform output -raw AWS_DEFAULT_REGION)
export AWS_DEFAULT_REGION_ALIAS=$(terraform output -raw AWS_DEFAULT_REGION_ALIAS)
export INFRA_NAME=$(terraform output -raw INFRA_NAME)
export DEPLOY_ENV=$(terraform output -raw DEPLOY_ENV)
export DB_ADMIN_USERNAME=$(terraform output -raw DB_ADMIN_USERNAME)
export DB_ADMIN_PASSWORD=$(terraform output -raw DB_ADMIN_PASSWORD)
export DB_HOST=$(terraform output -raw DB_HOST)
export DB_PORT=$(terraform output -raw DB_PORT)
export AWS_ACCOUNT_ID=$(terraform output -raw AWS_ACCOUNT_ID)
export AWS_CLUSTER_NAME=$(terraform output -raw AWS_CLUSTER_NAME)
export AWS_SECRETS_MANAGER_S3=$(terraform output -raw AWS_SECRETS_MANAGER_S3)
export AWS_SECRETS_MANAGER_RDS=$(terraform output -raw AWS_SECRETS_MANAGER_RDS)
export CLUSTER_REGION=${AWS_DEFAULT_REGION}
export CLUSTER_NAME=${AWS_CLUSTER_NAME}


9. Create RDS User and Grant Permissions

# path : ${TOP}/infra

echo ${DB_ADMIN_PASSWORD} | mysql -h ${DB_HOST} -P ${DB_PORT} -u ${DB_ADMIN_USERNAME} -p${DB_ADMIN_PASSWORD} <<EOF
create user '${DB_APP_USERNAME}'@'%' identified by '${DB_APP_PASSWORD}';
GRANT SELECT, PROCESS, SHOW DATABASES, SHOW VIEW ON *.* TO '${DB_APP_USERNAME}'@'%';
GRANT SELECT, INSERT, UPDATE, DELETE, EXECUTE, SHOW VIEW ON cachedb.* TO '${DB_APP_USERNAME}'@'%';
GRANT SELECT, INSERT, UPDATE, DELETE, EXECUTE, SHOW VIEW ON kubeflow.* TO '${DB_APP_USERNAME}'@'%';
GRANT SELECT, INSERT, UPDATE, DELETE, EXECUTE, SHOW VIEW ON metadb.* TO '${DB_APP_USERNAME}'@'%';
GRANT SELECT, INSERT, UPDATE, DELETE, EXECUTE, SHOW VIEW ON mlpipeline.* TO '${DB_APP_USERNAME}'@'%';
GRANT SELECT, INSERT, UPDATE, DELETE, EXECUTE, SHOW VIEW ON ai_conductor.* TO '${DB_APP_USERNAME}'@'%';
GRANT SELECT, INSERT, UPDATE, DELETE, EXECUTE, SHOW VIEW ON edge_conductor.* TO '${DB_APP_USERNAME}'@'%';
flush privileges;
EOF