Convey the relationships between your in-cluster resources and other Arpio-supported AWS resources
Overview
By default, Arpio will dynamically inventory and backup the resources within your Kubernetes clusters. Upon restore, Arpio also attempts to translate these resources and their dependencies accurately. However, due to the dynamic nature of Kubernetes, Arpio sometimes needs some additional direction to accurately interpret the resource identifiers in your cluster’s configuration. For this reason, Arpio allows customers to create custom ConfigMaps to add directly to their clusters, which enable Arpio to translate resources more precisely.
Background
When inventorying resources in environments, Arpio relies on unique identifiers attached to resources to correctly identify a source resource type and its dependencies and to recreate them faithfully in the recovery environment.
For many identifiers, such as VPC IDs, Subnet IDs, Security Group IDs, etc., the id numbers are regionally unique and thus are easier to find and replace as necessary in order to rebuild the infrastructure elsewhere.
On the other hand, some identifiers, such as IAM Role Names, are not unique to a region within an account. Sometimes these kinds of identifiers are reused with nothing to identify the resource type in the configuration. This can lead Arpio to misinterpret the resource type upon cluster restore.
Because of the potential for overlapping names across resource types, we’ve implemented this hinting system to allow cluster configuration to explicitly convey to Arpio resource types. This allows us to find the relationships between your in-cluster resources and other, Arpio supported, AWS resources.
Creating a Custom ConfigMap
For all EKS clusters, Arpio applies a default set of rules to translate your cluster resources. Those rules are published at https://api.arpio.io/api/info/eks/baseTranslationConfig.json | https://api.arpio.io/api/info/eks/baseTranslationConfig.yaml.
In addition to Arpio’s default rules, customers can add their own customized translation rules by creating their own ConfigMaps. To do this, you’ll follow the format described below to create a new ConfigMap with custom resource definitions.
Once complete, a customized Arpio ConfigMap can be added to the source cluster. It should be named arpio-resource-map
.
Each map is placed in a yaml file in the configMap’s data object under the key override
.
The map installed into the kube-system
namespace is considered the default addition/override set for your entire cluster. Any maps installed into other namespaces will only affect that namespace. This allows delegation of responsibilities to those in control of that particular namespace.
Creating Resource Definitions
Each resource definition in your ConfigMap has 3 major pieces:
- The name
- A source object
- A list of target objects.
For example:
containerEnvVars:
source:
k8sTypes:
- CronJob
- DaemonSet
- Deployment
- Job
- Pod
- StatefulSet
paths:
-
$..spec.containers,initContainers,ephemeralContainers[*].env[*].value
targets:
- awsType: AWS::EC2::VPC
field: VpcId
- field: Id
type: AWS::Region
- awsType: AWS::ECR::Repository
field: repositoryUri
matcher: substring
- awsType: AWS::IAM::Role
field: _arn_
- awsType: '*'
field: _arn_
This definition - named containerEnvVars
- picks up and translates: VPC Ids, Region names, ECR Repository substrings, IAM Role ARNs, and any other full ARN in the value entry of environment maps for container, initContainer, and ephemeralContainer specs and template specs in CronJob, DaemonSet, Deployment, Job, Pod, and StatefulSet kinds. The template specs are implicit here by the jsonpath syntax in source.paths
.
Most definitions will only have a single target as you’ll want to limit the ability for it to be picked up as the wrong thing. One might think the AWS::Region
match would also catch a part of the AWS::ECR::Repository.repositoryUri
, but each of these matches is required to be the full string of that leaf node in the data structure, unless the matcher is set to something like substring or csv.
Definition Names
Defining a map of the same name as one of Arpio’s defaults will override that resource map at the top level. This means that you will need to reiterate every part of the default resource map you want to retain in your ConfigMap, and leave out just the portion you do not wish to use. See the full example below for a reference.
Source Objects
The source object has 4 keys: k8sTypes, paths, filePath, and fileType. Basic entries will just require the first two. The file* keys are optional, but if one is specified, the other is required.
k8sTypes: list of k8s kinds to match this definition against
paths: list of jsonpath-like paths to locate the targets in
filePath: jsonpath location of a file inside this resource
fileType: one of YAML
or YAML.b64
with the latter being a base64 encoded YAML file
Target Objects
The target objects have N keys: awsType, type, field, and matcher. Only one of awsType or type is allowed and matcher is optional - defaulting to a full string match.
awsType: These will mostly align with the Resource Type Value in this page. Arpio maintains a list of supported awsConfigTypes in our API.
type: Some base-level AWS identifiers don’t have associated AWS::Config designations. For those, we use similarly formatted entries that are forced outside the namespace. AWS::Region
, AWS::ECR::HostedRepository
, AWS::AvailabilityZone
, and AWS::Account
are the currently supported types here.
field: If type is used, this should be Id
, otherwise, it’s a jsonpath inside the AWS/boto description of that particular resource or the special value _arn_
which is the full ARN of the resource. For example, if you want to translate a security group id, the groupId field name would be the field value.
matcher: csv
or substring
. Some fields will contain a list of comma separated ARNs, subnet IDs, or security group IDs. In those cases, using csv will allow Arpio to split it up on those commas and rebuild it back into a csv. Substring matches are useful for finding things like AWS::Regions inside other strings, or more commonly, ECR repository URIs as only part of the image definitions in workload specs.
Custom Type Definitions:
AWS::Account
12 digit AWS Account id numbers
AWS::AvailabilityZone
The lowercase availability zone names - useful for EBS volume attachments, etc.
AWS::Region
The lowercase instances of the region IDs.
AWS::ECR::HostedRepository
AWS hosts some ECR Repos across regions, but they end up being in different accounts, and obviously with different region IDs embedded in them. This allows Arpio to translate those hosted ECR repositories into the one local to your target region.
A full working ConfigMap example:
kind: ConfigMap
apiVersion: v1
metadata:
name: arpio-resource-map
namespace: kube-system
data:
override: |
argoRolloutEcr:
source:
k8sTypes:
- Rollout
paths:
- $.spec.template.spec.containers[*].image
targets:
- awsType: AWS::ECR::Repository
field: repositoryUri
matcher: substring
karpenterNodeClassAcct:
source:
k8sTypes:
- Ec2NodeClass-disabled
paths:
- spec.amiSelectorTerms[*].owner-disabled
targets:
- field: Id
type: AWS::Account
This example has two definitions in it. The first one translates the image identifiers for Argo CD Rollouts, and the second overwrites the default karpenterNodeClassAcct
translation but makes it such that it won’t match either the Kind or the path in the Ec2NodeClass resources.