Skip to content
English
  • There are no suggestions because the search field is empty.

Automating Arpio StackSets Adoption at Scale

This guide describes how to automate StackSets deployment using the Arpio API and AWS CloudFormation CLI.

The docs here illustrate how to Deploy Access with AWS StackSets through the Arpio console.

Jump to:

Prerequisites

  • StackSets capability enabled on your Arpio tenant (contact Arpio support)
    • StackSets is enabled as a capability on your Arpio tenant—there is no per-app flag. The backend detects StackSet management by reading the ArpioStackSet tag from the deployed Stack and exposes this information to the Arpio UI and API.
  • Arpio API credentials with appropriate permissions


Summary

Step

Frequency

Where

1. Create Administration Role

Once

Management account in AWS

2. Create Execution Roles

Once per target account

Each primary/recovery account in AWS

3. Create Arpio Application

Per app

Arpio API

4. Fetch Access Templates

Per app

Arpio API

5. Create StackSets

Once (skip if exists)

Management account in AWS

6. Create Stack Instances

Per app (2 calls)

Management account in AWS

 

Variables

Replace these placeholders throughout the guide:

Placeholder

Description

MANAGEMENT_ACCOUNT_ID

AWS account ID of your management account

PRIMARY_ACCOUNT_ID

AWS account ID of your primary (source) account

RECOVERY_ACCOUNT_ID

AWS account ID of your recovery account

PRIMARY_REGION

e.g. us-east-1

RECOVERY_REGION

e.g. us-west-2

ARPIO_ACCOUNT_ID

Your Arpio account ID

TOKEN

Your Arpio API bearer token

 

 


Step 1 — Create Administration Role (once, in management account)

aws cloudformation create-stack \

  --stack-name ArpioStackSetAdministrationRole \

  --capabilities CAPABILITY_NAMED_IAM \

  --template-body file://admin-role.yml

Save the following as admin-role.yml:

AWSTemplateFormatVersion: '2010-09-09'

Description: StackSet Administration Role for Arpio

Parameters:

  ExecutionRoleName:

    Type: String

    Default: ArpioStackSetExecutionRole

Resources:

  AdministrationRole:

    Type: AWS::IAM::Role

    Properties:

      RoleName: ArpioStackSetAdministrationRole

      AssumeRolePolicyDocument:

        Version: '2012-10-17'

        Statement:

          - Effect: Allow

            Principal:

              Service: cloudformation.amazonaws.com

            Action: sts:AssumeRole

      Policies:

        - PolicyName: AssumeExecutionRole

          PolicyDocument:

            Version: '2012-10-17'

            Statement:

              - Effect: Allow

                Action: sts:AssumeRole

                Resource: !Sub 'arn:aws:iam::*:role/${ExecutionRoleName}'

Wait for completion:

aws cloudformation wait stack-create-complete \

  --stack-name ArpioStackSetAdministrationRole

 



Step 2 — Create Execution Roles (once per target account)

Once the Administration Role can assume roles in the target account, deploy the Execution Role using one of the below methods. Run in each AWS account that participates as primary or recovery.

Option A: Deploy via CloudFormation CLI

Run this command from the target account (or use cross-account role assumption):

aws cloudformation create-stack \

  --stack-name ArpioStackSetExecutionRole \

  --capabilities CAPABILITY_NAMED_IAM \

  --parameters ParameterKey=AdministrationAccountId,ParameterValue=MANAGEMENT_ACCOUNT_ID \

  --template-body file://execution-role.yml

Save the following as execution-role.yml:

AWSTemplateFormatVersion: '2010-09-09'

Description: StackSet Execution Role for Arpio

Parameters:

  AdministrationAccountId:

    Type: String

    Description: AWS Account ID of the Administration Account

  AdministrationRoleName:

    Type: String

    Default: ArpioStackSetAdministrationRole

Resources:

  ExecutionRole:

    Type: AWS::IAM::Role

    Properties:

      RoleName: ArpioStackSetExecutionRole

      AssumeRolePolicyDocument:

        Version: '2012-10-17'

        Statement:

          - Effect: Allow

            Principal:

              AWS: !Sub 'arn:aws:iam::${AdministrationAccountId}:role/${AdministrationRoleName}'

            Action: sts:AssumeRole

      ManagedPolicyArns:

        - arn:aws:iam::aws:policy/AdministratorAccess

Wait for completion:

aws cloudformation wait stack-create-complete \

  --stack-name ArpioStackSetExecutionRole


Option B: Deploy via CloudShell in Target Account

The Arpio console provides a ready-to-run command. Copy it from the UI and paste into CloudShell:

# From Arpio Console: App Settings > AWS Access > Step 1b

# Copy the provided command and run in CloudShell

aws cloudformation create-stack \

  --stack-name ArpioStackSetExecutionRole \

  --template-url <url-from-arpio-console> \

  --capabilities CAPABILITY_NAMED_IAM \

  --parameters ParameterKey=AdministrationAccountId,ParameterValue=<mgmt-acct>


Option C: Batch Deployment via Automation

For bulk onboarding of multiple accounts, you can script the deployment using cross-account role assumption:

