Adopting Existing AWS Resources
Adopting existing AWS resources that were created using other tools
The ACK controllers are intended to manage the complete lifecycle of an AWS
resource, from creation through deletion. However, you may already be
managing those resources using other tools - such as CloudFormation or
Terraform. Migrating to ACK could be time-consuming to redeclare all resources
as YAML, or even cause you to lose the state of the application if parts of the
system are recreated. The ACK AdoptedResource
custom resource was designed to
help migrate these AWS resources to be managed by an ACK controller in your Kubernetes
cluster without having to define the full YAML spec or needing to delete and
re-create the resource.
To adopt an AWS resource, create an AdoptedResource
custom
resource that specifies the unique identifier for the AWS resource and a target
K8s object. After applying this custom resource to the cluster, the ACK
controller will describe the AWS resource and create the associated ACK resource
inside the cluster - with a complete spec and status. The ACK controller will
then treat the newly-created ACK resource like any other.
All ACK controllers ship with the same AdoptedResource
CRD. Every controller
contains the logic for adopting resources from its particular service. That is,
the S3 controller understands how to adopt all S3 resources. If you don’t have a
particular service controller installed, and try to adopt a resource from that
service, the AdoptedResource
CR will have no effect.
Spec
The full spec for the AdoptedResource
CRD is located in the API
reference. The spec contains two parts: the AWS resource reference and
the Kubernetes target.
AWS Resource
The AWS resource reference requires the unique identifier for the object, either
as an ARN or as the name or ID of the object. Which of these is required depends
on the service and the particular resource.
You can find which field is required
by finding the unique identifier field used by the Describe*
, List*
, or Get*
API
calls for that resource.
If we were adopting for an IAM Role, since the IAM Get Role API call requires RoleName
, you should set .spec.aws.nameOrId
to the name of the role you would like to adopt.
If we were adopting for an IAM Policy, since the IAM Get Policy API call requires PolicyArn
, you should set .spec.aws.arn
to the ARN of the policy you would like to adopt.
Kubernetes Target
The Kubernetes target requires the group
and kind
- these identify from
which service and resource you wish to adopt. For example, to adopt an S3
bucket, you would specify a group
of s3.services.k8s.aws
and a kind
of
Bucket
. The Kubernetes target also allows you to override the metadata
for
the object that is created. By default, all resources created through an
AdoptedResource
will have the same metadata.name
as the AdoptedResource
that created it.
Example
Below is an example of adopting an S3 bucket, overriding the name and namespace of the target K8s object and adding a label.
apiVersion: services.k8s.aws/v1alpha1
kind: AdoptedResource
metadata:
name: adopt-my-existing-bucket
spec:
aws:
nameOrID: example-bucket
kubernetes:
group: s3.services.k8s.aws
kind: Bucket
metadata:
name: my-existing-bucket
namespace: default
labels:
app: foo
Additional Keys
Some AWS resources cannot be defined using only a single unique identifier. For
APIs where we need to provide multiple identifiers, the AdoptedResource
spec
contains a field called aws.additionalKeys
which allows for any number of
arbitrary key-value pairs required to define the multiple identifier keys. When
adopting a resource with multiple identifiers, provide the most specific
identifier in the nameOrID
field. Then for each additional identifier, set the
name of the key in additionalKeys
to be the name in the ACK spec or status for
that field, and the value to be the actual identifier value.
For example, the Integration
resource in AWS API Gateway
V2 is uniquely identified by both an integrationID
and an apiID
. The API
requires both of these features to describe an integration. In
this case, we would provide the integrationID
for the nameOrID
field - since
it is unique for every API Gateway v2 API
object. Then to provide the apiID
,
we add a key of apiID
in the additionalKeys
and the value as the API ID for
the resource we want to adopt. The full spec of the AdoptedResource
would look
like the following:
apiVersion: services.k8s.aws/v1alpha1
kind: AdoptedResource
metadata:
name: adopt-my-existing-integration
spec:
aws:
nameOrID: integration-id-123456789012
additionalKeys:
apiID: api-id-123456789012
kubernetes:
group: apigatewayv2.services.k8s.aws
kind: Integration