Attini Configuration

The Attini Framework will look for a file in your distributions root directory called attini-config.json, attini-config.yml or attini-config.yaml. Only one of these files is allowed.

This file is required, and it should at least contain a distributionName.

distributionName: String
distributionId: String
version: String
distributionTags:
  String: String
dependencies:
  - distributionName: String
    version: String
initDeployConfig:
  template: String
  stackName: String
  forceUpdate: Boolean
  tags:
    String: String
  variables:
    String:
      String: String
  parameters:
    String:
      String: String
package:
  container:
    image: String
    loginCommands:
      - String
    options:
      - String
  prePackage:
    commands:
      - String
  postPackage:
    commands:
      - String
{
  "distributionName": "String",
  "distributionId": "String",
  "version": "String",
  "distributionTags": {
    "String": "String"
  },
  "dependencies" : [
    {
      "distributionName" : "String",
      "version" : "String"
    }
  ],
  "initDeployConfig": {
    "template": "String",
    "stackName": "String",
    "forceUpdate": "Boolean",
    "tags":{
      "String": "String"
    },
    "variables": {
      "String": {
        "String": "String"
      }
    },
    "parameters": {
      "String": {
        "String": "String"
      }
    }
  },
  "package": {
    "container": {
      "image": "String",
      "loginCommands": [
        "String"
      ],
      "options": [
        "Sting"
      ]
    },
    "prePackage": {
      "commands": [
        "String"
      ]
    },
    "postPackage": {
      "commands": [
        "String"
      ]
    }
  }
}

distributionName

Type: String

Minimum 2 and maximum 128 characters. Allowed characters: “a-z”, “A-Z”, “0-9” and “-_.”.

If you don’t have a good name in mind, using your Git repository name is a good place to start. But this is not a requirement, sometimes a distribution consists of a combination of many Git repository’s and/or external resources, and sometimes it makes sense to split a repository up into many different distributions.

Required: Yes

distributionId

Type: String

Minimum 2 and maximum 128 characters. Allowed characters: “a-z”, “A-Z”,“0-9” and “-_.”.

We recommend automatically setting the distributionId using the package section in the attini-config (see example below). This will make it easy for you to use the same package logic on your local computer as you use on your build server. The Git commit id is a good value for the distributionId because it will be easy to see what code runs in your environments. It can also be a good idea to append a timestamp to the id so that you can re-build the same commit if needed.

If you need to mock anything for your local builds (like an environment variable), see the --environment-config-script flag in the attini distribution package command.

Default: Random GUID

Required: No

version

Type: String

A semantic version for your distribution.

The version is intended to be a human-readable and sequential value to identify your distribution. It’s different from the distributionId whose primary purpose is to be a unique identifier.

It’s recommended to configure the version for distributions that are intended for production. See the --distribution-version, -v flags in the attini distribution package command.

Required: No

distributionTags

Type: Map<String,String>

Metadata that is relevant to your organization or distribution, some normal use-cases include:

  • Keep track of Git branch that was the source of the distribution.
  • Build time.
  • Build agent/build container.
  • If your distribution consists of a combination of Git repositories, this is a good place to store the Git commit of those repositories.

See limitations

Required: No

dependencies

Type: List<Dependency>

A list of distributions that this distribution is dependent on. Attini will validate that the dependency is present in the environment. Attini will also include a URL to the dependencies output in the deployment plan payload (assuming it contains one).

Find more information here.

Required: No

initDeployConfig

Type: InitDeployConfig

Configuration for the Init Deploy.

Within this object, you can use distributionName and environment as sub-string parameters, see examples below.

Required: No

package

Type: Package

Under the package section, you can configure automation you want to execute when packaging a distribution using the attini distribution package command. The attini deploy run command will also perform a package assuming the path supplied points is to a directory.

The Attini CLI will create a temp working directory when packaging a distribution. Therefore, you can manipulate any resources without it affecting the original files.

The path to the temp directory will be stored in the ATTINI_WORK_DIR environment variable during the execution of package commands.