#!/bin/bash

# deploy_execution_roles.sh

# Deploys Execution Role to multiple target accounts



MGMT_ACCOUNT_ID="123456789012"

TARGET_ACCOUNTS=("<aws_source_account_id>" "<aws_target_account_id>" "333333333333")

CROSS_ACCOUNT_ROLE="OrganizationAccountAccessRole"  # or your role name



TEMPLATE_URL="https://arpio-cloudformation-templates.s3.amazonaws.com/\

stacksets/ArpioStackSetExecutionRole.yml"


for ACCOUNT_ID in "${TARGET_ACCOUNTS[@]}"; do

  echo "Deploying to account: $ACCOUNT_ID"

 
  # Assume role in target account

  CREDS=$(aws sts assume-role \

    --role-arn arn:aws:iam::${ACCOUNT_ID}:role/${CROSS_ACCOUNT_ROLE} \

    --role-session-name ArpioExecRoleDeploy \

    --query 'Credentials.[AccessKeyId,SecretAccessKey,SessionToken]' \

   --output text)

  export AWS_ACCESS_KEY_ID=$(echo $CREDS | cut -d' ' -f1)

  export AWS_SECRET_ACCESS_KEY=$(echo $CREDS | cut -d' ' -f2)

  export AWS_SESSION_TOKEN=$(echo $CREDS | cut -d' ' -f3)


  # Deploy the stack

  aws cloudformation create-stack \

    --stack-name ArpioStackSetExecutionRole \

    --template-url "$TEMPLATE_URL" \

    --capabilities CAPABILITY_NAMED_IAM \

    --parameters ParameterKey=AdministrationAccountId,ParameterValue=$MGMT_ACCOUNT_ID


  # Wait for completion

  aws cloudformation wait stack-create-complete \

    --stack-name ArpioStackSetExecutionRole


  echo "Completed: $ACCOUNT_ID"

done


# Clear temporary credentials

unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN

Verify Execution Role Deployment

Confirm the role exists in the target account:

# Verify the role was created (run in target account)

aws iam get-role --role-name ArpioStackSetExecutionRole


# Check the trust policy allows the Administration Role

aws iam get-role --role-name ArpioStackSetExecutionRole \

  --query 'Role.AssumeRolePolicyDocument'

 


Step 3 — Create an Arpio Application (per app)

curl -X POST "https://app.arpio.io/api/accounts/ARPIO_ACCOUNT_ID/applications" \

  -H "Authorization: Bearer TOKEN" \

  -H "Content-Type: application/json" \

  -d '{

    "accountId": "ARPIO_ACCOUNT_ID",

    "name": "APP_NAME",

    "type": "aws",

    "rpo": RPO_SECONDS,

    "notificationEmails": ["team@example.com"],

    "sourceEndpointUri": "aws:PRIMARY_ACCOUNT_ID:PRIMARY_REGION",

    "targetEndpointUri": "aws:RECOVERY_ACCOUNT_ID:RECOVERY_REGION",

    "selectionRules": [

      { "type": "tag", "tagKey": "TAG_KEY", "tagValue": "TAG_VALUE" }

    ],

    "syncPhase": "STANDBY"

  }'

Save the appId from the response.

 


Step 4 — Fetch Access Templates (per app)

Template S3 URLs are stable and remain constant even when Arpio releases updates. The template content is refreshed in place at the same URL. This means you can store the URL in your automation scripts and CI/CD pipelines without needing to re-query for each update.

curl -s "https://app.arpio.io/api/accounts/ARPIO_ACCOUNT_ID/syncPairs/aws:PRIMARY_ACCOUNT_ID:PRIMARY_REGION/aws:RECOVERY_ACCOUNT_ID:RECOVERY_REGION/accessTemplates" \

  -H "Authorization: Bearer TOKEN"

From the response, extract these fields:

Response field

Use in

stackSetsTemplate.sourceStackSetTemplateS3Url

Step 5 — SOURCE_STACKSET_TEMPLATE_URL (first app only)

stackSetsTemplate.targetStackSetTemplateS3Url

Step 5 — TARGET_STACKSET_TEMPLATE_URL (first app only)

stackSetsTemplate.sourceTemplate.bucket

Step 6 — SOURCE_TEMPLATE_BUCKET

stackSetsTemplate.sourceTemplate.key

Step 6 — SOURCE_TEMPLATE_KEY

stackSetsTemplate.targetTemplate.bucket

Step 6 — TARGET_TEMPLATE_BUCKET

stackSetsTemplate.targetTemplate.key

Step 6 — TARGET_TEMPLATE_KEY

 


Step 5 — Create Two StackSets (once, in management account — skip if already created)

This step only needs to run once. If you already have the ArpioPrimaryAccess and ArpioRecoveryAccess StackSets, skip to Step 6.

Create the ArpioPrimaryAccess StackSet:

