Skip to main content

Install Mission Control Agent on an AWS EKS cluster

Prerequisites

To install and run Mission Control you need to have the following prerequisites:

  • EKS 1.28+ with an Ingress Controller
  • 500-1000m of CPU and 4GB of Memory
  • Persistent Volumes with 20GB+ of storage or an external postgres database like RDS

Create an IAM Role​

Depending on how you want to use Mission Control you need to create an IAM role for mission control to use:

Use CaseRole
Read Only Scrapingarn:aws:iam::aws:policy/ReadOnlyAccess
Playbooks to create and update AWS Resourcesarn:aws:iam::aws:policy/PowerUserAccess
Secret Management (optional)Custom KMS policy (see below)
Create new IAM Policy (Alternative)

You can also create a new policy with only the permissions required by Mission Control

iam-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "mission-control-config-role",
"Effect": "Allow",
"Action": [
"acm:Describe*",
"acm:Get*",
"acm:List*",
"cloudtrail:LookupEvents",
"config:BatchGetAggregateResourceConfig",
"config:BatchGetResourceConfig",
"config:Describe*",
"config:Get*",
"config:List*",
"config:SelectAggregateResourceConfig",
"config:SelectResourceConfig",
"ec2:Describe*",
"ecr:Describe*",
"eks:Describe*",
"eks:ListClusters",
"elasticfilesystem:Describe*",
"elasticloadbalancing:Describe*",
"guardduty:Describe*",
"guardduty:Get*",
"guardduty:List*",
"iam:GetAccountName",
"iam:GetAccountSummary",
"iam:GetGroup",
"iam:GetGroupPolicy",
"iam:GetInstanceProfile",
"iam:GetLoginProfile",
"iam:GetPolicy",
"iam:GetRole",
"iam:GetRolePolicy",
"iam:GetUser",
"iam:List*",
"lambda:List*",
"rds:Describe*",
"sts:GetCallerIdentity"
"trustedadvisor:Describe*",
"trustedadvisor:DownloadRisk",
"trustedadvisor:Get*",
"trustedadvisor:List*",
],
"Resource": "*"
}
]
}

Configure IAM Roles for Mission Control​

  1. Ensure the AWS Pod Identity Agent is configured and running

  2. Create a mapping file for eksctl

    eksctl.yaml
    podIdentityAssociations:
    - namespace: mission-control
    serviceAccountName: mission-control-sa
    permissionPolicyARNs:
    # Add additional policies as needed:
    # - arn:aws:iam::aws:policy/PowerUserAccess
    # - Custom KMS policy ARN for secret management
    - arn:aws:iam::aws:policy/ReadOnlyAccess

    - namespace: mission-control
    serviceAccountName: config-db-sa
    permissionPolicyARNs:
    # Add additional policies as needed:
    # - arn:aws:iam::aws:policy/PowerUserAccess
    # - Custom KMS policy ARN for secret management
    - arn:aws:iam::aws:policy/ReadOnlyAccess

    - namespace: mission-control
    serviceAccountName: canary-checker-sa
    permissionPolicyARNs:
    # Add additional policies as needed:
    # - arn:aws:iam::aws:policy/PowerUserAccess
    # - Custom KMS policy ARN for secret management
    - arn:aws:iam::aws:policy/ReadOnlyAccess
    iam:
    # note withOIDC is not required for Pod Identity
    serviceAccounts:
    # used by mission control for notifications / playbooks
    - metadata:
    name: mission-control-sa
    namespace: mission-control
    attachPolicyARNs:
    # Add additional policies as needed:
    # - "arn:aws:iam::aws:policy/PowerUserAccess"
    # - Custom KMS policy ARN for secret management
    - "arn:aws:iam::aws:policy/ReadOnlyAccess"
    # used for cloudwatch, S3 and other AWS health checks
    - metadata:
    name: canary-checker-sa
    namespace: mission-control
    attachPolicyARNs:
    # Add additional policies as needed:
    # - "arn:aws:iam::aws:policy/PowerUserAccess"
    # - Custom KMS policy ARN for secret management
    - "arn:aws:iam::aws:policy/ReadOnlyAccess"
    # used to scrape resources, AWS CloudTrail and AWS Cost & Usage Reports
    - metadata:
    name: config-db-sa
    namespace: mission-control
    attachPolicyARNs:
    # Add additional policies as needed:
    # - "arn:aws:iam::aws:policy/PowerUserAccess"
    # - Custom KMS policy ARN for secret management
    - "arn:aws:iam::aws:policy/ReadOnlyAccess"

    Using an existing IAM Role

    If you are using a pre-existing IAM role when creating a pod identity association, you must configure the role to trust the newly introduced EKS service principal (pods.eks.amazonaws.com)

    iam-trust-policy.json
    {
    "Version": "2012-10-17",
    "Statement": [
    {
    "Effect": "Allow",
    "Principal": {
    "Service": "pods.eks.amazonaws.com"
    },
    "Action": ["sts:AssumeRole", "sts:TagSession"]
    }
    ]
    }
  3. Apply the Pod Identities using eksctl

    eksctl create podidentityassociation -c eksctl.yaml

  4. Choose a routable DOMAIN for Mission Control

    See Ingress for more options on configuring the ingress including generating certs with cert-manager

    See Local Testing for testing using a kind or minikube without a routable domain

  5. Install Mission Control

    apiVersion: v1
    kind: Namespace
    metadata:
    name: mission-control
    ---
    apiVersion: source.toolkit.fluxcd.io/v1
    kind: HelmRepository
    metadata:
    name: flanksource
    namespace: mission-control
    spec:
    interval: 5m0s
    url: https://flanksource.github.io/charts
    ---
    apiVersion: helm.toolkit.fluxcd.io/v2
    kind: HelmRelease
    metadata:
    name: mission-control-agent
    namespace: mission-control
    spec:
    chart:
    spec:
    chart: mission-control-agent
    sourceRef:
    kind: HelmRepository
    name: flanksource
    namespace: mission-control
    interval: 5m
    values:
    upstream.agent: YOUR_LOCAL_NAME
    upstream.username: token
    upstream.password:
    upstream.host:
    See values.yaml

