# Installing a connector on EKS Using Terraform

> 📘 You have chosen the advanced installation method
>
> You can also easily connect AWS in Apono following this UI guide [here](/docs/aws-environment/apono-connector-for-aws.md)

## How to install the Connector on EKS Using Terraform

### Prerequisites

* Required CLI: `terraform`

### Step 1 - Create Connector

* Login to Apono and create connector in the [Connector Page](https://app.apono.io/connectors)

Important: before you start, copy the connector Terraform params and export them in the terminal.

### Step 2 - Configure Variables

```
variable "eks_cluster_name" {
  type    = string
  default = "PLEASE_REPLACE_WITH_CLUSTER_NAME"
}

variable "CONNECTOR_ID" {
  type    = string
  description = "Apono Connector ID"
}

variable "APONO_TOKEN" {
  type    = string
  description = "Apono authoriozatrion token"
  sensitive = true
}

variable "APONO_WEBSOCKET_URL" {
  type    = string
  description = "Apono websocket URL"
}

variable "aws_region" {
  type    = string
  default = "us-east-1"
}

variable "service_account_name" {
  type    = string
  default = "apono"
}

variable "namespace" {
  type    = string
  default = "apono"
}

```

### Step 3 - Add necessary Terraform providers

\*\* if you already use your own providers, you can skip this step

```
provider "aws" {
  alias  = "apono"
  region = var.aws_region
}

data "aws_eks_cluster" "cluster" {
  name     = var.eks_cluster_name
}

data "aws_eks_cluster_auth" "eks_cluster_auth" {
  name     = var.eks_cluster_name
}

data "aws_caller_identity" "aws_account" {
}

locals {
  aws_account_id = data.aws_caller_identity.aws_account.account_id
  oidc_provider = replace(data.aws_eks_cluster.cluster.identity[0].oidc[0].issuer, "https://", "")
  config_path = "~/.kube/config"
  config_context = "my-context" 
}

provider "kubernetes" {
  config_path = local.config_path
  config_context = local.config_context
}

provider "helm" {
  kubernetes {
    config_path = local.config_path
    config_context = local.config_context
  }
}
```

Run `terraform init` to validate it works

### Step 4 - Add EKS cluster OIDC provider to your IAM

**It's required that your EKS cluster OIDC provider will be added to your IAM.**\
\&#xNAN;*This step is required only once, and you may have already done it.*

```
data "aws_eks_cluster" "eks_cluster" {
  name = var.eks_cluster_name
}

data "tls_certificate" "tls_cert" {
  url = data.aws_eks_cluster.eks_cluster.identity[0].oidc[0].issuer
}

resource "aws_iam_openid_connect_provider" "eks-oidc-provider" {
  client_id_list  = ["sts.amazonaws.com"]
  thumbprint_list = [data.tls_certificate.tls_cert.certificates[0].sha1_fingerprint]
  url             = data.aws_eks_cluster.eks_cluster.identity[0].oidc[0].issuer
}
```

### Step 5 - Create the Connector IAM role

The Connector is deployed using helm and requires an IAM Role to be able to access tagged ASM secrets in the future.

```
// IAM role and access policy for apono tagged secrets
resource "aws_iam_role" "apono-connector" {
  name     = "${var.service_account_name}-${var.CONNECTOR_ID}"

  assume_role_policy = jsonencode({
    "Version" : "2012-10-17",
    "Statement" : [
      {
        "Effect" : "Allow",
        "Principal" : { "Federated" : "arn:aws:iam::${local.aws_account_id}:oidc-provider/${local.oidc_provider}" },
        "Action" : "sts:AssumeRoleWithWebIdentity",
        "Condition" : {
          "StringEquals" : { "${local.oidc_provider}:sub" : "system:serviceaccount:${var.namespace}:${var.service_account_name}" }
        }
      }
    ]
  })
  
  inline_policy {
    name = "apono-tagged-keys-access-policy"

    policy = jsonencode({
      Version = "2012-10-17"
      Statement = [
        {
          Effect = "Allow"
          Action = [ "kms:Sign" ]
          Resource = "*"
          Condition = { "StringEquals": {"aws:ResourceTag/apono-connector-read": "true"} }
        },
      ]
    })
  }
  
  inline_policy {
    name = "apono-tagged-secrets-access-policy"

    policy = jsonencode({
      Version = "2012-10-17"
      Statement = [
        {
          Effect = "Allow"
          Action = [ "secretsmanager:GetSecretValue", "secretsmanager:DescribeSecret"]
          Resource = "arn:aws:secretsmanager:*:${local.aws_account_id}:secret:*"
          Condition = { "StringEquals": {"aws:ResourceTag/apono-connector-read": "true"} }
        },
      ]
    })
  }

  // for IAM Managment
  inline_policy {
    name = "iam-access-policy"
    policy = jsonencode({
      Version = "2012-10-17"
      Statement = [
        {
            Effect = "Allow"
            Action = [
                "iam:ListPolicies",
                "iam:CreateInstanceProfile",
                "iam:ListGroups",
                "iam:ListInstanceProfiles"
            ],
            Resource = "*"
        },
        {
            Effect = "Allow"
            Action = [
                "iam:CreateInstanceProfile",
                "iam:GetRole",
                "iam:UpdateAssumeRolePolicy",
                "iam:ListRoleTags",
                "iam:TagRole",
                "iam:CreateRole",
                "iam:DeleteRole",
                "iam:AttachRolePolicy",
                "iam:PutRolePolicy",
                "iam:AddRoleToInstanceProfile",
                "iam:ListInstanceProfilesForRole",
                "iam:DetachRolePolicy",
                "iam:ListAttachedRolePolicies",
                "iam:DeleteRolePolicy",
                "iam:ListAttachedGroupPolicies",
                "iam:ListRolePolicies",
                "iam:GetRolePolicy",
                "iam:PassRole",
                "iam:GetInstanceProfile",
                "iam:CreateUser",
                "iam:CreateAccessKey",
                "iam:DeleteAccessKey",
                "iam:PutUserPolicy",
                "iam:DeleteUserPolicy",
                "iam:GetUser",
                "iam:GetUserPolicy",
                "iam:ListAttachedUserPolicies",
                "iam:ListUserPolicies",
                "iam:UpdateLoginProfile",
                "iam:ListAccessKeys",
                "iam:AttachUserPolicy",
                "iam:DetachUserPolicy",
                "iam:CreateLoginProfile"
            ]
            Resource = [
                "arn:aws:iam::*:instance-profile/*",
                "arn:aws:iam::*:role/*",
                "arn:aws:iam::*:group/*",
                "arn:aws:iam::*:user/*"
            ]
        }
      ]
    })
  }
  
  inline_policy {
    name = "ec2-policy"
    policy = jsonencode({
      Version = "2012-10-17"
      Statement = [{
        "Effect": "Allow",
        "Action": [ "ec2:DescribeInstances","ec2:DescribeTags","ec2:AssociateIamInstanceProfile" ],
        "Resource": "*"
      }]
    })
  }
}

data "aws_iam_policy" "SecurityAudit" {
  arn = "arn:aws:iam::aws:policy/SecurityAudit"
}

resource "aws_iam_role_policy_attachment" "connector-security-audit" {
  role       = "${aws_iam_role.apono-connector.name}"
  policy_arn = "${data.aws_iam_policy.SecurityAudit.arn}"
}

```

### Step 6 - Deploy Apono Connector

```
locals {
  connector_helm_repo = "https://apono-io.github.io/apono-helm-charts/"
  connector_helm_chart = "apono-connector"
  connector_helm_chart_version = "<<helmVersion>>"
}

// agent deployment
resource "kubernetes_namespace_v1" "apono-namespace" {
  metadata {
    name = var.namespace
  }
}

resource "helm_release" "apono-connector" {
  name             = "apono-connector"
  repository       = local.connector_helm_repo
  chart            = local.connector_helm_chart
  version          = local.connector_helm_chart_version
  namespace        = kubernetes_namespace_v1.apono-namespace.metadata[0].name


  set {
    name = "serviceAccount.name"
    value = var.service_account_name
  }
  
  set {
    name = "serviceAccount.awsRoleAccountId"
    value = local.aws_account_id
  }
  
  set {
    name = "serviceAccount.awsRoleName"
    value = "${var.service_account_name}-${var.CONNECTOR_ID}"
  }

  set {
    name = "image.tag"
    value = "<<connectorVersion>>"
  }

  set {
    name  = "apono.token"
    value = var.APONO_TOKEN
  }

  set {
    name  = "apono.url"
    value = var.APONO_WEBSOCKET_URL
  }

  set {
    name  = "apono.connectorId"
    value = var.CONNECTOR_ID
  }
}


```

### Validate the Connector is Connected

You can validate the Connector is installed in the [Connector status page](https://app.apono.io/connectors).


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.apono.io/docs/aws-environment/apono-connector-for-aws/installing-a-connector-on-eks-using-terraform.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
