Gestionar AWS SSM Parameter Store con ParamsX

ParamsX

AWS Systems Manager Parameter Store es una solución muy cómoda para centralizar configuración y secretos, pero cuando empiezas a manejar muchos parámetros, varios entornos y diferentes aplicaciones, algunas tareas del día a día pueden volverse bastante repetitivas.

Consultar o modificar un parámetro concreto desde AWS no supone ningún problema. La fricción aparece cuando necesitas trabajar con varios a la vez: revisar cambios, modificar valores, gestionar tags, mantener distintas convenciones de rutas o comprobar exactamente qué vas a tocar antes de aplicar nada.

De esa necesidad nació ParamsX, una CLI escrita en Python para trabajar con AWS Systems Manager Parameter Store desde la terminal, descargando los parámetros a un fichero local que puedes editar cómodamente con tu editor habitual.

El objetivo inicial era sencillo:

Descargar un conjunto de parámetros, editarlos localmente y poder ver exactamente qué iba a cambiar en AWS antes de aplicar nada.

ParamsX nació en diciembre de 2024 y desde entonces ha ido evolucionando para adaptarse a más estructuras, flujos de trabajo y requisitos de seguridad.

Instalación

ParamsX está disponible en PyPI:

pip install paramsx

También puedes instalarlo de forma aislada con pipx:

pipx install paramsx

Después se genera la configuración inicial:

paramsx configure

Y se ejecuta simplemente con:

paramsx

La configuración queda almacenada en:

~/.xsoft/paramsx_config.py

Si ya tienes una configuración de una versión anterior, paramsx configure no la sobrescribe. La herramienta comprueba la configuración existente y te informa de las opciones nuevas o de posibles problemas.

Además, puedes generar una plantilla completa de la versión instalada con:

paramsx configure --ejemplo

Esto crea:

~/.xsoft/paramsx_config.ejemplo.py

junto a tu configuración actual, de forma que puedes comparar ambas sin modificar tu fichero.

Definir qué parámetros quieres gestionar

Una de las cosas que quería evitar era imponer una estructura concreta en Parameter Store, ya que cada organización acaba utilizando convenciones diferentes por ejemplo:

/dev/api/my-service
/API/MY-SERVICE/DEV
/API/DEV/MY-SERVICE
/API/DEV/MY-SERVICE/auth

Por eso ParamsX utiliza perfiles de rutas.

Una configuración básica podría ser:

perfiles = {
    "min": {
        "posicion_entorno": "inicio",
        "case_entorno": "lower",
        "case_ruta": "lower",
    }
}

configuraciones = {
    "profile_name": "default",
    "region_name": "eu-south-2",

    "entornos": [
        "dev",
        "pre",
        "prod",
    ],

    "parameter_list": [
        {"path": "/common", "perfil": "min"},
        {"path": "/api", "perfil": "min"},
    ],
}

En este caso se convierte en:

/dev/api
/dev/common

Cómo funcionan los perfiles

Los perfiles son una de las partes que más ha evolucionado en ParamsX.

La primera versión asumía prácticamente una única forma de construir las rutas. Eso funciona mientras todos tus proyectos utilizan la misma convención, pero deja de funcionar cuando aparecen cuentas antiguas, equipos distintos o aplicaciones con estructuras diferentes.

Un perfil define cómo construir la ruta real de AWS a partir de la ruta declarada en parameter_list.

Cada perfil tiene tres propiedades:

CampoValoresQué controla
posicion_entornoiniciofinalmixtoningunoDónde se coloca el entorno dentro de la ruta
case_entornoloweruppercapitalizeCómo se escribe el entorno
case_rutaloweruppercapitalizeningunoCómo se normaliza la ruta al crear parámetros nuevos

La forma más sencilla de entenderlos es ver qué hace cada campo.

Posición del entorno

Utilizando dev como entorno de ejemplo:

