diff --git a/.gitignore b/.gitignore index 18221f8..70c2a9f 100644 --- a/.gitignore +++ b/.gitignore @@ -9,8 +9,8 @@ crash.log # Exclude all .tfvars files, which are likely to contain sentitive data, such as -# password, private keys, and other secrets. These should not be part of version -# control as they are data points which are potentially sensitive and subject +# password, private keys, and other secrets. These should not be part of version +# control as they are data points which are potentially sensitive and subject # to change depending on the environment. # *.tfvars @@ -31,4 +31,4 @@ override.tf.json # Ignore CLI configuration files .terraformrc -terraform.rc +terraform.rc \ No newline at end of file diff --git a/.terraform.lock.hcl b/.terraform.lock.hcl index 16a8380..74051a6 100644 --- a/.terraform.lock.hcl +++ b/.terraform.lock.hcl @@ -2,28 +2,28 @@ # Manual edits may be lost in future updates. provider "registry.terraform.io/hashicorp/aws" { - version = "3.63.0" + version = "3.74.0" constraints = ">= 3.28.0" hashes = [ - "h1:lf8Qex8bhCmh8TUEAU6H4brzjy3+d4BXB6gcOYnNtNY=", - "zh:42c6c98b294953a4e1434a331251e539f5372bf6779bd61ab5df84cac0545287", - "zh:5493773762a470889c9a23db97582d3a82035847c8d3bd13323b4c3012abf325", - "zh:550d22ff9fed4d817a922e7b84bd9d1f2ef8d3afa00832cf66b8cd5f0e6dc748", - "zh:632cb5e2d9d5041875f57174236eafe5b05dbf26750c1041ab57eb08c5369fe2", - "zh:7cfeaf5bde1b28bd010415af1f3dc494680a8374f1a26ec19db494d99938cc4e", - "zh:99d871606b67c8aefce49007315de15736b949c09a9f8f29ad8af1e9ce383ed3", - "zh:c4fc8539ffe90df5c7ae587fde495fac6bc0186fec2f2713a8988a619cef265f", - "zh:d0a26493206575c99ca221d78fe64f96a8fbcebe933af92eea6b39168c1f1c1d", - "zh:e156fdc964fdd4a7586ec15629e20d2b06295b46b4962428006e088145db07d6", - "zh:eb04fc80f652b5c92f76822f0fec1697581543806244068506aed69e1bb9b2af", - "zh:f5638a533cf9444f7d02b5527446cdbc3b2eab8bcc4ec4b0ca32035fe6f479d3", + "h1:YNOblHBUf+XTjGTfIIsAMGp4weXB+tmQrMPCrpmM1/U=", + "zh:00767509c13c0d1c7ad6af702c6942e6572aa6d529b40a00baacc0e73faafea2", + "zh:03aafdc903ad49c2eda03889f927f44212674c50e475a9c6298850381319eec2", + "zh:2de8a6a97b180f909d652f215125aa4683e99db15fcf3b28d62e3d542f875ed6", + "zh:3ac29ebc3af99028f4230a79f56606a0c2954b68767bd749b921a76eb4f3bd30", + "zh:50add2e2d118a15a644360eabc5a34cec59f2560b491f8fabf9c52ab83ca7b09", + "zh:85dd8e81910ab79f841a4a595fdd8ac358fbfe460956144afb0be3d81f91fe10", + "zh:895de83d0f0941fde31bfc53fa6b1ea276901f006bec221bbdee4771a04f3693", + "zh:a15c9724aac52d1ba5001d2d83e42843099b52b1638ea29d84e20be0f45fa4f1", + "zh:c982a64463bd73e9bff2589de214b1de0a571438d9015001f9eae45cfc3a2559", + "zh:e9ef973c18078324e43213ea1252c12b9441e566bf054ddfdbff5dd62f3035d9", + "zh:f297e705b0f339c8baa27ae70db5df9aa6578adfe1ea3d2ba8edc186512464eb", ] } provider "registry.terraform.io/hashicorp/null" { version = "3.1.0" hashes = [ - "h1:grYDj8/Lvp1OwME+g1AsECPN1czO5ssSf+8fCluCHQY=", + "h1:vpC6bgUQoJ0znqIKVFevOdq+YQw42bRq0u+H3nto8nA=", "zh:02a1675fd8de126a00460942aaae242e65ca3380b5bb192e8773ef3da9073fd2", "zh:53e30545ff8926a8e30ad30648991ca8b93b6fa496272cd23b26763c8ee84515", "zh:5f9200bf708913621d0f6514179d89700e9aa3097c77dac730e8ba6e5901d521", @@ -41,7 +41,7 @@ provider "registry.terraform.io/hashicorp/null" { provider "registry.terraform.io/hashicorp/tls" { version = "3.1.0" hashes = [ - "h1:U+kgPLboCrcs4eZV87esP7iydF8mjMyHKE/mDsrwfkQ=", + "h1:fUJX8Zxx38e2kBln+zWr1Tl41X+OuiE++REjrEyiOM4=", "zh:3d46616b41fea215566f4a957b6d3a1aa43f1f75c26776d72a98bdba79439db6", "zh:623a203817a6dafa86f1b4141b645159e07ec418c82fe40acd4d2a27543cbaa2", "zh:668217e78b210a6572e7b0ecb4134a6781cc4d738f4f5d09eb756085b082592e", diff --git a/.tflint.hcl b/.tflint.hcl new file mode 100644 index 0000000..3a833ce --- /dev/null +++ b/.tflint.hcl @@ -0,0 +1,19 @@ +config { + module = true +} + +plugin "aws" { + enabled = true + version = "0.12.0" + source = "github.com/terraform-linters/tflint-ruleset-aws" +} + +rule "terraform_naming_convention" { + enabled = true +} +rule "terraform_typed_variables" { + enabled = true +} +rule "terraform_unused_required_providers" { + enabled = true +} diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..8a4f880 --- /dev/null +++ b/Makefile @@ -0,0 +1,9 @@ + +install_lint : + curl -s https://raw.githubusercontent.com/terraform-linters/tflint/master/install_linux.sh | bash + +verify : install_lint + terraform fmt + terraform validate + tflint . + echo "********** Verication done ************ " \ No newline at end of file diff --git a/README.md b/README.md index a2a8095..43323b0 100644 --- a/README.md +++ b/README.md @@ -1,29 +1,60 @@ -# EC2-Minikube - -## Architecture - -![Architecture](images/architecture.drawio.png) - -## Pre-requisite -- yq on your host instance, go [here](https://github.com/mikefarah/yq) to install - -## Usage - -### Provisioning the Infrastructure - -```bash -terraform apply -``` - -### Connecting to the k8s cluster - -You can export the Kubeconfig file using this helper -```bash -$(terraform output -raw kubeconfig_command) -``` - -### Checking the connection - -```bash -kubectl cluster-info -``` +# EC2-Minikube + +## Architecture + +![Architecture](images/architecture.drawio.png) + +## Usage + +### Set up the aws Cli + +Use your access key and secret access key to authenticate + +```bash +aws configure +``` + +### Add execution permission on "downoad_kubeconfig" script + +```bash +sudo chmod +x ./scripts/download_kubeconfig.sh +``` + +### Install yq , yaml template engine . + +```bash +sudo add-apt-repository ppa:rmescandon/yq +sudo apt-get install yq +``` + +### Check your provisioning plan + +```bash +terraform plan +``` + +### Provisioning the Infrastructure + +```bash +terraform apply +``` + +### Connecting to the k8s cluster "check output" + +You can export the Kubeconfig file using this helper + +```bash +$(terraform output -raw kubeconfig_command) +``` + +### Checking the connection + +```bash +kubectl cluster-info +``` + +### You can validate and check your Iac with TFlint + +```bash +make verify +``` diff --git a/main.tf b/minikube_module/main.tf similarity index 86% rename from main.tf rename to minikube_module/main.tf index 037403c..6433e6a 100644 --- a/main.tf +++ b/minikube_module/main.tf @@ -1,119 +1,116 @@ -data "aws_ami" "ubuntu" { - most_recent = true - - filter { - name = "name" - values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"] - } - - filter { - name = "virtualization-type" - values = ["hvm"] - } - - owners = ["099720109477"] # Canonical -} - -resource "tls_private_key" "private_key" { - algorithm = "RSA" -} - -resource "aws_key_pair" "aws_keypair" { - public_key = tls_private_key.private_key.public_key_openssh -} - -resource "aws_security_group" "allow_kube_api_server" { - name = "${var.minikube_instance_name}-allow-kube-api-server" - description = "Allow TLS inbound traffic" - - ingress = [ - { - description = "allow ssh" - from_port = 22 - to_port = 22 - protocol = "TCP" - cidr_blocks = ["0.0.0.0/0"] - ipv6_cidr_blocks = [] - prefix_list_ids = [] - security_groups = [] - self = false - }, - { - description = "allow api server" - from_port = 8443 - to_port = 8443 - protocol = "TCP" - cidr_blocks = ["0.0.0.0/0"] - ipv6_cidr_blocks = [] - prefix_list_ids = [] - security_groups = [] - self = false - } - ] - - egress = [ - { - description = "allow all" - from_port = 0 - to_port = 0 - protocol = "-1" - cidr_blocks = ["0.0.0.0/0"] - ipv6_cidr_blocks = ["::/0"] - prefix_list_ids = [] - security_groups = [] - self = false - } - ] - - tags = { - Name = "allow_kube_api_server" - } -} - -resource "aws_eip" "instance_elastic_ip" {} - -resource "aws_instance" "minikube_instance" { - ami = data.aws_ami.ubuntu.id - instance_type = "t3.large" - key_name = aws_key_pair.aws_keypair.key_name - security_groups = [aws_security_group.allow_kube_api_server.name] - - tags = { - Name = var.minikube_instance_name - } - - connection { - type = "ssh" - user = "ubuntu" - private_key = tls_private_key.private_key.private_key_pem - host = self.public_ip - } - - provisioner "file" { - source = "${path.module}/scripts/setup-minikube.sh" - destination = "/home/ubuntu/setup-minikube.sh" - } - provisioner "remote-exec" { - inline = ["chmod +x /home/ubuntu/setup-minikube.sh", "/home/ubuntu/setup-minikube.sh ${aws_eip.instance_elastic_ip.public_ip}"] - } -} - -resource "null_resource" "download_kubeconfig" { - depends_on = [ - aws_instance.minikube_instance - ] - triggers = { - "timestamp" = timestamp() - } - provisioner "local-exec" { - command = "${path.module}/scripts/download_kubeconfig.sh \"$PRIVATE_KEY\" ubuntu ${aws_eip.instance_elastic_ip.public_ip} ${var.kubeconfig_output_location}" - environment = { - PRIVATE_KEY = tls_private_key.private_key.private_key_pem - } - } -} - -resource "aws_eip_association" "minikube_eip_assoc" { - instance_id = aws_instance.minikube_instance.id - allocation_id = aws_eip.instance_elastic_ip.id -} +data "aws_ami" "ubuntu" { + most_recent = true + + filter { + name = "name" + values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"] + } + + filter { + name = "virtualization-type" + values = ["hvm"] + } + + owners = ["099720109477"] # Canonical +} + +resource "tls_private_key" "private_key" { + algorithm = "RSA" +} + +resource "aws_key_pair" "aws_keypair" { + public_key = tls_private_key.private_key.public_key_openssh +} + +resource "aws_security_group" "allow_kube_api_server" { + name = "allow_kube_api_server" + description = "Allow TLS inbound traffic" + # inbound traffic rules, can be updated with a terraform dynamic block + ingress = [ + { + description = "allow ssh" + from_port = 22 + to_port = 22 + protocol = "TCP" + cidr_blocks = ["0.0.0.0/0"] + ipv6_cidr_blocks = [] + prefix_list_ids = [] + security_groups = [] + self = false + }, + { + description = "allow api server" + from_port = 8443 + to_port = 8443 + protocol = "TCP" + cidr_blocks = ["0.0.0.0/0"] + ipv6_cidr_blocks = [] + prefix_list_ids = [] + security_groups = [] + self = false + } + ] + # Outbound traffic rules, can be updated with a terraform dynamic block + egress = [ + { + description = "allow all" + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + ipv6_cidr_blocks = ["::/0"] + prefix_list_ids = [] + security_groups = [] + self = false + } + ] + + tags = { + Name = "allow_kube_api_server" + } +} + +resource "aws_eip" "instance_elastic_ip" {} + +resource "aws_instance" "minikube_instance" { + ami = data.aws_ami.ubuntu.id + instance_type = var.instance_type + key_name = aws_key_pair.aws_keypair.key_name + + security_groups = [aws_security_group.allow_kube_api_server.name] + + connection { + type = "ssh" + user = "ubuntu" + private_key = tls_private_key.private_key.private_key_pem + host = self.public_ip + } + + provisioner "file" { + source = "${path.module}/scripts/setup-minikube.sh" + destination = "/home/ubuntu/setup-minikube.sh" + } + provisioner "remote-exec" { + inline = ["chmod +x /home/ubuntu/setup-minikube.sh", "/home/ubuntu/setup-minikube.sh ${aws_eip.instance_elastic_ip.public_ip}"] + } +} + +resource "null_resource" "download_kubeconfig" { + depends_on = [ + aws_instance.minikube_instance + ] + triggers = { + "timestamp" = timestamp() + } + provisioner "local-exec" { + command = "${path.module}/scripts/download_kubeconfig.sh \"$PRIVATE_KEY\" ubuntu ${aws_eip.instance_elastic_ip.public_ip} ${var.kubeconfig_output_location}" + environment = { + PRIVATE_KEY = tls_private_key.private_key.private_key_pem + } + } +} + +resource "aws_eip_association" "minikube_eip_assoc" { + instance_id = aws_instance.minikube_instance.id + allocation_id = aws_eip.instance_elastic_ip.id +} diff --git a/minikube_module/output.tf b/minikube_module/output.tf new file mode 100644 index 0000000..91a83d2 --- /dev/null +++ b/minikube_module/output.tf @@ -0,0 +1,9 @@ +output "kubeconfig_command" { + description = "Command that needs to be run in order for your kubectl to point to the minikube" + value = "export KUBECONFIG=${abspath("${var.kubeconfig_output_location}")}" +} + +output "minikub_public_ip" { + description = "MiniKube instance public ip address" + value = aws_eip.instance_elastic_ip.public_ip +} diff --git a/scripts/download_kubeconfig.sh b/minikube_module/scripts/download_kubeconfig.sh similarity index 77% rename from scripts/download_kubeconfig.sh rename to minikube_module/scripts/download_kubeconfig.sh index 228e06f..7acc724 100755 --- a/scripts/download_kubeconfig.sh +++ b/minikube_module/scripts/download_kubeconfig.sh @@ -17,10 +17,4 @@ chmod 400 $TMP_PEM_FILE # Getting the KuebConfig ssh -i $TMP_PEM_FILE -o StrictHostKeyChecking=no $REMOTE_USER@$REMOTE_ADDR "sudo cat /root/.kube/config" >$TMP_KUBECONFIG -if ! command -v yq &> /dev/null -then - echo "yq could not be found, you can install it from here https://github.com/mikefarah/yq" - exit 1 -fi - yq eval ".clusters[0].cluster.server = \"https://${REMOTE_ADDR}:8443\"" "$TMP_KUBECONFIG" >$OUTPUT_FILE diff --git a/scripts/setup-minikube.sh b/minikube_module/scripts/setup-minikube.sh similarity index 97% rename from scripts/setup-minikube.sh rename to minikube_module/scripts/setup-minikube.sh index a0df653..3037375 100644 --- a/scripts/setup-minikube.sh +++ b/minikube_module/scripts/setup-minikube.sh @@ -27,7 +27,7 @@ sudo apt update sudo apt install -y docker-ce docker-ce-cli containerd.io sudo usermod -aG docker $USER -sudo apt install -y conntrack socat +sudo apt install -y conntrack sudo minikube start --driver=none --embed-certs --apiserver-ips=${ELASTIC_IP} sudo minikube addons enable ingress diff --git a/terraform.tf b/minikube_module/terraform.tf similarity index 80% rename from terraform.tf rename to minikube_module/terraform.tf index 114022a..4b7126e 100644 --- a/terraform.tf +++ b/minikube_module/terraform.tf @@ -1,14 +1,14 @@ -terraform { - required_version = ">= 1.0" - - required_providers { - aws = { - source = "hashicorp/aws" - version = ">=3.28.0" - } - } -} - -provider "aws" { - region = var.region -} +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">=3.28.0" + } + } +} + +provider "aws" { + region = var.aws_region +} diff --git a/minikube_module/variables.tf b/minikube_module/variables.tf new file mode 100644 index 0000000..b2eb77f --- /dev/null +++ b/minikube_module/variables.tf @@ -0,0 +1,17 @@ +variable "kubeconfig_output_location" { + description = "KubeConfig file Location" + type = string + +} +variable "aws_region" { + description = "the aws region where to deploy the cluster" + type = string +} + +variable "instance_type" { + description = "Ec2 instance type to use " + type = string +} + + + diff --git a/output.tf b/output.tf index 43ce0b0..c575c32 100644 --- a/output.tf +++ b/output.tf @@ -1,9 +1,9 @@ -output "kubeconfig_command" { +output "kubeconfig_export" { description = "Command that needs to be run in order for your kubectl to point to the minikube" - value = "export KUBECONFIG=${abspath("${var.kubeconfig_output_location}")}" + value = module.aws_ec_kube_cluster.kubeconfig_command } -output "minikube_public_ip" { +output "kube_public_ip" { description = "MiniKube instance public ip address" - value = aws_eip.instance_elastic_ip.public_ip + value = module.aws_ec_kube_cluster.minikub_public_ip } diff --git a/ressource.tf b/ressource.tf new file mode 100644 index 0000000..2a8097b --- /dev/null +++ b/ressource.tf @@ -0,0 +1,6 @@ +module "aws_ec_kube_cluster" { + source = "./minikube_module" + kubeconfig_output_location = var.kubconfig_location + aws_region = var.region + instance_type = var.cluster_instance_type +} diff --git a/root-variables.tf b/root-variables.tf new file mode 100644 index 0000000..4aafccf --- /dev/null +++ b/root-variables.tf @@ -0,0 +1,20 @@ +variable "kubconfig_location" { + description = "Location of the exported cluster's kubeconfig" + type = string + default = "./k8s/kubeconfig" + +} + +variable "cluster_instance_type" { + description = "Type of the cluster's nodes" + type = string + default = "t3.large" +} + +variable "region" { + description = "Cluster's aws region" + type = string + default = "us-east-1" + +} + diff --git a/variables.tf b/variables.tf deleted file mode 100644 index 4eab89e..0000000 --- a/variables.tf +++ /dev/null @@ -1,16 +0,0 @@ -variable "region" { - type = string - description = "AWS Region" - default = "eu-west-1" -} - -variable "kubeconfig_output_location" { - type = string - description = "KubeConfig file Location" -} - -variable "minikube_instance_name" { - type = string - description = "Minikube EC2 Instance name" - default = "minikube-on-ec2" -}