Skip to main content

Extending with Skills

Overview

This guide walks through creating a custom IPA stack skill using /ipa.author.stack. By the end, the reader has authored a new stack skill with a CloudFormation template, SKILL.md, SECURITY.md, and TROUBLESHOOT.md that integrates with /ipa.compose and the Makefile generation pipeline.

When to Use This Guide

Use this guide when:

  • An engagement requires an AWS service not covered by the built-in stacks (e.g., RDS, ElastiCache, Step Functions, SES)
  • A custom tier stack is needed that bundles multiple related services into a single deployable unit with feature flags
  • An existing CloudFormation template needs to be wrapped as a composable stack skill for use with /ipa.compose
  • The stack library needs to be extended with a reusable stack skill for use across multiple engagements

Do not use this guide to compose or deploy existing stacks — see Composing a Solution instead.

Before You Start

Before starting, confirm the following:

  • .env file exists with APP_NAMESPACE, APP_ENV, AWS_REGION, AWS_ACCOUNT_ID, and AWS_PROFILE set
  • An initialized project with at least one successful /ipa.compose run (confirms the skill infrastructure is working)
  • A CloudFormation template or design document for the new stack, including the AWS resources to create, parameters, and outputs
  • Familiarity with CloudFormation template authoring (parameters, resources, outputs, exports)
  • Understanding of the IPA skill directory layout: each stack skill lives at .claude/skills/ipa.stack.NAME/ with SKILL.md, SECURITY.md, and TROUBLESHOOT.md

Reference files for structural conventions:

  • .claude/skills/ipa.author.stack/REFERENCE.md — authoritative reference for all stack skill and pattern contracts
  • .claude/skills/ipa.stack.ecr/ — simple prepare stack example (single service, no wirable parameters)
  • .claude/skills/ipa.stack.backend/ — tier stack example (multiple services, feature flags, wirable parameters)

Before / Target State

BeforeAfter
A CloudFormation template or design for infrastructure not part of the built-in stacksCloudFormation template at infra/cfn/NAME/NAME.yml following IPA conventions
No stack skill — the infrastructure cannot be selected or wired by /ipa.composeComplete stack skill at .claude/skills/ipa.stack.NAME/ with SKILL.md, SECURITY.md, and TROUBLESHOOT.md
No compose integrationThe new stack appears as a selectable option in /ipa.compose with auto-wiring support

Steps

1. Design the stack interface

Before invoking the authoring skill, plan the stack interface. Define the following for each item:

Parameters:

  • Which parameters beyond Namespace and Environment does the stack need?
  • For each parameter, determine its classification:
    • Configuration — sourced from .env or template defaults (e.g., MemorySize, Timeout)
    • Wirable — Required — must be populated from an upstream stack output (e.g., ImageUri from ECR)
    • Wirable — Optional — defaults to empty string, conditionally enables resources (e.g., AlarmSnsTopicArn)

Outputs:

  • What values do downstream stacks or operational steps need?
  • Every output must be exported using the convention {StackName}-{OutputKey}

Lifecycle:

  • prepare — one-time prerequisites that survive teardown (e.g., ECR, Cognito)
  • deploy — application stacks created and destroyed together

Wiring:

  • Which existing stacks provide inputs to this stack?
  • Which downstream stacks consume this stack's outputs?

2. Run /ipa.author.stack

To scaffold the stack skill, invoke the authoring skill:

/ipa.author.stack create NAME

Replace NAME with the service name (lowercase, e.g., rds, elasticache, stepfn).

The skill detects the authoring mode based on the input:

InputMode
Names a single AWS service (e.g., rds, ses)Single-service prepare stack
Describes a multi-service scenario or names a tier conceptCombined (tier stack + pattern definition)
Target files already existUpdate mode

The skill walks through an interactive requirements gathering phase, collecting architecture overview, parameters, outputs, capabilities, security posture, and lifecycle classification. It then generates four artifacts:

  • infra/cfn/NAME/NAME.yml — CloudFormation template
  • .claude/skills/ipa.stack.NAME/SKILL.md — stack skill metadata
  • .claude/skills/ipa.stack.NAME/SECURITY.md — security advisory
  • .claude/skills/ipa.stack.NAME/TROUBLESHOOT.md — failure catalog

3. Review the CloudFormation template

After the skill generates the template, review infra/cfn/NAME/NAME.yml for correctness. Confirm these IPA conventions are followed:

Mandatory parameters — Namespace and Environment are the first two parameters with the exact validation pattern:

Parameters:
Namespace:
Type: String
AllowedPattern: '^[a-z][a-z0-9-]{0,11}$'
ConstraintDescription: 'Invalid namespace — 1-12 chars, lowercase alphanumeric + hyphens, starts with letter'
Environment:
Type: String
AllowedPattern: '^[a-z][a-z0-9-]{0,11}$'
ConstraintDescription: 'Must be 1-12 chars, lowercase letters/digits/hyphens, starts with letter'

Resource naming — all resources use !Sub '${Namespace}-${Environment}-suffix' with no hardcoded account IDs or regions.

Output exports — every output uses the standard export convention:

Outputs:
ExampleOutput:
Description: 'Description of the output'
Value: !GetAtt Resource.Attribute
Export:
Name: !Sub '${AWS::StackName}-ExampleOutput'

Conditions — wirable-optional parameters use conditions to gate resources:

Conditions:
HasOptionalParam: !Not [!Equals [!Ref OptionalParam, '']]

To validate the template syntax, run:

aws cloudformation validate-template \
--template-body file://infra/cfn/NAME/NAME.yml

A successful validation returns the template description and parameter list. Fix any errors and re-validate before proceeding.

4. Verify SKILL.md compose compatibility

Open .claude/skills/ipa.stack.NAME/SKILL.md and confirm it contains the four sections that /ipa.compose requires, with exact heading names:

SectionHeadingPurpose
CloudFormation Contract## CloudFormation ContractTemplate path, stack name suffix, capabilities
Parameters## ParametersParameter table with columns: Parameter, Type, Default, Validation, Error Message
Parameter Classification### Parameter ClassificationClassification under Parameters, using <- arrow notation for wirable parameters
Outputs## OutputsOutput table with columns: Output, Description, Export Convention, Used By

The Parameter Classification section is critical for auto-wiring. Wirable parameters must use the arrow notation so /ipa.compose can resolve connections:

**Wirable — Required** (1) — sourced from upstream stack outputs:
- ImageUri <- ipa.stack.ecr `RepositoryUri`
warning

If any of the four required sections are missing or use different heading names, /ipa.compose validation (V3) rejects the stack skill. The heading names must match exactly.

5. Review the SECURITY.md

Open .claude/skills/ipa.stack.NAME/SECURITY.md and confirm it documents:

  • Deployment Permissions — IAM actions the Builder Execution Role needs, scoped to the tightest resource ARN possible
  • Security Controls — hardcoded security posture (encryption, access control, logging)
  • Known Deferrals — any security items deferred for POC scope, each with a Reason and Risk assessment

After creating or updating the stack skill, run /ipa.security to recalculate the Builder Execution Role permissions for the new stack:

/ipa.security

6. Test composition

To verify the new stack integrates with the composition pipeline, run:

/ipa.compose

Select the new stack when prompted. The compose skill reads the SKILL.md, validates the sections, resolves wiring, and generates Makefiles.

After composition completes, verify the generated artifacts in scripts/:

  • scripts/deploy.mk (or scripts/prepare.mk for prepare-lifecycle stacks) contains a deploy-NAME target with the correct --template-file, --parameter-overrides, and --capabilities
  • Wiring is resolved: $(eval) lines fetch outputs from upstream stacks and pass them as parameter overrides
  • scripts/SECURITY-DISPOSITION.md includes any Known Deferrals from the new stack

7. Deploy and verify

To deploy the new stack, run:

/ipa.deploy

After deployment completes, confirm the stack was created:

aws cloudformation describe-stacks \
--stack-name $(APP_NAMESPACE)-$(APP_ENV)-NAME \
--query 'Stacks[0].StackStatus' \
--output text

The expected output is CREATE_COMPLETE.

To confirm outputs are accessible to downstream stacks, list the stack exports:

aws cloudformation describe-stacks \
--stack-name $(APP_NAMESPACE)-$(APP_ENV)-NAME \
--query 'Stacks[0].Outputs[*].[OutputKey,OutputValue]' \
--output table

The output table lists each exported key and its value.

Verification

To verify the full workflow succeeded, confirm these checks:

  1. /ipa.compose lists the new stack as a selectable option and composes without validation errors.

  2. Generated Makefiles include targets for the new stack. To check:

    grep 'deploy-NAME' scripts/deploy.mk

    This returns the deploy target line for the new stack.

  3. The CloudFormation stack is deployed and healthy:

    aws cloudformation describe-stacks \
    --stack-name $(APP_NAMESPACE)-$(APP_ENV)-NAME \
    --query 'Stacks[0].StackStatus' \
    --output text

    Expected: CREATE_COMPLETE

  4. Stack outputs are exported and accessible via CloudFormation exports:

    aws cloudformation list-exports \
    --query "Exports[?starts_with(Name, '$(APP_NAMESPACE)-$(APP_ENV)-NAME')].[Name,Value]" \
    --output table

Troubleshooting

ProblemLikely CauseFix
aws cloudformation validate-template fails with Template format errorNamespace or Environment parameter missing the required AllowedPattern, or YAML syntax error in the templateAdd the exact AllowedPattern from REFERENCE.md Section 4 to both parameters. Run a YAML linter to check syntax.
/ipa.compose validation fails with "missing required section"SKILL.md is missing one of the four required sections (## CloudFormation Contract, ## Parameters, ### Parameter Classification, ## Outputs) or uses a different heading nameAdd the missing section with the exact heading name. See REFERENCE.md Section 8 for the required section list.
Wiring resolution fails — parameter marked as "unresolved"The <- arrow notation in Parameter Classification is missing, malformed, or references a stack not in the compositionAdd or correct the arrow notation: ParamName <- ipa.stack.source \OutputKey``. Confirm the source stack is included in the pattern.
CREATE_FAILED during deployment with parameter validation errorA required parameter is missing from --parameter-overrides in the generated Makefile, or a parameter value does not match the AllowedPatternCheck the Makefile target for the missing parameter. Verify the parameter value format against the AllowedPattern in the CloudFormation template. Re-compose with /ipa.compose to regenerate.

Next Steps

  • Compose the new stack into a solution — see Composing a Solution
  • Stack skills reference — see Stack Skills for documentation on all built-in stack skills
  • Author skills reference — see Author Skills for documentation on /ipa.author.stack
  • Recalculate security permissions — run /ipa.security to update the Builder Execution Role for the new stack
  • Tear down the deployment — run /ipa.destroy (see Path to Production for lifecycle management)