posicion_entornoRuta declaradaRuta resultante
inicio/rds/dev/rds
final/API/STA/API/STA/DEV
mixto/API/*/STA/API/DEV/STA
ninguno/api/sta/auth/api/sta/auth

El modo mixto permite indicar exactamente dónde quieres insertar el entorno utilizando *.

Esto no solo permite adaptar el naming, sino también acotar la lectura a un subárbol concreto.

El modo ninguno, por su parte, mantiene la ruta exactamente sin añadir entorno. Puede ser útil, por ejemplo, cuando cada entorno vive en una cuenta AWS diferente.

Formato del entorno

case_entorno permite adaptar el mismo entorno lógico a diferentes convenciones:

case_entornoResultado para dev
lowerdev
upperDEV
capitalizeDev

De esta forma, un proyecto puede utilizar:

/dev/api

y otro:

/API/DEV

sin tener que cambiar la lógica de la herramienta.

Formato de la ruta

case_ruta controla cómo se normaliza la ruta cuando se crea un parámetro nuevo.

Si escribes:

/API/MULTIAPI/Token

el resultado puede ser:

case_rutaResultado
lower/api/multiapi/token
upper/API/MULTIAPI/TOKEN
capitalize/Api/Multiapi/Token
ninguno/API/MULTIAPI/Token

Este comportamiento se aplica al crear parámetros nuevos.

ParamsX no renombra ni modifica las rutas que ya existen en AWS: se leen y editan respetando su nombre actual.

Puedes definir tantos perfiles como necesites y asignar uno distinto a cada entrada de parameter_list.

Por ejemplo:

perfiles = {
    "min": {
        "posicion_entorno": "inicio",
        "case_entorno": "lower",
        "case_ruta": "lower",
    },

    "max": {
        "posicion_entorno": "final",
        "case_entorno": "upper",
        "case_ruta": "ninguno",
    },
}

configuraciones = {
    "parameter_list": [
        {"path": "/common", "perfil": "min"},
        {"path": "/api", "perfil": "min"},
        {"path": "/API/STA", "perfil": "max"},
    ],
}

La idea es separar dos conceptos: qué ruta quiero gestionar y cómo se construye esa ruta en este proyecto.

Editar parámetros localmente

Al ejecutar:

paramsx

se muestra un menú con las operaciones principales:

1. Leer parámetros
2. Comparar y actualizar parámetros
3. Crear backups
4. Crear un parámetro nuevo

El flujo principal empieza seleccionando Leer parámetros.

Eliges una ruta y un entorno y ParamsX descarga los parámetros correspondientes.

Por defecto genera:

parameters_dev.py
parameters_dev_backup.py

El fichero principal es el que editas y el backup conserva el estado original descargado desde AWS.

Si trabajas con varias rutas dentro de un mismo entorno, puedes activar:

fichero_por_ruta = True

De esta forma cada ruta genera su propio fichero y una lectura no sobrescribe la anterior.

Por ejemplo:

parameters_dev__API_STA__max.py
parameters_dev__API_STA__max_backup.py

Puedes abrir el fichero principal en VS Code, PyCharm, Vim o cualquier otro editor y modificar los parámetros cómodamente.

Si tienes activada la gestión de tags, todo se encuentra en el mismo fichero:

parametros = [
    {
        "parameter_name": "/dev/api/my-service/token",
        "parameter_description": "Token utilizado por la API",
        "parameter_value": """abc123""",

        "tagApplication": "my-service",
        "tagEnvironment": "dev",
        "tagOwner": "platform",
        "tagProject": "internal",
        "tagProduct": "backend",
        "tagService": "api",
        "tagComponent": "auth",
        "tagManagedBy": "paramsx",
    }
]

Esto permite modificar desde el mismo editor:

  • el valor;
  • la descripción;
  • el tipo del parámetro;
  • sus tags.

Las tags que quieres exigir también se configuran desde paramsx_config.py.

Por ejemplo:

tags_obligatorias = [
    "Application",
    "Environment",
    "Owner",
    "Project",
    "Product",
    "Service",
    "Component",
    "ManagedBy",
]

Si la gestión de tags está desactivada, estos campos simplemente no aparecen en el fichero exportado.

El segundo fichero, el backup, contiene el estado original y es lo que permite calcular después exactamente qué ha cambiado.

El punto importante: ver el diff antes de escribir en AWS

Esta era probablemente la funcionalidad que más me interesaba cuando empecé el proyecto.

Después de editar el fichero seleccionas la opción de carga y ParamsX compara el fichero modificado con el estado original y clasifica los cambios antes de aplicar nada en AWS.

Por ejemplo:

NUEVOS
+ /dev/api/my-service/new_parameter

MODIFICADOS
~ /dev/api/my-service/token
  valor

~ /dev/api/my-service/config
  descripción | tags

ELIMINADOS
- /dev/api/my-service/old_parameter

El diff puede detectar cambios en: valor, descripción, tipo y tags.

Solo después de confirmarla se aplican los cambios.

El flujo termina siendo: leer → editar → diff → revisar → aplicar en lugar de modificar parámetros individualmente desde la consola y perder fácilmente la visión global del cambio.

IAM y control de acceso

ParamsX no implementa un sistema de permisos paralelo. AWS IAM sigue siendo quien decide qué puede leer o modificar cada usuario o rol.

parameter_list únicamente define las rutas con las que quieres trabajar.

Si tu rol no tiene acceso a una ruta, AWS seguirá denegando la operación y ParamsX mostrará un mensaje más claro en lugar de una traza completa de boto3.

Además, si tu organización utiliza ABAC, las tags gestionadas por ParamsX pueden formar parte de las condiciones IAM para controlar el acceso a parámetros privados.

En mi caso, este es precisamente el enfoque que utilizo actualmente: las rutas ayudan a organizar los parámetros y las tags participan en el control de acceso mediante IAM.

Errores IAM más legibles

Si AWS deniega el acceso, ParamsX intenta convertir la excepción de boto3 en un mensaje más útil.

Por ejemplo:

⚠ No tienes permisos para leer: /dev/rds

Pídele a un administrador que te dé acceso o configura
una ruta más específica en parameter_list.

La seguridad sigue estando en AWS. ParamsX simplemente intenta hacer más cómodo el flujo de trabajo alrededor de ella.

SecureString por defecto

Otro comportamiento que quería que fuese difícil olvidar era el cifrado.

Los parámetros nuevos creados directamente desde ParamsX se crean como SecureString.

Por defecto:

forzar_securestring = True

hace que los parámetros enviados por ParamsX se almacenen como: SecureString

La razón es sencilla: con el tiempo es fácil que Parameter Store termine conteniendo credenciales, tokens u otros valores sensibles.

También se puede desactivar este comportamiento en el archivo de configuración:

forzar_securestring = False

En ese caso, al actualizar parámetros existentes ParamsX respeta el tipo que ya tengan en AWS: String, StringList o SecureString

Backups antes de cambios importantes

Además del backup temporal utilizado para calcular el diff, ParamsX permite generar backups manuales.

Puedes guardar:

  • una combinación concreta de ruta y entorno;
  • todas las rutas incluidas en tu parameter_list;
  • todos los parámetros de SSM a los que tengas acceso en la cuenta.

Por ejemplo, un backup completo genera:

all_parameters_backup.py

Puede resultar especialmente útil antes de reorganizar rutas, hacer migraciones o aplicar cambios importantes.

Crear parámetros sin abrir la consola

ParamsX también permite crear un parámetro desde cero.

Indicas:

  • entorno;
  • ruta;
  • descripción;
  • valor;
  • tags.

Y la herramienta construye la ruta utilizando el perfil configurado.

Por ejemplo:

Entorno: dev
Ruta: /api/my-service/token

con un perfil que coloca el entorno al inicio se convierte en:

/dev/api/my-service/token

Antes de crear nada se muestra la ruta, el valor y las tags finales para que puedas revisarlos.

Además, la creación utiliza:

Overwrite=False

para evitar sobrescribir accidentalmente un parámetro que ya exista.

¿Por qué no usar CloudFormation o Terraform?

ParamsX no pretende sustituir Terraform, CloudFormation, CDK ni ningún sistema de Infrastructure as Code.

Si tus parámetros forman parte de infraestructura declarativa y su ciclo de vida se gestiona desde IaC, probablemente deberían seguir ahí.

El caso que intenta resolver ParamsX es diferente: parámetros que ya existen en Parameter Store y forman parte de la operación diaria de aplicaciones. Especialmente cuando necesitas:

  • consultar varios rápidamente;
  • modificar varios valores;
  • revisar exactamente qué va a cambiar;
  • gestionar sus tags;
  • crear backups;
  • trabajar con diferentes convenciones de rutas;
  • o simplemente evitar navegar constantemente por la consola.

Son herramientas para problemas diferentes, ParamsX intenta hacer más cómodo y seguro el trabajo diario con los parámetros nuevos o que ya viven en AWS SSM.


Estado actual

El proyecto sigue evolucionando a partir de situaciones que aparecen durante su uso, intentando mantener un flujo sencillo:

leer → editar → revisar → aplicar

sin sustituir los controles que ya proporciona AWS.

PyPI: https://pypi.org/project/paramsx

Si trabajas habitualmente con AWS Systems Manager Parameter Store, me gustaría saber:

¿Cómo gestionas actualmente los cambios masivos y la revisión antes de aplicarlos?

Espero que ParamsX pueda ser útil a otros equipos que se encuentren con problemas similares.

¡Salu2!