aws cloudformation create-stack-set \

  --stack-set-name ArpioPrimaryAccess \

  --template-url SOURCE_STACKSET_TEMPLATE_URL \

  --permission-model SELF_MANAGED \

  --administration-role-arn arn:aws:iam::MANAGEMENT_ACCOUNT_ID:role/ArpioStackSetAdministrationRole \

  --execution-role-name ArpioStackSetExecutionRole \

  --capabilities CAPABILITY_NAMED_IAM

Create the ArpioRecoveryAccess StackSet:

aws cloudformation create-stack-set \

  --stack-set-name ArpioRecoveryAccess \

  --template-url TARGET_STACKSET_TEMPLATE_URL \

  --permission-model SELF_MANAGED \

  --administration-role-arn arn:aws:iam::MANAGEMENT_ACCOUNT_ID:role/ArpioStackSetAdministrationRole \

  --execution-role-name ArpioStackSetExecutionRole \

 --capabilities CAPABILITY_NAMED_IAM

 


Step 6 — Create Stack Instances (per app, in management account)

The SourceAwsAccountId and TargetAwsAccountId parameters in the StackSet template are placeholders with default values set to the first application's account IDs at template generation time. Always override these with parameter overrides when creating new stack instances.

Primary Access — deploys into the primary account/region:

aws cloudformation create-stack-instances \

  --stack-set-name ArpioPrimaryAccess \

  --accounts PRIMARY_ACCOUNT_ID \

  --regions PRIMARY_REGION \

  --parameter-overrides \

    ParameterKey=SourceAwsAccountId,ParameterValue=PRIMARY_ACCOUNT_ID \

    ParameterKey=SourceRegion,ParameterValue=PRIMARY_REGION \

    ParameterKey=TargetAwsAccountId,ParameterValue=RECOVERY_ACCOUNT_ID \

    ParameterKey=TargetRegion,ParameterValue=RECOVERY_REGION \

    ParameterKey=TemplateS3Bucket,ParameterValue=SOURCE_TEMPLATE_BUCKET \

    ParameterKey=TemplateS3Key,ParameterValue=SOURCE_TEMPLATE_KEY

Recovery Access — deploys into the recovery account/region:

aws cloudformation create-stack-instances \

  --stack-set-name ArpioRecoveryAccess \

  --accounts RECOVERY_ACCOUNT_ID \

  --regions RECOVERY_REGION \

  --parameter-overrides \

    ParameterKey=SourceAwsAccountId,ParameterValue=PRIMARY_ACCOUNT_ID \

    ParameterKey=SourceRegion,ParameterValue=PRIMARY_REGION \

    ParameterKey=TargetAwsAccountId,ParameterValue=RECOVERY_ACCOUNT_ID \

    ParameterKey=TargetRegion,ParameterValue=RECOVERY_REGION \

    ParameterKey=TemplateS3Bucket,ParameterValue=TARGET_TEMPLATE_BUCKET \

    ParameterKey=TemplateS3Key,ParameterValue=TARGET_TEMPLATE_KEY

 


Automating Template Updates

Key Benefit: Single Command Updates

When Arpio releases new template versions, you can automate the update process by comparing template versions and running update-stack-set.

Running update-stack-set once per StackSet automatically propagates the update to ALL stack instances. For 50 applications, you run 2 commands instead of 100.


Compare Current vs. Latest Template Version

Query the application to get the current templateVersion:

# Get current template version

curl -X GET "https://api.arpio.io/api/accounts/{account_id}/applications/{app_id}" \

  -H "Authorization: Bearer {token}"

# Parse the templateVersion field from the response

Query the access templates endpoint to get the latest template version:

# Get latest template version from accessTemplates endpoint

curl -X GET "https://api.arpio.io/api/accounts/{account_id}/syncPairs/\

  {src_account}/{src_region}/{tgt_account}/{tgt_region}/accessTemplates" \

  -H "Authorization: Bearer {token}"

# Compare templateVersion with current application version


Apply Updates

If versions differ, run update-stack-set to propagate changes to all instances:

# Update Primary StackSet (propagates to ALL primary stack instances)

aws cloudformation update-stack-set \

  --stack-set-name ArpioPrimaryAccess \

  --template-url {sourceStackSetTemplateS3Url} \

  --administration-role-arn arn:aws:iam::{mgmt_account}:role/ArpioStackSetAdministrationRole \

  --capabilities CAPABILITY_NAMED_IAM


# Update Recovery StackSet (propagates to ALL recovery stack instances)

aws cloudformation update-stack-set \

  --stack-set-name ArpioRecoveryAccess \

  --template-url {targetStackSetTemplateS3Url} \

  --administration-role-arn arn:aws:iam::{mgmt_account}:role/ArpioStackSetAdministrationRole \

  --capabilities CAPABILITY_NAMED_IAM

 

Verify Update Success

After running the update, verify success using one of these methods:

  1. Check templateVersion: Query the application API and verify the templateVersion field matches the expected version.
  2. Check Sync Access: Call the access endpoint to confirm Arpio can reach the sync endpoint.
# Verify access after update

curl -X GET "https://api.arpio.io/api/accounts/{account_id}/syncPairs/\

  {src_account}/{src_region}/{tgt_account}/{tgt_region}/access" \

  -H "Authorization: Bearer {token}"