Required: No

Examples

Configuration examples

Simple example
Simple example
distributionName: network
distributionId: 3957876a98566823744050eef132c133536ea32b
distributionTags:
  branch: feature/add-nlb
{
  "distributionName": "network",
  "distributionId": "3957876a98566823744050eef132c133536ea32b",
  "distributionTags": {
    "Version": "1.1.2",
    "Branch": "feature/add-nlb"
  }
}
Full example
distributionName: platform
distributionId: 67e13cb77e9139929057602a46229cf0162c8747
version: 1.0.1
distributionTags:
  owner: carl
  branch: hotfix/bugfix
dependencies:
  - distributionName: infra
    version: ">1.0.0"
initDeployConfig:
  template: pipeline.yaml
  stackName: "${environment}-${distributionName}-init-deploy"
  variables:
    default:
      configPath: /my/default/config.json
    dev:
      configPath: /my/dev/config.json
  parameters:
    default:
      containerTag: latest
    dev:
      containerTag: 1.0.11
  tags:
    dev:
      costCenter: Development
    prod:
      costCenter: Sales
  package:
    container:
      image: 123424324422.dkr.ecr.eu-west-1.amazonaws.com/my-build-images:latest
      loginCommands:
        - export AWS_PROFILE=Shared
        - aws ecr get-login-password --region eu-west-1 | docker login --username AWS --password-stdin 123424324422.dkr.ecr.eu-west-1.amazonaws.com
      options: # Here you add options for the docker run command.
        - -v $HOME/.aws:/root/.aws:rw # this command will copy your local aws credentials to the container (if the container runs as root).
    prePackage:
      commands:
        - echo $ATTINI_WORK_DIR
        - export AWS_PROFILE=MyProfile
        - attini configure set-dist-id --override --random
        - attini configure set-tag --key version --value echo `1.0.2`

    postPackage:
      commands:
        - echo "done with package"
{
  "distributionName": "platform",
  "distributionId": "67e13cb77e9139929057602a46229cf0162c8747",
  "version": "1.0.1",
  "distributionTags": {
    "owner": "carl",
    "branch": "hotfix/bugfix"
  },
  "dependencies" : [
    {
      "distributionName" : "String",
      "version" : "String"
    }
  ],
  "initDeployConfig": {
    "template": "pipeline.yaml",
    "stackName": "${environment}-${distributionName}-init-deploy",
    "variables": {
      "default": {
        "configPath": "/my/default/config.json"
      },
      "dev": {
        "configPath": "/my/dev/config.json"
      }
    },
    "parameters": {
      "default": {
        "containerTag": "latest"
      },
      "dev": {
        "containerTag": "1.0.11"
      }
    },
    "tags": {
      "dev": {
        "costCenter": "Development"
      },
      "prod": {
        "costCenter": "Sales"
      }
    }
  },
  "package": {
    "container": {
        "image": "123424324422.dkr.ecr.eu-west-1.amazonaws.com/my-build-images:latest",
        "loginCommands": [
          "export AWS_PROFILE=Shared",
          "aws ecr get-login-password --region eu-west-1 | docker login --username AWS --password-stdin 123424324422.dkr.ecr.eu-west-1.amazonaws.com"
        ],
        "options": [
          "-v $HOME/.aws:/root/.aws:rw"
        ]
    },
    "prePackage": {
      "commands": [
        "echo $ATTINI_WORK_DIR",
        "export AWS_PROFILE=MyProfile",
        "attini configure set-dist-id --override --random",
        "attini configure set-tag --key version --value echo `1.0.2`"
      ]
    },
    "postPackage": {
      "commands": [
        "echo \"done with package\""
      ]
    }
  }
}

Examples with variables

If I’ve configured my variables in the attini-config like the example below.

initDeployConfig:
  variables:
    default:
      myConfigDirectory: defaultConfigDirectory
      stackNamePrefix: sandbox
    dev:
      myConfigDirectory: devConfigDirectory
      stackNamePrefix: dev

