Spawn resources in different cloud providers using Terraform

Introduction:

main.tf

provider "google" {
project = "<Your project name>"
}
provider "aws" {
region = "ca-central-1"
}
provider "kubernetes" {
load_config_file = "false"
host = "https://${google_container_cluster.primary.endpoint}"
username = "admin"
password = "<At least 15 chars>"
client_certificate = base64decode(
google_container_cluster.primary.master_auth[0].client_certificate,
)
client_key = base64decode(
google_container_cluster.primary.master_auth[0].client_key,
)
cluster_ca_certificate = base64decode(
google_container_cluster.primary.master_auth[0].cluster_ca_certificate,
)
}
resource "aws_vpc" "db-vpc" {
cidr_block = "10.1.0.0/16"
instance_tenancy = "default"
enable_dns_hostnames = true
}
resource "aws_subnet" "subnet1" {
vpc_id = aws_vpc.db-vpc.id
cidr_block = "10.1.1.0/24"
availability_zone = "ca-central-1a"
}
resource "aws_subnet" "subnet2" {
vpc_id = aws_vpc.db-vpc.id
cidr_block = "10.1.2.0/24"
availability_zone = "ca-central-1b"
}
resource "aws_route_table_association" "subnet1-rt" {
subnet_id = aws_subnet.subnet1.id
route_table_id = aws_vpc.db-vpc.default_route_table_id
depends_on = [ aws_subnet.subnet1 ]
}
resource "aws_route_table_association" "subnet2-rt" {
subnet_id = aws_subnet.subnet2.id
route_table_id = aws_vpc.db-vpc.default_route_table_id
depends_on = [ aws_subnet.subnet2 ]
}
resource "aws_internet_gateway" "igw" {
vpc_id = aws_vpc.db-vpc.id
}
resource "aws_route" "route-igw" {
route_table_id = aws_vpc.db-vpc.default_route_table_id
destination_cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.igw.id
depends_on = [ aws_internet_gateway.igw ]
}
resource "aws_default_security_group" "sg_rds" {
vpc_id = aws_vpc.db-vpc.id
ingress {
from_port = 3306
to_port = 3306
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_db_subnet_group" "rds-sg" {
name = "mysql-sg"
subnet_ids = [aws_subnet.subnet1.id , aws_subnet.subnet2.id]
}
resource "aws_db_instance" "rds" {
allocated_storage = 20
storage_type = "gp2"
engine = "mysql"
engine_version = "5.7"
instance_class = "db.t2.micro"
name = "trialdb"
username = "admin"
password = "admin1234"
parameter_group_name = "default.mysql5.7"
db_subnet_group_name = aws_db_subnet_group.rds-sg.name
publicly_accessible = true
skip_final_snapshot = true
depends_on = [ aws_db_subnet_group.rds-sg ]
}

gke.tf

variable "gke_username" {
default = "admin"
description = "gke username"
}
variable "region" {
default = "us-central1-a"
}
variable "gke_password" {
default = "<15 chars in length>"
description = "gke password"
}
variable "gke_num_nodes" {
default = 1
description = "number of gke nodes"
}
# GKE cluster
resource "google_container_cluster" "primary" {
name = "trial-gke"
location = var.region
remove_default_node_pool = true
initial_node_count = 1
master_auth {
username = var.gke_username
password = var.gke_password
client_certificate_config {
issue_client_certificate = true
}
}
}
# Separately Managed Node Pool
resource "google_container_node_pool" "primary_nodes" {
name = "${google_container_cluster.primary.name}-node-pool"
location = var.region
cluster = google_container_cluster.primary.name
node_count = var.gke_num_nodes
node_config {
oauth_scopes = [
"https://www.googleapis.com/auth/logging.write",
"https://www.googleapis.com/auth/monitoring",
]
labels = {
env = "trials"
}
# preemptible = true
machine_type = "n1-standard-1"
tags = ["gke-node", "trials-gke"]
metadata = {
disable-legacy-endpoints = "true"
}
}
}
output "kubernetes_cluster_name" {
value = google_container_cluster.primary.name
description = "GKE Cluster Name"
}

wordpress.tf

resource "kubernetes_service" "svc" {
metadata {
name = "wp-svc"
labels = {
app = "wp"
}
}
spec {
selector = {
app = "wp"
}
type = "LoadBalancer"
port {
port = "80"
}
}
depends_on = [ google_container_node_pool.primary_nodes ]
}
resource "kubernetes_persistent_volume_claim" "pvc" {
metadata {
name = "wp-pvc"
}
spec {
access_modes = ["ReadWriteOnce"]
resources {
requests = {
storage = "1Gi"
}
}
}
depends_on = [ google_container_node_pool.primary_nodes ]
}
resource "kubernetes_deployment" "deploy" {
metadata {
name = "wp-deploy"
labels = {
app = "wp"
}
}
spec {
replicas = 1
selector {
match_labels = {
app = "wp"
}
}
template {
metadata {
labels = {
app = "wp"
}
}
spec {
container {
image = "wordpress"
name = "wordpress"
port {
name = "wordpress"
container_port = "80"
}
volume_mount {
name = "wordpress-persistent-storage"
mount_path = "/var/www/html"
}
env {
name = "WORDPRESS_DB_HOST"
value = aws_db_instance.rds.address
}
env {
name = "WORDPRESS_DB_USER"
value = "admin"
}
env {
name = "WORDPRESS_DB_PASSWORD"
value = "admin1234"
}
env {
name = "WORDPRESS_DB_NAME"
value = "trialdb"
}
}
volume {
name = "wordpress-persistent-storage"
persistent_volume_claim {
claim_name = "wp-pvc"
}
}
}
}
}
depends_on = [ kubernetes_service.svc , kubernetes_persistent_volume_claim.pvc ]
}
output "ip" {
value = kubernetes_service.svc.load_balancer_ingress.0.ip
}

Implementation:

terraform init
terraform plan -out wp.json
terraform validate
Success! The configuration is valid.
terraform apply "wp.json"
terraform destroy

Conclusion:

--

--

--

Cloud and DevOps Consultant.

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Mutable, immutable… everything is an object

An interesting tool/technology I encountered in preparation for Bootcamp

Quick guide to setting up a multi site wordpress

6 Tricks to Effectively Use JSON in Python

Wanna use Laravel Homestead VM without installing PHP and Composer?

AWS account OpenID federation using Keycloak

Essentia Staking Guide

Chronicles of Team Pixel — Part One

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Prasanth Kanikicherla

Prasanth Kanikicherla

Cloud and DevOps Consultant.

More from Medium

Ansible Dynamic Inventory AWS

Manage AWS Secrets with aws-vault

Terraform AWS Provider 4.0 refactors S3 bucket resource

CI/CD — Use Google Cloud Build for automated deployment into Google Kubernetes Engine