Skip to main content

Self Hosted Installation on AWS EKS

Prerequisites

To install and run a self-hosted Mission Control on AWS EKS you need to have the following prerequisites:

  • EKS 1.28+ with an Ingress Controller
  • 500m - 2000m of CPU and 6 - 8GB of Memory (2 - 4GB if using an external DB)
  • Persistent Volumes with 20GB+ of storage or an external postgres database like RDS
  • Access to create
  • (Optional) SMTP Server (For sending notifications and invites)

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
    namespace: mission-control
    spec:
    chart:
    spec:
    chart: mission-control
    sourceRef:
    kind: HelmRepository
    name: flanksource
    namespace: mission-control
    interval: 5m
    values:
    global.ui.host: DOMAIN
    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

aws-kms-connection.yaml
apiVersion: mission-control.flanksource.com/v1
kind: Connection
metadata:
name: aws-kms
namespace: mission-control
spec:
aws:
region: us-west-2
# Use the same authentication method as your main AWS connection
awsKms:
keyID: alias/mission-control-secrets

Update Mission Control Helm Chart

helm upgrade mission-control flanksource/mission-control \
--set kmsConnection='connection://mission-control/aws-kms' \
-n mission-control \
--wait

Next Steps