The following will resolve to a valid AttiniCfn configuration file.

extends: ${myConfigDirectory}/file.yaml
parameters:
  ParameterKey: ParameterValue
tags:
  Key: Value

The following will also be a valid AttiniCfn step.

StepName:
  Type: AttiniCfn
  Properties:
    StackName: ${stackNamePrefix}-hello-world-lambda
    Template: /lambda.yaml

If you want to combine AWS CloudFormation Fn::Sub with Attini variables, the following syntax will work.

StepName:
  Type: AttiniCfn
  Properties:
    StackName:
      Fn::Sub:
        - ${AttiniVariable}-${CloudFormationParameter}-hello-world-lambda
        - AttiniVariable: ${stackNamePrefix}
          CloudFormationParameter: !Ref Parameter # this assumes that there is a CloudFormation Parameter called "Parameter"
    Template: /lambda.yaml

Subsections of Attini Configuration

Dependency

Find more information here.

distributionName: String
version: String
{
  "distributionName" : "String",
  "version" : "String"
}

distributionName

Type: String

A name of a distribution the current distribution is dependent on.

Required: Yes

version

Type: String

The version of the dependency. Specified using the same rules as NPM.

This can be used to make sure that all dependencies have the correct versions.

Required: No

Init Deploy Config

template: String
stackName: String
forceUpdate: Boolean
tags:
  String: String
variables:
  String:
    String: String
parameters:
  String:
    String: String | import
{
  "template": "String",
  "stackName": "String",
  "forceUpdate": "Boolean",
  "tags":{
    "String": "String"
  },
  "variables": {
    "String": {
      "String": "String"
    }
  },
  "parameters": {
    "String": {
      "String": "String" | "import"
    }
  }
}

template

Type: String

The path to the init deploy template.

Required: No

stackName

Type: String

Init deploy stack name.

Required: No

forceUpdate

Type: Boolean

If true then the init-stack will always update, even if there is no change.

Default: false

Required: No

tags

Type: Map<String,String>

Init deploy stack tags.

Required: No

variables

Type: Map<String,Map<String,String>>

Global variables for the init deploy stack. Will be passed as variables to every AttiniCfn step in the deployment plan. The key should be an environment name (dev, stage, prod, etc) or default.

Anything under default will be used only if the variable is not configured for the current environment.

How are variables different from parameters?

Variables only work within the context of AttiniCfn and its associated configuration files. If you specify Variables with the same keys in a AttiniCfn step, it will override variables in the attini-config.

Parameters are normal AWS CloudFormation parameters to the init deploy stack

Within initDeployConfig in your attini-config file there are a few variables that are always available.

environment

Will always transform to the current environment name.

Usage: ${environment}

distributionName

Will always convert to the current distributionName name.

Usage: ${distributionName}

See examples with variables.

Required: No

parameters

Type: Map<String,Map<String,String>> | Map<String,Map<String,Import>>

Parameters for the init deploy stack, the top level key key is the environment name (dev, stage, prod, etc) or default.

Anything under default will be used only if the parameter is not configured for the current environment.

Under each environment, you can configure a key-value map, where the key is the parameters name.

If your distribution has a dependency on another distribution, then you can import values directly from its output.

Example
initDeployConfig:
  parameters:
    default:
      lambdaRam: 512
      vpcId:
        sourceType: Distribution
        source:
          name: network
          mapping: $.vpc.vpcId
    dev:
      lambdaRam: 1028
    prod:
      lambdaRam: 1540

Required: No

Examples with variables

If I have configured my variables in the attini-config like the example below.

initDeployConfig:
  variables:
    default:
      myConfigDirectory: defaultConfigDirectory
      stackNamePrefix: sandbox
    dev:
      myConfigDirectory: devConfigDirectory
      stackNamePrefix: dev

The following will resolve to a valid AttiniCfn configuration file.

extends: ${myConfigDirectory}/file.yaml
parameters:
  ParameterKey: ParameterValue
tags:
  Key: Value

