Creating Infraestructure with the ACK from EKS AWS.
Published: 2024-06-27 21:14:51

Cloud people!

The turn in this occasion is for the AWS controller for k8s (ack).

I believe that traditional Infrastructure as Code (IaC) tools have some limitations. The transition towards solutions such as Crossplane or similar projects is inevitable and, possibly, in a short time this evolution will be adopted. At another time, we could discuss in detail the pros and cons of these tools.

## Requirements
* [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html)
* [Kubectl](https://kubernetes.io/docs/tasks/tools/)
* [Terraform](https://www.terraform.io/downloads.html)
* [k9s](https://k9scli.io/topics/install/)
* [Helm](https://helm.sh/docs/intro/install/)
* K8s cluster (You can use a local cluster or in this demo an eks cluster.)

Let's see how we can do this.

##Reference Architecture
In this demo Terraform is used to deploy infrastructure base where ack will be executed.

Please check this [link](https://aws-controllers-k8s.github.io/community/docs/community/how-it-works/) for architecture reference.


## Step 1.

In this step you need to deploy a cluster of k8s and all that necessary for that cluster work. For a better brevity, the code is shared in this repository.
{% embed https://github.com/segoja7/ack_controller_demo %} 

## Step 2.
With the eks cluster in this case running you need to install the controller inside the cluster, in this opportunity is used helm with the provider of terraform. Check the code. Aditional you need to create a service account with least privileges permissions, in this case our   controller is for ec2, with a policy of ec2 is enough and the name of namespace.

```
module "ack-role-for-service-accounts-eks" {

  source  = "terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts-eks"
  version = "5.39.1"

  role_name        = local.workspace["role_name"]
  role_policy_arns = local.workspace["role_policy_arns"]

  oidc_providers = local.workspace["oidc_providers"]

  tags = merge(
    var.required_tags,
    local.workspace["tags"]
  )
}

```
```
      role_policy_arns = {
        policy = "arn:aws:iam::aws:policy/AmazonEC2FullAccess"
      }

      oidc_providers = {
        ex = {
          provider_arn               = var.oidc_provider_arn
          namespace_service_accounts = ["ack-system:ack-ec2-controller"]
        }
      }

```
## Step 3.
With the service account created, It is time to deploy the controller, in this case an ec2 controller. 

```
module "eks-blueprints-addons" {
  source  = "aws-ia/eks-blueprints-addons/aws"
  version = "1.16.2"

  cluster_name      = local.workspace["cluster_name"]
  cluster_endpoint  = local.workspace["cluster_endpoint"]
  cluster_version   = local.workspace["cluster_version"]
  oidc_provider_arn = local.workspace["oidc_provider_arn"]
  helm_releases     = local.workspace["helm_releases"]
}
```
```
      helm_releases = {
        ec2-controller= {
          name                = "ec2-controller"
          description         = "A Helm chart for ack ec2-controller"
          repository_username = data.aws_ecrpublic_authorization_token.token.user_name
          repository_password = data.aws_ecrpublic_authorization_token.token.password
          namespace           = "ack-system"
          chart_version       = "1.2.12"
          chart               = "ec2-chart"
          create_namespace    = true
          repository          = "oci://public.ecr.aws/aws-controllers-k8s"
          values = [templatefile("./helm-charts/ack_ec2_controller/values.yaml", {
            role-arn = var.role_arn_controller
            region   = "us-east-1"
          })]
        }
      }
```

## Step 4.
Validating controller.

![ack ec2 controller](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jdkpszkidd1jl8a0jaqp.png)

> remember that this controller have permissions all this resources, not only ec2 instances. :D

![ack ec2 controller crd](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/awucuqn2z8b4qzt1hrtj.png)


## Step 5.
With the controller running without problems, now it is possible to create resources. For that there is the following raw manifest.

```
apiVersion: ec2.services.k8s.aws/v1alpha1
kind: Instance
metadata:
  name: segoja7-ack
spec:
  imageID: ami-023c11a32b0207432
  instanceType: t3.micro
  subnetID: subnet-0365ed0ebddcdb2a0
  tags:
    - key: ManagedBy
      value: ec2-controller
    - key: Name
      value: segoja7-ack
```

![ack ec2 controller deployment](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0p00co1vs3cysd1gpjcc.gif)


![ec2 console](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8s0s0wn5xiiatvizb25s.png)


Conclusion: In this demo, It is demonstrated how to deploy an ack controller, in this case for ec2 service, create a role with permissions for the service account and deploy the resource from eks. 

Thanks for reading this post, let me know if you have any question or comment.