Setup inCloud Managed with AWS
inCloud Managed is one of our setup options, which install our platform's infrastructure in a cloud environment owned by your organization, allowing you to delegate its entire setup, update, and maintenance to groundcover.
Note: inCloud Managed is available exclusively to Enterprise users.
inCloud Managed requires to create an isolated account within your AWS organization, that will be managed by groundcover's control plane and will establish, configure, and maintain the infrastructure and workloads within the account. These include AWS VPC, S3, EKS, LB, etc.
To complete the installation of inCloud Managed (total estimated time: 1 hour) you will need to follow these steps, all of which are detailed in the guide that follows:

Step 0: Create a workspace
If you've previously set up a workspace with groundcover, skip this step
Follow the steps in the link below to signup and create a workspace in groundcover:
Step 1: Allocate an AWS account to groundcover
groundcover inCloud Managed can be deployed using one the following configurations:
Option A: Creating a new, dedicated sub-account
We recommend naming the account [groundcover-incloud] and placing the account in OU=Infrastructure/OU=Managed. For additional information please see Establishing your best practice AWS environment (external link to a page on the AWS website).
Option B: Use an existing AWS account
If you prefer using a single account approach, inCloud Managed can also be deployed into an existing account, running alongside existing production workloads in your existing AWS account. To limit access and prevent resource collusion, we implement a “scoping territory” approach using ABAC tags for access control and VPC subnets for network control.
Choose your telemetry delivery method
By default, groundcover inCloud Managed deploys as a SaaS solution using ZTNA public, allowing you to deliver telemetry data securely over the public internet.
Prefer private networking is supported with Private Link.
Step 2: Ask for your External ID
Users on an Enterprise plan (prerequisite for inCloud Managed) have access to a private support channel on Slack for their organization. Use that channel to let us know that you're ready to get started with the inCloud Managed setup and ask for your External ID. The groundcover team will share your External ID with you.
Step 3: Setup a cross-account IAM role
To grant our control-plane access to the account, we use AWS’s built-in access federation feature.
The following guide will walk you through the steps required to setup this access.
We create the role and managed policies to adhere to security best practices (external link to Wikipedia) by limiting access on IAM, EC2 and related services to the bare minimum required for control plane operations including: health monitoring, security patches, auto scaling and version updates.
For quick integration, we recommend using our CloudFormation template to deploy the groundcover role inside the new account. Click here for the CloudFormation template.
Make sure to enter the external ID provided by groundcover.
The following snippet does the following:
- Create the managed policies to be used by the role 
- Create the role 
- Assign the policies to the role 
locals {
  role_name       = "groundcover-managed"
  external_id     = "<external-id>"
  policy_version  = "2.4.13"
  policy_base_url = "https://groundcover-public-cloudformation-templates.s3.us-east-1.amazonaws.com/groundcover-managed-role/policies"
}
# Fetch policies from S3
data "http" "readonly_monitoring_policy" {
  url = "${local.policy_base_url}/managed-policy-${local.policy_version}-readonly-monitoring.json"
  request_headers = {
    Accept = "application/json"
  }
}
data "http" "core_infrastructure_policy" {
  url = "${local.policy_base_url}/managed-policy-${local.policy_version}-core-infrastructure.json"
  request_headers = {
    Accept = "application/json"
  }
}
data "http" "advanced_services_policy" {
  url = "${local.policy_base_url}/managed-policy-${local.policy_version}-advanced-services.json"
  request_headers = {
    Accept = "application/json"
  }
}
# Read-only monitoring managed policy
resource "aws_iam_policy" "groundcover_readonly_monitoring" {
  name        = "${local.role_name}-readonly-monitoring-${local.policy_version}"
  description = "groundcover managed policy for read-only and monitoring operations"
  policy = data.http.readonly_monitoring_policy.response_body
}
# Core infrastructure managed policy
resource "aws_iam_policy" "groundcover_core_infrastructure" {
  name        = "${local.role_name}-core-infrastructure-${local.policy_version}"
  description = "groundcover managed policy for core infrastructure and EKS management"
  policy = data.http.core_infrastructure_policy.response_body
}
# Advanced services managed policy
resource "aws_iam_policy" "groundcover_advanced_services" {
  name        = "${local.role_name}-advanced-services-${local.policy_version}"
  description = "groundcover managed policy for advanced AWS services and features"
  policy = data.http.advanced_services_policy.response_body
}
# IAM role with assume role policy
resource "aws_iam_role" "groundcover_role" {
  name = local.role_name
  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect = "Allow"
        Principal = {
          AWS = "arn:aws:iam::991078109329:role/control-plane"
        }
        Action = "sts:AssumeRole"
        Condition = {
          StringEquals = {
            "sts:ExternalId" = local.external_id
          }
        }
      }
    ]
  })
}
# Attach the managed policies to the role
resource "aws_iam_role_policy_attachment" "readonly_monitoring" {
  role       = aws_iam_role.groundcover_role.name
  policy_arn = aws_iam_policy.groundcover_readonly_monitoring.arn
}
resource "aws_iam_role_policy_attachment" "core_infrastructure" {
  role       = aws_iam_role.groundcover_role.name
  policy_arn = aws_iam_policy.groundcover_core_infrastructure.arn
}
resource "aws_iam_role_policy_attachment" "advanced_services" {
  role       = aws_iam_role.groundcover_role.name
  policy_arn = aws_iam_policy.groundcover_advanced_services.arn
}
This method is not recommended - we strongly sugest using either CloudFormation or Terraform to provision the role
Create a Role:
- Log in as a privileged user to the AWS account chosen in Step 1. 
- Navigate to IAM -> Roles 
- Click “Create role” 

