autojanet/skills/azure-pipeline-lambda/SKILL.md
Zoë cc74ad0bd0
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
fix: use library/ Harbor project, add skills, fix pipeline secrets
- .woodpecker.yaml: image paths -> library/autojanet-{agent,dispatcher}
- .woodpecker.yaml: secret names RS_HARBOR_USER / RS_HARBOR_PASS (global)
- container/Dockerfile: restore COPY skills/, skills/ populated from opencode config
- skills/: 84 opencode skills bundled into image
- k8s/manifests: update image refs to library/
2026-05-30 15:43:14 -07:00

5.1 KiB

name description
azure-pipeline-lambda Extends azure-devops-pipeline for AWS Lambda deployments. Handles zip and container packaging, OIDC credentials, function update and alias promotion. Always load azure-devops-pipeline first.

What I add

Type-specific steps for AWS Lambda pipelines. Merge these into the skeleton from azure-devops-pipeline.

Additional required inputs — ask the user

  1. Function name — the Lambda function name in AWS
  2. AWS region — e.g. us-east-1
  3. AWS service connection name — the ADO AWS OIDC service connection name
  4. Packaging methodzip | container
  5. Deployment methodaws-cli | SAM | CDK
  6. Runtimepython3.x | nodejs20.x | other (for linting tool selection)
  7. Alias to update — e.g. nonprod or prod (matches target tier)

Lint stage steps

Python runtime

- script: pip install pylint && pylint src/ --fail-under=7
  displayName: "Lint — pylint"
- script: |
    pip install cfn-lint
    cfn-lint template.yaml 2>/dev/null || true    
  displayName: "Lint — cfn-lint (CloudFormation, if present)"
  continueOnError: true

Node runtime

- script: npm ci && npx eslint src/
  displayName: "Lint — eslint"

Security scan stage steps

Python runtime

- script: |
    pip install pip-audit
    pip-audit -r requirements.txt --output json > pip-audit-results.json    
  displayName: "Security scan — pip-audit"
- task: PublishBuildArtifacts@1
  inputs:
    pathToPublish: pip-audit-results.json
    artifactName: security-scan
  displayName: "Publish scan results"

Node runtime

- script: |
    npm audit --json > npm-audit-results.json || true
    npm audit --audit-level=high    
  displayName: "Security scan — npm audit"
- task: PublishBuildArtifacts@1
  inputs:
    pathToPublish: npm-audit-results.json
    artifactName: security-scan
  displayName: "Publish scan results"

Build stage steps (zip packaging)

- script: |
    mkdir -p package
    # Python: install deps into package dir
    pip install -r requirements.txt -t ./package
    # Copy handler (adjust filename as needed)
    cp *.py ./package/
    # Remove dev/test artifacts
    find ./package -name "*.pyc" -delete
    find ./package -name "__pycache__" -type d -exec rm -rf {} + 2>/dev/null || true
    find ./package -name "*.dist-info" -type d -exec rm -rf {} + 2>/dev/null || true
    cd package && zip -r ../$(Build.BuildNumber).zip .    
  displayName: "Package Lambda — zip (Python)"
- task: PublishBuildArtifacts@1
  inputs:
    pathToPublish: $(Build.BuildNumber).zip
    artifactName: lambda-package
  displayName: "Publish Lambda artifact"

For Node runtime, replace the pip install/cp lines with:

- script: |
    npm ci --omit=dev
    zip -r $(Build.BuildNumber).zip . \
      --exclude "*.git*" \
      --exclude "*node_modules/.cache*" \
      --exclude "*test*" \
      --exclude "*.spec.*" \
      --exclude "*.test.*"    
  displayName: "Package Lambda — zip (Node)"

Build stage steps (container packaging)

Use the full azure-pipeline-docker steps for the container build. Reference the resulting image URI in the Lambda deploy step by passing --image-uri instead of --zip-file.

Deploy stage steps (aws-cli method)

- task: AWSCLI@1
  inputs:
    awsCredentials: <aws-service-connection-name>
    regionName: <aws-region>
    awsCommand: lambda
    awsSubCommand: update-function-code
    awsArguments: >-
      --function-name <function-name>
      --zip-file fileb://$(Pipeline.Workspace)/lambda-package/$(Build.BuildNumber).zip      
  displayName: "Deploy — update function code"

- task: AWSCLI@1
  inputs:
    awsCredentials: <aws-service-connection-name>
    regionName: <aws-region>
    awsCommand: lambda
    awsSubCommand: wait
    awsArguments: function-updated --function-name <function-name>
  displayName: "Deploy — wait for update"

- task: AWSCLI@1
  inputs:
    awsCredentials: <aws-service-connection-name>
    regionName: <aws-region>
    awsCommand: lambda
    awsSubCommand: publish-version
    awsArguments: --function-name <function-name>
  displayName: "Deploy — publish version"

- script: |
    VERSION=$(aws lambda list-versions-by-function \
      --function-name <function-name> \
      --query "Versions[-1].Version" \
      --output text)
    aws lambda update-alias \
      --function-name <function-name> \
      --name <alias-name> \
      --function-version "$VERSION"    
  displayName: "Deploy — update alias"
  env:
    AWS_DEFAULT_REGION: <aws-region>

Hard rules for Lambda

  • Always use OIDC service connection — never hardcode AWS_ACCESS_KEY_ID or AWS_SECRET_ACCESS_KEY in the pipeline YAML
  • Always wait for function-updated before publishing version — skipping this causes race conditions
  • Always update alias after publishing version — direct function invocation without alias is not acceptable
  • Zip packaging: always exclude .git, __pycache__, *.pyc, node_modules/.cache, test files
  • Shell variable expansion in AWSCLI task awsArguments requires >- (block scalar) not > to avoid newline issues