Optional: KMS Setup for Secret Management​

If you plan to use secret parameters in playbooks, create a KMS key and IAM policy to encrypt and manage sensitive data:

Create a KMS Key​

# Set your AWS region and account ID
export AWS_REGION=us-west-2
export ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)

# Create a KMS key for Mission Control
aws kms create-key \
--description "Mission Control Secret Management Key" \
--region $AWS_REGION \
--query 'KeyMetadata.KeyId' \
--output text > mission-control-key-id.txt

export KEY_ID=$(cat mission-control-key-id.txt)

# Create an alias for easier reference
aws kms create-alias \
--alias-name alias/mission-control-secrets \
--target-key-id $KEY_ID \
--region $AWS_REGION

Create KMS IAM Policy​

# Create a custom KMS policy
cat > mission-control-kms-policy.json << EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "MissionControlKMSAccess",
"Effect": "Allow",
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey"
],
"Resource": "arn:aws:kms:${AWS_REGION}:${ACCOUNT_ID}:key/${KEY_ID}"
}
]
}
EOF

# Create the IAM policy
aws iam create-policy \
--policy-name MissionControlKMSPolicy \
--policy-document file://mission-control-kms-policy.json \
--query 'Policy.Arn' \
--output text > mission-control-kms-policy-arn.txt

export KMS_POLICY_ARN=$(cat mission-control-kms-policy-arn.txt)

After creating the key and policy, make sure to include the KMS policy ARN in your service account configurations above.

Create a Mission Control Connection​

awskms.yaml
---
# yaml-language-server: $schema=../../config/schemas/connection.schema.json
apiVersion: mission-control.flanksource.com/v1
kind: Connection
metadata:
name: flanksource-awskms
spec:
awskms:
keyID: arn:aws:kms:eu-west-1:123123123123:alias/sops-key
region: eu-west-1
accessKey:
valueFrom:
secretKeyRef:
name: aws-flanksource
key: AWS_ACCESS_KEY_ID
secretKey:
valueFrom:
secretKeyRef:
name: aws-flanksource
key: AWS_SECRET_ACCESS_KEY

Update Mission Control Helm Values​

Set kmsConnection to the KMS connection reference used by your installation:

apiVersion: v1
kind: Namespace
metadata:
name: mission-control
---
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
name: flanksource
namespace: mission-control
spec:
interval: 5m0s
url: https://flanksource.github.io/charts
---
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: mission-control-agent
namespace: mission-control
spec:
chart:
spec:
chart: mission-control-agent
sourceRef:
kind: HelmRepository
name: flanksource
namespace: mission-control
interval: 5m
values:
upstream.agent: YOUR_LOCAL_NAME
upstream.username: token
upstream.password:
upstream.host:
kmsConnection: "connection://<namespace>/<kms-connection-name>"

See values.yaml

Next Steps​