Select trusted entity:
- Trusted entity type: Select “AWS Account” 
- An AWS account: Check "Another AWS account"; Account ID: 991078109329 
- Options: Check "Require external ID" and enter your External ID (see Step 1) 
- Make sure “Require MFA” is unchecked 
- Click "Next" 
- In the following screen, do not attach any managed permissions 
- Click "Next" 

Name, review, and create:
Fill in the following details:
- Role name: Type - groundcover-managed
- Description: Optional field, your can write any free text description that can be helpful for you and others to understand this purpose of this role in the future (e.g. “app.groundcover.com control plane access”) 
- Tags: Type - groundcover:access = read. You can also use specify additional workflow-oriented tags
Click "Create role"

Trust relationships:
Search for the newly created groundcover-managed role (or scroll down the list until you find it) and click on it.

Navigate to the "Trust relationships" screen.

Click "Edit trust policy"

Replace the statement with the following snippet:
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::991078109329:role/control-plane"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": {
          "sts:ExternalId": "<External ID: Enter your ID (shared with you by groundcover)>"
        }
      }
    }
  ]
}Click "Update Policy"

Managed policies:
After creating the role and setting up the trust relationships, you need to create and attach three managed policies that grant groundcover the necessary permissions.
Create the Managed Policies
You will need to create three customer managed policies. Follow these steps for each policy in the links below:
Navigate to IAM Policies:
- In the AWS Management Console, go to IAM → Policies 
- Click "Create policy" 
- Select the "JSON" tab 
- Paste the policy content. 
- The recommended policy names are - groundcover-managed-<policy-name>-<version>- for example- groundcover-managed-core-infrastructure-2.4.13
Attach All Policies to the groundcover-managed Role:
Navigate to the Role:
- Go to IAM → Roles 
- Search for and click on the groundcover-managed role 
Attach the Policies:
- Click on the "Permissions" tab 
- Click "Add permissions" → "Attach policies" 
Search for and select all three policies:
- groundcover-managed-readonly-monitoring-<version>
- groundcover-managed-core-infrastructure-<version>
- groundcover-managed-advanced-services-<version>
Click "Add permissions"
Step 4: Share the ARN & region
Security of groundcover Control-Plane
groundcover Control-Plane is a secure reconciliation controller designed to manage enterprise inCloud infrastructure environments. It is compliant with ISO-27001 and SOC-2 standards.
The control plane can securely access your groundcover-incloud account by using a cross-account IAM role.
Binding Access
To establish the Trust Relationship, please share the following information with groundcover.
- Go to IAM > Roles > groundcover-managed > Trust relationships 
- Verify that the - sts:ExternalIdis as was provided by the groundcover team
- Take note of your ARN, which you will need to share with the groundcover team using our shared Slack channel. 
Example:

Step 5: Get installation values
After you share the ARN & Region with us, we will need to setup the backend. Once we do, we will share with you the configuration details required for you to complete Step 6 (below).
Step 6: Deploy our sensors
The final step is to deploy our sensors into the environment. In order to do so, follow this guide.
Last updated
