Knowledge Bank
Here you will find general information about Attini, such as:
- Common issues add fixes
- Glossary
- How to scale your Attini deployments in a bigger organization
- Information on why Attini is great!
Here you will find general information about Attini, such as:
The Attini Framework and the Attini CLI together create a way of working that helps you to manage your AWS resources using AWS CloudFormation.
A core concept in Attini is the complete isolation of IT environments. We achieve this by copying all deployment source files into the IT environment, then all the deployment logic is performed by serverless resources inside your IT environment. This means that every IT environment is self-sufficient.
With tools that run on virtual machines or in containers, it’s often too expensive and high maintenance to have a “worker node” running in every environment all the time, this means that you often run the worker nodes in a central location and share them cross environments. Even if you’re using a CI/CD SaaS service, you still have a central platform, you just don’t manage it yourself. These types of central platforms often result in scaling limitations and tight environment coupling.
Because Attini is 100% serverless, its easy and low cost to have one copy of all CI/CD resources per environment. This design also comes with performance advantages.
The Attini distribution is a zip archive that contains:
Attini distributions are inspired by how container images bundle all its dependencies into one image. Similarly, the Attini CLI helps you to package as many dependencies as possible into one distribution. This means that you will have all your templates, code, configuration, and any other files you might need, gathered in one place.
The Attini CLI also helps you to run scripts on a copy of your files, so you get a natural place in your workflow to:
The goal is to make the distribution as static as possible so that your deployment will be as predictable as possible.
It is of course possible to do all of these things during the deployment (using Attini runner, AWS Lambda, CodeBuild, ECS Task, or any other compute options available in your cloud environment) as well if you need to. But then you lose the guarantee that all of your deployments will look the same.
When we run multiple environments, we often have two contradicting requirements:
This is a contradiction because if we do things in one environment, that environment will divert from our other environments.
To work around this contradiction, we need to be able to do 3 things:
With Attini every environment has its own set CI/CD resources so it’s easy to individually work with one environment for development or incident mitigation (hotfix or rollback).
You can find discrepancies between environments by comparing distribution versions that are currently running in your environments. We recommend that you use a git commit (or part of the git commit) as your distribution id (or part of the id). This way you will also get a changelog via your git commit messages.
If you find discrepancies between environments, it’s easy to promote the distribution with the correct version to the out-of-date environment. Normally this means that we promote new features to production or other test environments (from development to staging), but it’s also very handy if you need to rollback a development environment after failed tests.
The pipeline that you are using when designing a hands-off deployment is critical for your success.
Here are some of the most important requirements:
The Attini deployment plan is always automatically created and updated by the Attini init deployment so it’s just as easy to maintain 1 deployment plan as 10 deployment plans.
The Attini deployment plan is an abstraction on AWS StepFunction with comes with a lot of advantages:
But the AWS StepFunction needs a few more features to manage all our requirements, so Attini added:
In addition to this, Attini have managed to make most of our deployment logic event-driven, which is a big performance improvement.
To make it easy to adopt Attini, we made 3 important design decisions:
Attini only uses your AWS credentials, so there is no need for another
login or SSO configuration, your current AWS IAM roles and users will
work out of the box (they might need the attini-cli-user-{region}
IAM
policy that is created by the attini-setup).
This also means that AWS CloudTrail will log everything Attini does, find mroe information here.
If you run all your build scripts via the package section in the attini-config. It will be easy for you to run the same code from your local computer that your build server does. This enables you to bypass git and your build server during development, which improves development speed.
The Attini CLI also has features that are designed to help you to mock your build server configuration so that your build scripts can run unchanged.
Because we moved all deployment logic from a central CI/CD platform (Build server, Deployment SaaS solution, etc), and because you can install the Attini CLI anywhere, you can always extend any tool you currently use with Attini.
To get started with Attini, see our Quick start.
You often want to have a central repository for your build artifacts. This example shows how to configure an S3 bucket to act as a central repository for Attini distributions.
We will go through:
This example is for GitHub actions, but the general architecture will work with any build server that integrates with git and AWS. You will just have to reconfigure a few things.
First, we need an S3 bucket with the following configuration.
Ensure you have AWS CloudTrail data events enabled for this bucket if you plan to use it in Production. If the distributions are tampered with, you want to know who did it.
We need a life cycle policy for the objects. There will always be a copy of the distributions inside every individual environment using it, so you don’t need to worry about removing distributions that might be needed for a rollback.
In the example below, we will delete the distributions after 365 days.
We need a bucket policy allowing application accounts to get the distributions.
The example below opens the bucket for the entire AWS Organization.
We need to give GitHub actions permission to upload an object to the bucket.
In the example below, I create a Managed Policy that I will use for an IAM User or an IAM Role.
AWSTemplateFormatVersion: 2010-09-09
Description: Example of and S3 bucket that can act as a central repository for attini distributions.
Parameters:
BucketName:
Type: String
Description: The repository (s3 bucket) name.
OrganizationId:
Type: String
Description: The id of your AWS Organization (o-xxxxxxxxxx). This will allow all AWS Accounts in your AWS Organization to get objects from the bucket.
Resources:
AttiniRepository:
Type: AWS::S3::Bucket
Properties:
BucketName: !Ref BucketName
BucketEncryption:
ServerSideEncryptionConfiguration:
-
ServerSideEncryptionByDefault:
SSEAlgorithm: AES256
VersioningConfiguration:
Status: Enabled
LifecycleConfiguration:
Rules:
-
Id: ExpirationInDays
Status: Enabled
ExpirationInDays: 356
-
Id: MultipartUploadLifecycleRule
Status: Enabled
AbortIncompleteMultipartUpload:
DaysAfterInitiation: 7
-
Id: NoncurrentVersionExpirationInDays
Status: Enabled
NoncurrentVersionExpirationInDays: 30
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
BucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket: !Ref AttiniRepository
PolicyDocument:
Statement:
-
Action:
- s3:GetObject
- s3:ListBucket
Effect: Allow
Resource:
- !GetAtt AttiniRepository.Arn
- !Sub ${AttiniRepository.Arn}/*
Principal: "*"
Condition:
StringEquals:
aws:PrincipalOrgID: !Ref OrganizationId
PushAttiniDistribution:
Type: AWS::IAM::ManagedPolicy
Properties:
ManagedPolicyName: push-attini-distribution
Description: This policy allows an IAM User or IAM Role to push distribution to the repository bucket
PolicyDocument:
Version: 2012-10-17
Statement:
- Action:
- s3:PutObject
Effect: Allow
Resource: !Sub ${AttiniRepository.Arn}/*
Outputs:
AttiniRepository:
Description: The name of the S3 bucket
Value: !Ref AttiniRepository
If your build server already has access to S3, you can skip this step.
You can give GitHub actions AWS access in 2 ways using IAM Role (OIDC) or with an IAM User.
Using the IAM Role is better because you want to have to manage API keys, so this is recommended for production use.
Using the IAM User is fast and easy, so for a POC, this opinion is ok.
push-attini-distribution
Managed Policy to your role.push-attini-distribution
Managed Policy in the template if you want to. Temporarily save the
“Access key ID” and “Secret access key” somewhere safe.AWS_ACCESS_KEY_ID
and the other
AWS_SECRET_ACCESS_KEY
and populate the values that you saved from
step 1.Create a file called attini-config.yaml
in the root of the repository.
It should look something like this:
distributionName: hello-world
package:
prePackage:
commands:
- attini configure set-dist-id --id ${GITHUB_SHA} # this command will set the Attini distribution to the git commit id
If you ever need to package (attini distribution package
) the
distribution on your local computer when doing development, you can mock
the GITHUB_SHA
environment variable using the flag
--environment-config-script
. In this script, you can add the shell
command export GITHUB_SHA=test-commit-id
.
In the root of your repository, create a file called
.github/workflows/build.yml
Now add the following code to the file:
on:
push:
branches:
- main
name: Build and push Attini distribution
jobs:
deploy:
name: Build and push
runs-on: ubuntu-latest
steps:
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: eu-west-1
- name: Install Attini CLI # Better to do this in the container image if it's possible
shell: bash
run: |
curl -fsSO https://docs.attini.io/blob/attini-cli/install-cli.sh
bash install-cli.sh -s
- name: Check out repository code
uses: actions/checkout@v2
- name: Package and upload the Attini distribution
shell: bash
run: |
# GITHUB_SHA is an environment variable which is our git commit id, which is a good value to use for the distribution id.
DISTRIBUTION_ID="${GITHUB_SHA}"
DISTRIBUTION_NAME="hello-world"
REPOSITORY_BUCKET_NAME="attini-repository-bucket"
attini distribution package . --name ${DISTRIBUTION_NAME}.zip
# If you upload the distribution to the path "/latest/" it easy to find the latest version.
aws s3 cp ${DISTRIBUTION_NAME}.zip s3://${REPOSITORY_BUCKET_NAME}/${DISTRIBUTION_NAME}/latest/${DISTRIBUTION_NAME}.zip
# You also want to save a copy with the DISTRIBUTION_ID in path so that you can easily get old versions.
aws s3 cp ${DISTRIBUTION_NAME}.zip s3://${REPOSITORY_BUCKET_NAME}/${DISTRIBUTION_NAME}/${DISTRIBUTION_ID}/${DISTRIBUTION_NAME}.zip
At the very least you want to change the values for aws-region
and
REPOSITORY_BUCKET_NAME
in the file.
Next time you push a change to the main branch, your distribution
will be packaged and uploaded to the s3 bucket to the location
/hello-world/${DISTRIBUTION_ID}/hello-world.zip
and
/hello-world/latest/hello-world.zip
.
You can, of course, name your distributions whatever you want and use any prefix or path in S3 that makes sense for your way of working, but having the distribution name and id in the S3 key is a good place to start.
You can also add additional steps that automatically log in to your Development AWS account and deploy the distribution there.
Now log in to your application account (for example, Development or Production) from your terminal, build server, or AWS CloudShell and run the following command:
attini deploy run s3://${REPOSITORY_BUCKET_NAME}/hello-world/${DISTRIBUTION_ID}/hello-world.zip
This will pull the distribution from the repository and deploy it to your current environment.
This changelog is no longer maintained, please see our releases on GitHub.
Date: 28 March 2023
Date: 11 March 2023
Date: 2 March 2023
Date: 17 February 2023
Added support for new features in the Attini framework version 1.6.0.
Recommended framework version 1.6.0 or higher
Date: 7 February 2023
attini dist inspect
command now shows the distribution version.Date: 26 January 2023
attini init-project
commands.Date: 20 January 2023
attini deploy continue
command.Date: 17 January 2023
Date: 5 January 2023
Date: 12 December 2022
--container-build
and
--environment-config-script
in the attini deploy run
commandDate: 9 December 2022
Date: 7 December 2022
Date: 30 November 2022
--disable-least-privilege-init-deploy-policy
option to
attini setup
command.Date: 21 November 2022
Date: 26 October 2022
Date: 19 October 2022
attini deploy continue
command to resume
deployments paused by the AttiniManalApproval.Date: 13 October 2022
attini deploy run
now have a smoother cross account
deployment experience. When deploying straight from an S3 bucket,
s3:GetBucketLocation
permissions is now required.attini deploy history
commandDate: 10 October 2022
attini deploy run
and attini deploy describe
. It will now print
outputs from different steps as well as any output from scripts
executed with the attini runner.--json
option to attini deploy run
,
attini deploy describe
and attini package
commands.Date: 20 September 2022
attini context
is now attini environment context
.attini distribution
parent command.attini package
is now attini distribution package
.attini distribution inspect
command.attini distribution download
command.--environment
option to the attini context
command.--distribution-name
option to the attini context
command.attini ops
parent command.attini report rogue-stacks
is now attini ops rogue-stacks
.attini export-logs
is now attini ops export-logs
.attini delete-stack-resource
is now
attini ops delete-stack-resource
.--delete-stack
flag to the
attini delete-stack-resource
command.Date: 1 September 2022
Date: 31 August 2022
attini update-cli
command. It will update the CLI...attini environment list
command will now print errors in yaml
or json format.Date: 22 August 2022
Date: 05 August 2022
attini context
command. The timestamp for the
latest deployment will now print the correct format.Date: 22 June 2022
attini context
command. Will now correctly show
distributions even if the StepFunction logs have been cleared (after
90 days). This required the distribution to be deployed with version
1.2.54 or later of the Attini framework.attini context
command.--force
option for deployment commands. This will make
the CLI skip the confirmation prompt.Date: 10 June 2022
Date: 31 May 2022
Date: 21 April 2022
Date: 30 Mars 2022
attini package
would freeze if executed
in an environment with 2 or less available threads.attini package
would crash if executed
in an environment without the "SHELL" environment variable set.Date: 22 Mars 2022
attini deploy describe
now behave as intended.Date: 22 Mars 2022
Requires Attini Framework version 1.2.8 or higher.
Date: 2 Mars 2022
attini report rogue-stacks
now behave as intended when
there are multiple environments in the same account.Date: 14 February 2022
--environment-config-script
option is now required to be located
in the distribution project folder, or in a subdirectory to it.--environment-config-script
option is now relative from where the command is executed, not
relative to the distribution root.--environment-config-script
option.Date: 8 February 2022
attini deploy run
and
attini package
commands. You can now specify an image in your
attini-config that will be used for packaging your distributionattini report rogue-stacks
command to help manage stacks no
longer managed by a distribution.attini delete-stack-resources
command that will remove any
resources Attini created in order to manage a Cloudformation stack.
Will not delete the actual stack.attini deploy run
and attini package
commands will now put the
finished distribution in a folder called attini_dist inside the
distributions project folder.Date: 31 January 2022
Requires Attini Framework version 1.2.8 or higher.
attini deploy describe
command to follow deployment started
by others or get information about previous deployments.attini setup
command no longer require --contact-email.Date: 14 January 2022
Requires Attini Framework version 1.2.0 or higher.
attini context
command will now print what version of the Attini
framework is installed in your AWS account.attini init-project
command with various subcommands to help
get started with new projects.attini deploy history
command now prints in yaml format by
default.attini deploy history
command no longer require environment
to be specified if there is only one environment in account.attini deploy rollback
command no longer require environment
to be specified if there is only one environment in account.attini deploy run
command no longer require environment to
be specified if there is only one environment in account.Date: 21 December 2021
attini environment create <env-name>
command.attini environment remove <env-name>
command.attini environment list
command.attini context
command to get information about the current
environments/account. Only works for distributions deployed with
version 1.1.1 or greater of the Attini framework.Date: 9 December 2021
Date: 16 November 2021
attini package --environment-config-script
option.attini deploy run --environment-config-script
option.attini setup
will no longer require user to enter the
--create-init-deploy-default-role
or --init-deploy-role-arn
when
updating the framework.attini setup
when installing
Attini for the first time.Date: 16 November 2021
attini setup --create-deployment-plan-default-role
flag.attini setup --create-init-deploy-default-role
flag.Date: 8 November 2021
attini package
command.attini setup --accept-license-agreement
flag.attini setup --keep-version
flag.attini configure set-init-deploy-parameter
command to easily
set/update parameters for init-deploy.attini configure set-init-deploy-tag
command to easily
set/update tags for init-deploy.attini configure set-parameter
command to easily set/update
parameters for CloudFormation deployments.attini configure set-tag
command to easily set/update tags
for CloudFormation deployments.attini configure set-dist-id
command easily set/update
distribution id.Date: 14 March 2023
Date: 6 March 2023
Date: 2 March 2023
Date: 20 February 2023
Date: 17 February 2023
AttiniCdk Step was added.
Changed the configuration of the default runner to:
"GiveAdminAccess" parameter was added to the Attini setup as a replacement for the deprecated "UseAdministratorAccessForDeployingCloudformation" parameter.
If you have onboarded the Attini framework with the configuration
UseAdministratorAccessForDeployingCloudformation=true
, you need
to set GiveAdminAccess=true
next time you update the framework.
This is easily done with the command
attini setup --give-admin-access
.
Recommended CLI version 1.5.5 or higher
Date: 10 February 2023
/
prefixDate: 31 January 2023
Date: 26 January 2023
Date: 17 January 2023
Date: 9 January 2023
Date: 5 January 2023
Date: 7 December 2022
Date: 21 November 2022
Date: 21 November 2022
Date: 26 October 2022
Date: 19 October 2022
Date: 12 October 2022
Date: 10 October 2022
Date: 20 September 2022
Date: 2 September 2022
Date: 1 September 2022
Date: 22 August 2022
Date: 5 August 2022
Date: 22 June 2022
attini context
CLI command.Date: 10 June 2022
Date: 1 June 2022
Date: 21 April 2022
Date: 22 Mars 2022
Date: 1 Mars 2022
Date: 11 February 2022
Date: 31 January 2022
Date: 14 January 2022
Requires Attini CLI version 1.1.0 or higher.
Date: 22 December 2021
Date: 30 November 2021
attini setup
when installing
Attini for the first time.Date: 23 November 2021
cfnOutput
and cfnGlobalOutput
section.Date: 16 November 2021
This change will not break any of your current deployments but next time
you update attini-setup
CloudFormation stack you will need to apply
new configuration.
attini-setup
parameters.Date: 8 November 2021
I get the error
Text '2021-05-04T18:35:49UTC' could not be parsed at index 19
when
using the CLI with AWS SSO credentials.
If you authenticate with an old version AWS CLI version, this error occurs. Please update the AWS CLI.
For more information about this issue, see aws-sdk-java-v2/issues/2190.
If you update the Attini CLI and the installation looks ok, but it takes no effect, it’s probably because you have 2 Attini CLI installed and the “old” installation is located before your “new” installation on your system PATH.
Run the command: type attini
And verify that the Attini CLI path is actually the one you updated.
The Attini CLI is currently only compiled for x86_64 CPU architecture for Mac, so you need Rosetta 2 for it to work.
You can install Rosetta using the command:
/usr/sbin/softwareupdate --install-rosetta --agree-to-license
Note: The first time you run the Attini CLI after the Rosetta installation, it will take a few extra seconds.
If you get the error zsh: killed
on all the Attini CLI commands after
an update, you have to delete the Attini CLI and reinstall it. See the
rm ${PATH_TO_CLI}/attini;
part of the installation Attini CLI command.
If you are trying to enable Attini CLI autocomplete via
source <(attini generate-completion)
command and it fails like this:
sh: syntax error near unexpected token
('`
Run this command instead:
attini generate-completion > /tmp/attini-generate-completion; source /tmp/attini-generate-completion; rm -f /tmp/attini-generate-completion
If the autocompletion for the CLI does not work, make sure you are not
running an old version of bash. Attini autocompletion required bash
version 4 or later. To update bash on a Mac with homebrew run
brew install bash
.
A frozen deployment plan is a consequence of the Attini resources or AWS Service integrations not responding to the underlying AWS StepFunction. This can be due to issues (for example, throttling) with some underlying services, like AWS Lambda or Amazon SNS.
If you have a frozen deployment plan, you should retry your deployment. The Attini framework will always cancel the old deployments before starting a new one, so there is no risk for zombie deployments.
If you have an old CloudFormation stack that you include in an Attini deployment plan and the first update of that CloudFormation stack fails, the Attini deployment will freeze. The workaround is to not do any updates to the CloudFormation stack on the first run, that way the CloudFormation stack will not fail.
Error message:
Resource handler returned message: "Invalid State Machine Definition: SCHEMA_VALIDATION_FAILED:
The field Type should have one of these values: [Task, Wait, Pass, Succeed, Fail, Choice, Parallel, Map] at
This issue can happen in 3 common scenarios:
Attini deployment origin is an S3 bucket that will be created by
.
It is is responsible for receiving distributions and trigger the
init deploy lambda. The s3 bucket will be called
attini-deployment-origin-${region}-${accountId}
, and you will
find it in your AWS account after you onboard the attini-setup.
There will be one Attini deployment origin bucket per AWS account and region.
The artifacts will be deleted according to your artifact life-cycle policy.
An S3 bucket that will be created by attini-setup
that is responsible for managing all the artifacts from your
distribution and making them available to your environment. The S3
bucket will be called attini-artifact-store-${region}-${accountId}
, and you will find
it in your AWS account after you onboard the attini-setup.
If your deployment needs temporary storage, you can use the Attini
artifact store with key prefix attini/tmp/
.
Find more info here
There will be one attini artifact store bucket per AWS account and region.
All the artifacts from a distribution will be uploaded to the
bucket with the prefix
/${AttiniEnvironmentName}/${DistributionName}/${DistributionNameId}/distribution-origin/
The artifacts will be deleted according to your artifact life-cycle policy.
When a distribution is being uploaded to an Attini Deployment Origin Bucket, it triggers a deployment which tells the Attini Framework to start. The Attini Framework will:
attini-config.json
, attini-config.yaml
or
attini-config.yml
and it contains the distribution name, id,
package config, tags and Init deploy configuration and more.