Skip to content
This repository was archived by the owner on Aug 7, 2025. It is now read-only.

Commit 1fe9a65

Browse files
HarshCaspercloutierMatsimonrw
authored
add docs on AWS Replicator (#1666)
Co-authored-by: Mathieu Cloutier <[email protected]> Co-authored-by: Simon Walker <[email protected]>
1 parent 90c904e commit 1fe9a65

File tree

5 files changed

+425
-0
lines changed

5 files changed

+425
-0
lines changed
Lines changed: 313 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,313 @@
1+
---
2+
title: "AWS Replicator"
3+
weight: 13
4+
description: "AWS Replicator makes it easier to use LocalStack in shared AWS environments by copying resources into LocalStack."
5+
tags: ["Teams plan"]
6+
---
7+
8+
## Introduction
9+
10+
Infrastructure deployed on AWS often requires access to shared resources defined externally.
11+
For example a VPC defined by another team to contain the application infrastructure.
12+
This makes it harder to deploy applications into LocalStack as these resource dependencies must be deployed first.
13+
These dependencies may not live in IaC where deployment is easy, or accessing the IaC may not be easy.
14+
Some resources may be referred to by ARN, for example Secrets Manager secrets, but these ARNs are partly random meaning that simply creating a new resource in LocalStack will generate a resource with a different ARN.
15+
16+
LocalStack AWS Replicator creates identical copies of AWS resources in a running LocalStack instance.
17+
This means that external resources can easily be replicated before deploying the main application, and removes the need to change existing stacks or create custom infrastructure, making LocalStack setup easier.
18+
19+
{{< callout "note">}}
20+
The AWS Replicator is in a preview state, supporting only [selected resources](#supported-resources).
21+
It is only available as part of the **LocalStack Teams** plan and higher.
22+
{{< /callout >}}
23+
24+
## Getting started
25+
26+
A valid `LOCALSTACK_AUTH_TOKEN` must be configured to start the LocalStack Pro image.
27+
28+
{{< callout "note" >}}
29+
The Replicator is in limited preview and is available from LocalStack CLI version 4.2.0.
30+
If you encounter issues, update your [LocalStack CLI](https://docs.localstack.cloud/getting-started/installation/#updating).
31+
{{< /callout >}}
32+
33+
### Retrieve credentials to access AWS
34+
35+
The AWS Replicator needs read access to your AWS account and performs a limited set of read-only operations on supported resources.
36+
These operations can be limited by creating a minimal IAM role with just the policy actions required for replication, and providing credentials to assume this role.
37+
38+
See the [supported resources section](#supported-resources) for details of what policy actions are required for each resource.
39+
40+
Replication is triggered using the LocalStack CLI, which must run in a shell configured to access AWS.
41+
If you have the aws-cli v2 installed, the cli will read credentials from your configured `AWS_PROFILE`.
42+
43+
Otherwise, the following environment variables must be set:
44+
45+
- `AWS_ACCESS_KEY_ID`
46+
- `AWS_SECRET_ACCESS_KEY`
47+
- `AWS_SESSION_TOKEN` (optional)
48+
- `AWS_DEFAULT_REGION`
49+
50+
{{< callout "tip" >}}
51+
Use `aws configure export-credentials --format env` to print the required environment variables in a format that can be evaluated.
52+
53+
{{< command >}}
54+
<disable-copy>$ </disable-copy>eval $(AWS_PROFILE=<aws-profile> aws configure export-credentials \
55+
--format env)
56+
{{< /command >}}
57+
{{< /callout >}}
58+
59+
### Trigger a replication job
60+
61+
Replication jobs can be triggered using the LocalStack CLI or an HTTP API.
62+
Both methods have two steps:
63+
64+
1. Submit a replication job.
65+
2. Check the job status.
66+
67+
#### Using the LocalStack CLI
68+
69+
The Replicator CLI is part of the LocalStack CLI.
70+
Follow the [installation instructions](https://docs.localstack.cloud/getting-started/installation/#localstack-cli) to set it up.
71+
72+
To start a replication job, get the ARN of the resource to replicate.
73+
Then, trigger the job using the command:
74+
75+
{{< command >}}
76+
export LOCALSTACK_AUTH_TOKEN=<auth token>
77+
export AWS_DEFAULT_REGION=...
78+
<disable-copy>
79+
# if required
80+
# export AWS_ACCESS_KEY_ID=
81+
# export AWS_SECRET_ACCESS_KEY=
82+
</disable-copy>
83+
localstack replicator start \
84+
--resource-type <resource-type> \
85+
--resource-identifier <identifier> \
86+
[--target-account-id <account-id>] \
87+
[--target-region-name <region-name>]
88+
{{< /command >}}
89+
90+
{{< callout "note" >}}
91+
Resources that supports replicating with arn can be replicated by providing `--resource-arn` instead of `--resource-type` and `--resource-identifier`.
92+
93+
{{< command >}}
94+
<disable-copy>$ </disable-copy>localstack replicator start --resource-arn <resource-arn>
95+
{{< /command >}}
96+
{{< /callout >}}
97+
98+
This triggers the replication job.
99+
The output will look similar to:
100+
101+
```json
102+
{
103+
"job_id": "50005865-1589-4f6d-a720-c86f5a5dd021",
104+
"state": "TESTING_CONNECTION",
105+
"error_message": null,
106+
"type": "SINGLE_RESOURCE",
107+
"replication_config": {
108+
"resource_type": "AWS::SSM::PARAMETER",
109+
"identifier": "myParameter"
110+
}
111+
}
112+
```
113+
114+
{{< callout "note" >}}
115+
- `--target-account-id` specifies the destination AWS account for replication.
116+
If not set, the resource is replicated into account `000000000000`.
117+
- `--target-region-name` specifies the destination AWS region.
118+
If not set, the resource is replicated into the default region from the provided credentials.
119+
{{< /callout >}}
120+
121+
#### Using the HTTP API
122+
123+
To trigger replication via the HTTP API, send a `POST` request to `http://localhost.localstack.cloud:4566/_localstack/replicator/jobs` with the following payload:
124+
125+
```json
126+
{
127+
"replication_type": "SINGLE_RESOURCE",
128+
"replication_job_config": {
129+
"resource_type": "<resource-type>",
130+
"identifier": "<identifier>"
131+
},
132+
"source_aws_config": {
133+
"aws_access_key_id": "...",
134+
"aws_secret_access_key": "...",
135+
"aws_session_token": "...", // optional
136+
"region_name": "...",
137+
"endpoint_url": "..." // optional
138+
},
139+
"target_aws_config": {} // optional, same shape as `source_aws_config`
140+
}
141+
```
142+
143+
### Check Replication Job Status
144+
145+
Replication jobs run asynchronously, so you need to poll their status to check when they finish.
146+
147+
#### Using the LocalStack CLI
148+
149+
When creating a replication job, the response includes a `job_id`.
150+
Use this ID to check the job status:
151+
152+
{{< command >}}
153+
$ export LOCALSTACK_AUTH_TOKEN=<auth token>
154+
155+
$ localstack replicator status <job-id>
156+
{{< /command >}}
157+
158+
This command returns the job status in JSON format, for example:
159+
160+
```json
161+
{
162+
"job_id": "50005865-1589-4f6d-a720-c86f5a5dd021",
163+
"state": "SUCCEEDED",
164+
"error_message": null,
165+
"type": "SINGLE_RESOURCE",
166+
"replication_config": {
167+
"resource_type": "AWS::SSM::PARAMETER",
168+
"identifier": "myParameter"
169+
}
170+
}
171+
```
172+
173+
For long-running jobs, the CLI can poll the status until the job reaches a terminal state.
174+
To wait for the job to finish, use the `--follow` flag.
175+
176+
#### Using the HTTP API
177+
178+
To check the status of a replication job via the HTTP API, send a `GET` request to `http://localhost.localstack.cloud:4566/_localstack/replicator/jobs/<job-id>`.
179+
180+
{{< callout "tip" >}}
181+
If the replication state is `SUCCEEDED` but the resource is missing, check in account `000000000000`.
182+
{{< /callout >}}
183+
184+
## Quickstart
185+
186+
This quickstart example creates an SSM parameter in AWS and replicates it to LocalStack.
187+
188+
To start, create the parameter in AWS.
189+
This example uses an SSO profile named `ls-sandbox` for AWS configuration, and replicates resources from the `eu-central-1` region.
190+
191+
{{< command >}}
192+
$ AWS_PROFILE=ls-sandbox aws ssm put-parameter\
193+
--name myparam \
194+
--type String \
195+
--value abc123
196+
<disable-copy>
197+
{
198+
"Version": 1,
199+
"Tier": "Standard"
200+
}
201+
</disable-copy>
202+
$ AWS_PROFILE=ls-sandbox aws ssm get-parameters --names myparam
203+
<disable-copy>
204+
{
205+
"Parameters": [
206+
{
207+
"Name": "myparam",
208+
"Type": "String",
209+
"Value": "abc123",
210+
"Version": 1,
211+
"LastModifiedDate": "2025-02-07T13:36:56.240000+00:00",
212+
"ARN": "arn:aws:ssm:eu-central-1:<account-id>:parameter/myparam",
213+
"DataType": "text"
214+
}
215+
],
216+
"InvalidParameters": []
217+
}
218+
</disable-copy>
219+
{{< /command >}}
220+
221+
The SSM parameter has the ARN: `arn:aws:ssm:eu-central-1:<account-id>:parameter/myparam`.
222+
223+
Next, we can check that the parameter is not present in LocalStack using `awslocal`:
224+
225+
{{< command >}}
226+
$ awslocal ssm get-parameters --name myparam
227+
<disable-copy>
228+
{
229+
"Parameters": [],
230+
"InvalidParameters": [
231+
"myparam"
232+
]
233+
}
234+
</disable-copy>
235+
{{< /command >}}
236+
237+
Next, trigger replication from AWS to LocalStack.
238+
This example uses an SSO profile named `ls-sandbox` for AWS configuration.
239+
240+
{{< command >}}
241+
$ LOCALSTACK_AUTH_TOKEN=<ls-auth-token> \
242+
AWS_PROFILE=ls-sandbox \
243+
localstack replicator start \
244+
--resource-type AWS::SSM::Parameter \
245+
--resource-identifier <identifier> \
246+
<disable-copy>
247+
Configured credentials from the AWS CLI
248+
{
249+
"job_id": "9acdc850-f71b-4474-b138-1668eb8b8396",
250+
"state": "TESTING_CONNECTION",
251+
"error_message": null,
252+
"type": "SINGLE_RESOURCE",
253+
"replication_config": {
254+
"resource_type": "AWS::SSM::PARAMETER",
255+
"identifier": "myparam"
256+
}
257+
}
258+
</disable-copy>
259+
{{< /command >}}
260+
261+
You can check the replication job status using the `job_id`:
262+
263+
{{< command >}}
264+
$ LOCALSTACK_AUTH_TOKEN=<ls-auth-token> \
265+
localstack replicator status 9acdc850-f71b-4474-b138-1668eb8b8396
266+
<disable-copy>
267+
{
268+
"job_id": "9acdc850-f71b-4474-b138-1668eb8b8396",
269+
"state": "SUCCEEDED",
270+
"error_message": null,
271+
"type": "SINGLE_RESOURCE",
272+
"replication_config": {
273+
"resource_arn": "arn:aws:ssm:eu-central-1:<account-id>:parameter/myparam"
274+
}
275+
}
276+
</disable-copy>
277+
{{< /command >}}
278+
279+
The state is `SUCCEEDED`, indicating the replication job completed successfully.
280+
The SSM parameter is now accessible.
281+
282+
{{< command >}}
283+
$ awslocal ssm get-parameters --name myparam --region eu-central-1
284+
<disable-copy>
285+
{
286+
"Parameters": [
287+
{
288+
"Name": "myparam",
289+
"Type": "String",
290+
"Value": "abc123",
291+
"Version": 1,
292+
"LastModifiedDate": 1738935663.08,
293+
"ARN": "arn:aws:ssm:eu-central-1:000000000000:parameter/myparam",
294+
"DataType": "text"
295+
}
296+
],
297+
"InvalidParameters": []
298+
}
299+
</disable-copy>
300+
{{< /command >}}
301+
302+
The resource is replicated into the same AWS region by default.
303+
Use the `--target-region-name` flag to change it.
304+
By default, replication occurs in LocalStack account `000000000000`.
305+
Use the `--target-account-id` flag to specify a different account.
306+
307+
## Supported Resources
308+
309+
{{< callout "tip" >}}
310+
To ensure support for all resources, use the latest LocalStack Docker image.
311+
{{< /callout >}}
312+
313+
{{< localstack_replicator_table >}}

data/replicator/coverage.json

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
[
2+
{
3+
"resource_type": "AWS::EC2::SecurityGroup",
4+
"policy_statements": [
5+
"cloudformation:GetResource",
6+
"ec2:DescribeSecurityGroups"
7+
],
8+
"service": "ec2",
9+
"identifier": "GroupId"
10+
},
11+
{
12+
"resource_type": "AWS::EC2::Subnet",
13+
"policy_statements": [
14+
"cloudformation:GetResource",
15+
"ec2:DescribeSubnets"
16+
],
17+
"service": "ec2",
18+
"identifier": "SubnetId"
19+
},
20+
{
21+
"resource_type": "AWS::EC2::VPC",
22+
"policy_statements": ["cloudformation:GetResource", "ec2:DescribeVpcs"],
23+
"service": "ec2",
24+
"identifier": "VpcId"
25+
},
26+
{
27+
"resource_type": "AWS::IAM::Policy",
28+
"policy_statements": ["iam:GetPolicy"],
29+
"service": "iam",
30+
"identifier": "Arn"
31+
},
32+
{
33+
"resource_type": "AWS::IAM::Role",
34+
"policy_statements": ["cloudformation:GetResource", "iam:GetRole"],
35+
"service": "iam",
36+
"identifier": "RoleName"
37+
},
38+
{
39+
"resource_type": "AWS::KMS::Key",
40+
"policy_statements": ["cloudformation:GetResource", "kms:DescribeKey"],
41+
"service": "kms",
42+
"identifier": "KeyId"
43+
},
44+
{
45+
"resource_type": "AWS::Lambda::LayerVersion",
46+
"policy_statements": [
47+
"cloudformation:GetResource",
48+
"lambda:GetLayerVersion"
49+
],
50+
"service": "lambda",
51+
"identifier": "LayerVersionArn"
52+
},
53+
{
54+
"resource_type": "AWS::SSM::Parameter",
55+
"policy_statements": [
56+
"cloudformation:GetResource",
57+
"ssm:GetParameters"
58+
],
59+
"service": "ssm",
60+
"identifier": "Name"
61+
},
62+
{
63+
"resource_type": "AWS::SecretsManager::Secret",
64+
"policy_statements": [
65+
"cloudformation:GetResource",
66+
"secretsmanager:DescribeSecret"
67+
],
68+
"service": "secretsmanager",
69+
"identifier": "Arn"
70+
}
71+
]

0 commit comments

Comments
 (0)