The following will also be a valid AttiniCfn step.

StepName:
  Type: AttiniCfn
  Properties:
    StackName: ${stackNamePrefix}-hello-world-lambda
    Template: /lambda.yaml

If you want to combine AWS CloudFormation Fn::Sub with Attini variables, the following syntax will work.

StepName:
  Type: AttiniCfn
  Properties:
    StackName:
      Fn::Sub:
        - ${AttiniVariable}-${CloudFormationParameter}-hello-world-lambda
        - AttiniVariable: ${stackNamePrefix}
          CloudFormationParameter: !Ref Parameter # this assumes that there is a CloudFormation Parameter called "Parameter"
    Template: /lambda.yaml

Subsections of Init Deploy Config

Import

sourceType: String
source: source
{
  "sourceType": "String",
  "source": "source"
}

sourceType

Type: String

Only supported value is Distribution

Required: Yes

source

Type: source

The distribution name that you want to import the value from.

Required: Yes

Subsections of Import

Source

name: String
mapping: String
{
  "name": "String",
  "mapping": "String"
}

name

Type: String

The distribution name that you want to import the value from.

Required: Yes

mapping

Type: String

The path to the value you want to import. The path follows the JSONPath syntax.

Hint

Run command attini deploy output with the Attini CLI to see a distributions output.

Required: Yes

Package

container:
  image: String
  loginCommands:
    - String
  options:
    - String
prePackage:
  commands:
    - String
postPackage:
  commands:
    - String
{
  "container": {
    "image": "String",
    "loginCommands": [
      "String"
    ],
    "options": [
      "String"
    ]
  },
  "prePackage": {
    "commands": [
      "String"
    ]
  },
  "postPackage": {
    "commands": [
      "String"
    ]
  }
}

container

Type: Container

Configure this if you want to package your distribution using a container.

Required: No

prePackage

Type: PrePackage

Instructions that will be executed after the source files are copied to a temporary directory, but before the files are pacadged into a distribution.

Required: No

postPackage

Type: List<String>

List of shell commands that is executed before the final distribution is created but before the final distribution is copied from the temp working directory.

Useful if you for example want to move the distribution somewhere after the packaging is done.

Required: No

Subsections of Package

Container

image: String
loginCommands:
  - String
options:
  - String
{
  "image": "String",
  "loginCommands": [
    "String"
  ],
  "options": [
    "String"
  ]
}

image

Type: String

An image URI which will be used to fetch a container for packaging your distribution.

Useful if you, for example, want to build your distribution locally inside a container that mimics your build server.

Note

For this configuration to take effect you need to apply the --container-build or -cb flag to the attini distribution package (or attini deploy run) command.

Required: No

loginCommands

Type: List<String>

List of shell commands that will be executed before the docker run command when using container builds.

Should only be used to log in to the image repository if the image needs to be downloaded as they are executed before the container is started.

Note

For this configuration to take effect, you need to apply the --container-repository-login or -crl flag to the attini distribution package (or attini deploy run) command.

Required: No

options

Type: List<String>

Command-line options you want to add the docker run command the Attini CLI generates and run for you.

Useful if you need to configure anything specific for your build container, for example, if you need to transfer AWS credentials to the container (-v $HOME/.aws:/root/.aws:rw).

Required: No

Post Package

commands:
  - String
{
  "commands": [
    "String"
  ]
}

postPackage

Type: List<String>

List of shell commands that is executed after the final distribution is created.

Useful if you, for example, want to move the distribution somewhere after the packaging is done.

Required: No

Pre Package

commands:
  - String
{
  "commands": [
    "String"
  ]
}

commands

Type: List<String> List of shell commands that are executed before distribution is created.

These commands are run with set -eo pipefail configuration so that the packaging will fail quickly if an error occurs. To revert this configuration (and ignore errors in your scrips), begin your commands with the line: set +eo pipefail.

Useful if you, for example, want to configure the distribution (see attini configure command) or fetch external resources to be included in the distribution.

Required: Yes