# Introduction

Deployment targets offer a scalable and flexible way to deploy Takomo configurations across multiple accounts and regions.

{% hint style="info" %}
Deployment targets functionality builds on top of Takomo's stack configuration and deployment features. Before learning more about deployment targets, you should have a good understanding of Takomo's basics.
{% endhint %}

## Deployment targets

A deployment target represents a target where to deploy CloudFormation stacks. Targets can reside in different accounts and regions. Each target has a name that you use to refer to it.

## Deployment groups

You use deployment groups to group deployment targets with similar configurations. You can nest deployment groups to create tree-like hierarchies where child groups inherit configuration from their parents.

Deployment targets inherit configuration from the deployment group they belong to. Both the child deployment groups and deployment targets can also override all or parts of the configuration they inherit.

## Config sets

You use config sets to specify stacks you want to deploy to your deployment targets. Config sets are regular Takomo stack configurations.

You can attach config sets to deployment groups and deployment targets. Deployment targets inherit config sets attached to the deployment group they belong to.

## Variables

You can specify variables for deployment groups and targets. Deployment groups inherit variables from their parents, and targets inherit variables from the deployment group they belong to. The variables are useful when you want to deploy your stacks to multiple targets with different parameters..

Takomo exposes variables attached to a deployment target when it gets deployed. You can refer to the variables in stack and stack group configuration files and stack templates the same way you would refer to standard command-line variables.

## Schemas

You can validate deployment targets you have defined in the deployment configuration using custom [Joi validation](https://joi.dev/) schemas.&#x20;


# Directory structure

You provide configuration for your deployment targets in a deployment configuration file. By default, Takomo looks **targets.yml** file from the **deployment** directory.

```bash
.
├─ stacks
├─ templates
├─ helpers
├─ partials
├─ resolvers
├─ hooks
├─ schemas
├─ config-sets
└─ deployment
   └─ targets.yml
```


# Deployment groups

You specify deployment groups with the `deploymentGroups` property. It is an object whose keys are paths to deployment groups, and values contain configuration for the corresponding deployment group.

#### Example

Here's an example of deployment configuration with five deployment groups:

{% code title="deployment/targets.yml" %}

```yaml
deploymentGroups:
  all/shared: {}
  all/application/dev: {}
  all/application/prod: {}
```

{% endcode %}

The deployment groups in this example form the following hierarchy:

```bash
all
├─ shared
└─ application
   ├─ dev
   └─ prod
```

There is one root-level deployment group named **all**, and under it, there are deployment groups **all/shared** and **all/application**. The **all/application** deployment group has two children: **all/application/dev** and **all/application/prod**.


# Deployment targets

You use deployment group's `targets` property to specify its targets. Each target must have a `name` that is unique among all targets in the deployment configuration.

#### Example

Let's continue the example we started earlier and add two targets to **all/application/dev** deployment group, and one to **all/application/prod** and **all/shared** deployment groups.&#x20;

{% code title="deployment/targets.yml" %}

```yaml
deploymentGroups:
  all/shared:
    targets:
      - name: infra
  all/application/dev:
    targets:
      - name: dev-environment
      - name: sandbox
  all/application/prod:
    targets:
      - name: prod-environment
```

{% endcode %}

Now, we have four deployment targets: **infra**, **dev-environment,** **sandbox** and **prod-environment**.


# Config sets

## Config set directory and files

Config sets are standard Takomo stack configurations‚ but instead of the stacks directory, you put them to subdirectories under the **config-sets** directory. The directory names become the names of the config sets, and you use them to refer to the config sets in the deployment configuration file.

You place your stack group and stack configuration files directly in the config set directory's root. Other standard Takomo directories such as the templates directory remains in the project's root. &#x20;

#### Example

Here is an example with two config sets named **networking** and **security**.

```bash
.
├─ templates
├─ config-sets
│  ├─ networking
│  │  ├─ private
│  │  │  └─ tgw.yml 
│  │  └─ public 
│  │     └─ load-balancer.yml 
│  └─ security
│     ├─ config.yml
│     └─ audit.yml 
└─ deployment
   └─ targets.yml
```

The networking config set has two stack groups named **private** and **public**, and under them, there are stacks **tgw\.yml** and **load-balancer.yml**.

The security config set has a stack group configuration (config.yml) and **audit.yml** stack.  &#x20;

## Attaching config sets

You can attach config sets to deployment targets or deployment groups. Deployment groups and targets inherit config sets from the deployment group they belong to. They can add config sets of their own but can't remove the config sets they inherited.

You attach config sets to deployment groups and targets by providing single config set name or a list of config set names in their `configSets` property.

#### Example

Let's attach the two config sets (**networking** and **security**) from the previous example to some deployment groups and targets in our deployment configuration.

{% code title="deployment/targets.yml" %}

```yaml
deploymentGroups:
  all:
    configSets: security
  all/shared:
    targets:
      - name: infra
  all/application:
    configSets: networking
  all/application/dev:
    targets:
      - name: dev-environment
      - name: sandbox
  all/application/prod:
    targets:
      - name: prod-environment
```

{% endcode %}

We attached the **security** config set to the **all** deployment group. As **all** is the root deployment group, all of our targets inherit the security config set from it. We then attached the **networking** config set to the **all/application** group.


# Variables

You can specify variables for deployment groups and deployment targets with the `vars` property. It is an object whose keys are variable names and values contain the values for the corresponding variables. Variable values can be strings, numbers, booleans, objects or lists of the aforementioned types.&#x20;

Deployment groups inherit variables from their parents, and deployment targets inherit variables from the deployment group they belong to.

If you want to apply variables to all deployment groups and targets, you can define the `vars` property at the top-level of the deployment configuration.

#### Example

Here's how you could use variables:

{% code title="deployment/targets.yml" %}

```yaml
vars:
  cost-center: 12345
  budget: 2000

deploymentGroups:
  all:
    configSets: security
  all/shared:
    vars:
      cost-center: 10000 
      budget: 500 
    targets:
      - name: infra
  all/application:
    configSets: networking
    deploymentRoleName: deployer
    vars:
      cost-center: 600
  all/application/dev:
    targets:
      - name: dev-environment
        vars:
          environment: dev
      - name: sandbox
        vars:
          environment: sandbox
  all/application/prod:
    targets:
      - name: prod-environment
        vars:
          environment: prod
          budget: 3000
```

{% endcode %}

We specify **cost-center** and **budget** variables to be applied to all deployment groups and targets using the top-level `vars` property. The **all/shared** deployment group overrides both of these variables, and **all/application** overrides only the **cost-center**. The targets located under the **all/application** specify a new variable named **environment**. The **prod-environment** target overrides the **budget** variable.&#x20;


# Schemas

You can validate deployment targets you have defined in the deployment configuration using custom [Joi validation](https://joi.dev/) schemas.&#x20;

{% hint style="info" %}
Take a look at [custom validation schemas documentation](https://docs.takomo.io/advanced-topics/custom-validation-schemas) to learn more about custom schemas.
{% endhint %}

You associate schemas with a deployment group using the `targetsSchema` property, which accepts a single schema or a list of schemas. Takomo uses the schemas associated with a deployment group to validate all deployment targets located under it in the deployment groups hierarchy.

You can also specify the `targetsSchema` property at the top-level of the deployment configuration. Top-level schemas are applied to all deployment groups.

The schemas used to validate deployment targets must be [object schemas](https://joi.dev/api/?v=17.4.0#object) because the deployment targets to validate are given as an object whose keys are paths to deployment targets in the deployment groups hierarchy, and values are configurations of the deployment target themselves.&#x20;

#### Example

Let's add two custom validation schemas. One to validate that if the budget variable is given, it must be a non-negative number, and another to validate that the environment variable is given and is one of the allowed values. The schemas are located in the **schemas** directory.

{% code title="schemas/budget.js" %}

```javascript
module.exports = {
  name: "budget",
  init: ({ joi }) =>
    joi.object().pattern(
      /^/,
      joi
        .object({
          vars: joi
            .object({
              budget: joi.number().min(0),
            }),
        })
        .unknown(true),
    ),    
}
```

{% endcode %}

{% code title="schemas/environment.js" %}

```javascript
module.exports = {
  name: "environment",
  init: ({ joi }) =>
    joi.object().pattern(
      /^/,
      joi
        .object({
          vars: joi
            .object({
              environment: joi.valid("dev", "sandbox", "prod"),required(),
            }),
        }).required()
        .unknown(true),
    ),    
}
```

{% endcode %}

With these schemas available, we can modify our deployment configuration and refer to the schemas with their names.

{% code title="deployment/targets.yml" %}

```yaml
vars:
  cost-center: 12345
  budget: 2000

targetsSchema: budget

deploymentGroups:
  all:
    configSets: security
  all/shared:
    vars:
      cost-center: 10000 
      budget: 500 
    targets:
      - name: infra
  all/application:
    configSets: networking
    targetsSchema: environment
    vars:
      cost-center: 600
  all/application/dev:
    targets:
      - name: dev-environment
        vars:
          environment: dev
      - name: sandbox
        vars:
          environment: sandbox
  all/application/prod:
    targets:
      - name: prod-environment
        vars:
          environment: prod
          budget: 300
```

{% endcode %}

We use the **budget** schema for all deployment targets and the **environment** schema for the targets under the **all/applications** deployment group.&#x20;

With this configuration, the object that gets passed to our custom schemas looks like this:

```yaml
all/shared/infra:
  deploymentGroupPath: all/shared
  name: infra
  configSets:
    - security
  vars:
    cost-center: 10000 
    budget: 500   
all/application/dev/dev-environment:
  deploymentGroupPath: all/application/dev
  name: dev-environment
  configSets:
    - security
    - networking
  vars:
    cost-center: 12345
    budget: 2000
    environment: dev  
all/application/dev/sandbox:
  deploymentGroupPath: all/application/dev
  name: sandbox
  configSets:
    - security
    - networking
  vars:
    cost-center: 12345
    budget: 2000
    environment: sandbox  
all/application/prod/prod-environment:
  deploymentGroupPath: all/application/prod
  name: prod-environment
  configSets:
    - security
    - networking
  vars:
    cost-center: 12345
    budget: 300 
    environment: prod
```


# Target account

There are two options to specify to which account Takomo should deploy stacks defined in a deployment target's config sets.

* Provide a complete IAM role ARN in the `deplomentRole` property.
* Provide the target account's id in the `accountId` property and the name of the IAM role in the `deploymentRoleName` property.

The first option takes precedence over the second one.

#### Example

Let's specify target accounts for our deployment targets.

{% code title="deployment/targets.yml" %}

```yaml
vars:
  cost-center: 12345
  budget: 2000

targetsSchema: budget

deploymentGroups:
  all:
    configSets: security
  all/shared:
    targets:
      - name: infra
        deploymentRole: arn:aws:iam::123456789012:role/ExampleAdmin
  all/application:
    configSets: networking
    targetsSchema: environment
    deploymentRoleName: deployer
  all/application/dev:
    targets:
      - name: dev-environment
        accountId: "222244446666"
      - name: sandbox
        accountId: "111133335555"
  all/application/prod:
    targets:
      - name: prod-environment
        accountId: "333355557777"
```

{% endcode %}

The **infra** deployment target uses the `deploymentRole` property to set the IAM role Takomo should use to deploy its configurations. The value for the `deploymentRole` property is complete IAM role ARN which also includes the target account id.

The rest of the deployment targets belong under the **all/application** deployment group in the deployment groups hierarchy. Therefore, they inherit the `deploymentRoleName` property defined by the **all/application** deployment group. Each target then specifies the `accountId` property, which Takomo combines with the `deploymentRoleName` property to form the complete ARN for the deployment role.


# Labels

You can add labels to deployment groups and targets with the `labels` property, which accepts a single label or a list of labels. Deployment groups and targets inherit labels from the deployment group they belong to and can have labels of their own but can't remove the inherited labels.

You can use labels to choose which deployment targets to include in commands. For example, you can deploy only those targets that have a **dev** label.

#### Example

Let's add label **app** to targets **dev-environment** and **prod-environment**, and another label **others** to **infra** and **sandbox** targets. We could use these labels to deploy all application targets (targets with the **app** label).

{% code title="deployment/targets.yml" %}

```yaml
vars:
  cost-center: 12345
  budget: 2000

targetsSchema: budget

deploymentGroups:
  all:
    configSets: security
  all/shared:
    targets:
      - name: infra
        deploymentRole: arn:aws:iam::123456789012:role/ExampleAdmin
        labels: others
  all/application:
    configSets: networking
    targetsSchema: environment
    deploymentRoleName: deployer
  all/application/dev:
    targets:
      - name: dev-environment
        accountId: "222244446666"
        labels: app
      - name: sandbox
        accountId: "111133335555"
        labels: others 
  all/application/prod:
    targets:
      - name: prod-environment
        accountId: "333355557777"
        labels: app
```

{% endcode %}


# Externalize targets configuration

As the number of deployment targets grows, the size of the deployment configuration file might become unwieldy. You can externalize the deployment target configurations outside the deployment configuration file to make the deployment configuration file more manageable. To do this, you need to define the deployment target repository in a **takomo.yml** file located in your project's root directory.

## Load deployment targets from the filesystem

Currently, there is one target repository implementation. It loads deployment target configurations from a specified directory. To enable it, you need to add the following configuration to the **takomo.yml** file.

{% code title="takomo.yml" %}

```yaml
deploymentTargets:
  repository:
    type: filesystem
    dir: <path to a directory with the target configurations>
    inferDeploymentGroupPathFromDirName: <boolean>
    inferDeploymentTargetNameFromFileName: <boolean>
```

{% endcode %}

The `type` property specifies that the target repository of type **filesystem** should be used to load the external targets configuration. The `dir` property specifies the file path to the directory from where to load the configurations. The file path can be absolute or relative to the project's root directory. Finally, the `inferDeploymentGroupPathFromDirName` property instructs Takomo to infer the target's deployment group from the name of the directory where the target's configuration file is located. &#x20;

Takomo will look for **.yml** files from the specified directory and its subdirectories. You can name the files as you wish. Each file must contain a valid configuration for one deployment target. The configuration format is the same as if the target's configuration was given in the deployment configuration file. The only difference is that unless you set `inferDeploymentGroupPathFromDirName` to **true**, you need to specify the target's deployment group with a `deploymentGroupPath` property. All deployment groups referred in the external configuration files must be defined in the deployment configuration file, too.

#### Example

Let's continue with our example and see how to externalize the deployment targets to a separate directory.

First, we specify that we want to load configuration for our deployment targets from a **my-targets** directory located in our project's root directory.

{% code title="takomo.yml" %}

```yaml
deploymentTargets:
  repository:
    type: filesystem
    dir: my-targets
```

{% endcode %}

Next, we extract the configuration for each of our target to separate files located in the my-targets directory.&#x20;

{% code title="my-targets/infra.yml" %}

```yaml
deploymentGroupPath: all/shared
name: infra
deploymentRole: arn:aws:iam::123456789012:role/ExampleAdmin
labels: others
```

{% endcode %}

{% code title="my-targets/dev-environment.yml" %}

```yaml
deploymentGroupPath: all/application/dev
name: dev-environment
accountId: "222244446666"
labels: app
```

{% endcode %}

{% code title="my-targets/sandbox.yml" %}

```yaml
deploymentGroupPath: all/application/dev
name: sandbox
accountId: "111133335555"
labels: others 
```

{% endcode %}

{% code title="my-targets/prod-environment.yml" %}

```yaml
deploymentGroupPath: all/application/prod
name: prod-environment
accountId: "333355557777"
labels: app
```

{% endcode %}

As you can see, each deployment target specifies the deployment group where the target belongs to.

After our changes, the deployment configuration file looks like this:&#x20;

{% code title="deployment/targets.yml" %}

```yaml
vars:
  cost-center: 12345
  budget: 2000

targetsSchema: budget

deploymentGroups:
  all:
    configSets: security
  all/shared: {}
  all/application:
    configSets: networking
    targetsSchema: environment
    deploymentRoleName: deployer
  all/application/dev: {}
  all/application/prod: {}
```

{% endcode %}

And this is how our file system looks like:

```bash
.
├─ templates
├─ config-sets
│  ├─ networking
│  │  ├─ private
│  │  │  └─ tgw.yml 
│  │  └─ public 
│  │     └─ load-balancer.yml 
│  └─ security
│     ├─ config.yml
│     └─ audit.yml 
├─ deployment
│  └─ targets.yml
└─ my-targets
   ├─ infra.yml
   ├─ dev-environment.yml
   ├─ sandbox.yml
   └─ prod-environment.yml
```

### Infer deployment group from a directory name

As mentioned earlier, you can use the `inferDeploymentGroupPathFromDirName` property to instruct Takomo to infer the target's deployment group from the name of the directory where the target's configuration file is located. If you choose to use this option, you need to have a directory structure that mirrors your deployment group hierarchy. As a benefit, you can omit the `deploymentGroupPath` property from the target files.

#### Example

Alright, let's convert our example to use the `inferDeploymentGroupPathFromDirName` property.

{% code title="takomo.yml" %}

```yaml
deploymentTargets:
  repository:
    type: filesystem
    dir: my-targets
    inferDeploymentGroupPathFromDirName: true
```

{% endcode %}

The deployment configuration file deployment/targets.yml stays the same but we need to create a directory structure that mirrors our deployment groups under the **my-targets** directory and move the target files to correct subdirectories. &#x20;

```bash
.
├─ templates
├─ config-sets
│  ├─ networking
│  │  ├─ private
│  │  │  └─ tgw.yml 
│  │  └─ public 
│  │     └─ load-balancer.yml 
│  └─ security
│     ├─ config.yml
│     └─ audit.yml 
├─ deployment
│  └─ targets.yml
└─ my-targets
   └─ all
      ├─ shared
      │  └─ infra.yml
      └─ application
         ├─ dev
         │  ├─ dev-environment.yml
         │  └─ sandbox.yml
         └─ prod
            └─ prod-environment.yml
```

We can then remove the `deploymentGroupPath` property from the target files.

### Infer deployment targets' names from names of their config files

You can use the `inferDeploymentTargetNameFromFileName` property to instruct Takomo to infer targets' names from the names of their configuration files. You can then omit the `name` property from the target files.&#x20;

The target name is inferred by removing the **.yml** file extension from the target's configuration file name.&#x20;

#### Example

Let's add `inferDeploymentTargetNameFromFileName` to our example.&#x20;

{% code title="takomo.yml" %}

```yaml
deploymentTargets:
  repository:
    type: filesystem
    dir: my-targets
    inferDeploymentGroupPathFromDirName: true
    inferDeploymentTargetNameFromFileName: true
```

{% endcode %}

Then just remove the `name` property from configuration files of our targets.


# Deploying targets

## Deploying config sets

You use the [deploy targets command](/command-line-usage/deploy-targets) to deploy stacks configured in config sets that are attached to deployment targets. For detailed information about the command, please see [here](/command-line-usage/deploy-targets).

#### Example

Here's an example showing how to deploy config sets to all targets under the **all/application** group:

```bash
tkm targets deploy all/application
```

## Removing config sets

You use the [undeploy targets command](/command-line-usage/undeploy-targets) to remove stacks configured in config sets that are attached to deployment targets. For detailed information about the command, please see [here](/command-line-usage/undeploy-targets).

#### Example

Here's an example demonstrating how to remove config sets from the **sandbox** target:

```bash
tkm targets undeploy --target sandbox
```


# Bootstrapping targets

Typically, you use a CI/CD pipeline to deploy stacks to your deployment targets. That usually means creating an IAM role for the CI/CD tool to assume and then use to perform the deployment. Of course, as a best practice, the deployment role should have only the minimum set of permissions.

The next question is how you create that deployment role in the first place. Takomo's approach to this problem is to divide config sets into two categories: **standard** and **bootstrap**.

The standard config sets are the ones you would deploy using the deployment role with a minimum set of permissions. The bootstrap config sets are, like the name implies, for bootstrapping resources needed to deploy the standard config sets, e.g., creating the deployment role. Deploying the bootstrap config sets should be a lightweight operation that you can run from your personal laptop with full admin permissions secured with MFA, or using some other automated but more restricted and secure option.

## Bootstrap config sets files and directories

At the file system level, there is no difference between the standard and bootstrap config sets. Take a look at [config sets documentation](/configuration/config-sets) to learn how you create config sets.

## Attaching bootstrap config sets

The way you attach a config set to a deployment group or target makes it either a standard or bootstrap config set. To attach bootstrap config sets, you use the `bootstrapConfigSets` property instead of the `configSets` property that you use to attach the standard config sets. Take a look at [config sets documentation](/configuration/config-sets) to learn how to  attach config sets.

## Target account

Setting the target account works the same way as with the [standard config sets](/configuration/config-sets). There are two options to specify to which account Takomo should deploy stacks defined in  deployment target's bootstrap config sets.

* Provide a complete IAM role ARN in the `bootstrapRole` property.
* Provide the target account's id in the `accountId` property and the name of the IAM role in the `bootstrapRoleName` property.

The first option takes precedence over the second one.

## Deploying bootstrap config sets

You use the [bootstrap targets command](/command-line-usage/bootstrap-targets) to deploy stacks configured in bootstrap config sets that are attached to deployment targets. For detailed information about the command, please see [here](/command-line-usage/bootstrap-targets).

#### Example

Here's an example showing how to deploy bootstrap config sets to all targets under the **all/application** group:

```bash
tkm targets bootstrap all/application
```

## Removing bootstrap config sets

You use the [tear down targets command](/command-line-usage/tear-down-targets) to remove stacks configured in bootstrap config sets that are attached to deployment targets. For detailed information about the command, please see [here](/command-line-usage/tear-down-targets).

#### Example

Here's an example demonstrating how to remove bootstrap config sets from the **sandbox** target:

```bash
tkm targets tear-down --target sandbox
```


# Deploy targets

Deploy infrastructure configured with config sets to the specified deployment groups and targets.

## Usage

```bash
tkm targets deploy [group-path...] \
  [--target <target>]... \
  [--exclude-target <target>]... \
  [--label <label>]... \
  [--exclude-label <label>]... \
  [--concurrent-targets <count>] \
  [--config-set <config-set>] \
  [--command-path <command-path>] \
  [--expect-no-changes]
```

## Positional arguments

* `group-path`
  * Provide one or more deployment group paths to deploy only the targets that belong to the deployment groups located under the given deployment group paths in the deployment groups hierarchy.
  * Optional.

## Options

In addition to the [common options](https://docs.takomo.io/command-line-usage/common-options), this command has the following options.

* `--label <label>`
  * Choose deployment targets by label. You can use this option multiple times to specify more labels.
  * Optional
* `--exclude-label <label>`
  * Exclude deployment targets by label. You can use this option multiple times to specify more labels.
  * Optional
* `--target <target>`
  * Deployment targets to deploy. You can use this option multiple times to specify more targets. You can use **%** character as a wildcard at the beginning and/or end of the target name to more than one target.&#x20;
  * Optional
* `--exclude-target <target>`
  * Exclude deployment targets. You can use this option multiple times to specify more targets. You can use **%** character as a wildcard at the beginning and/or end of the target name to more than one target.&#x20;
  * Optional
* `--concurrent-targets <number>`
  * Number of deployment targets to deploy concurrently. Defaults to 1. If you choose to review changes to each target, this is set to 1.
  * Optional
* `--config-set <config-set>`
  * Deploy only this config set.
  * Optional
* `--command-path <command-path>`
  * Deploy only stacks under this command path.
  * To use this option, also the `--config-set` option must be given.&#x20;
* `--expect-no-changes`
  * Fail the deployment if at least one stack has changes.

## IAM permissions

These are the minimum IAM permissions required to run this command.

```yaml
# Minimum permissions. Additional permissions are needed to actually 
# modify resources defined in the CloudFormation templates.
Statement: 
  - Sid: CloudFormation
    Effect: Allow
    Action:
      - cloudformation:CancelUpdateStack
      - cloudformation:DescribeStackEvents
      - cloudformation:CreateStack
      - cloudformation:GetTemplate
      - cloudformation:DeleteStack
      - cloudformation:UpdateStack
      - cloudformation:CreateChangeSet
      - cloudformation:DescribeChangeSet
      - cloudformation:DeleteChangeSet
      - cloudformation:ValidateTemplate
      - cloudformation:DescribeStacks
      - cloudformation:GetTemplateSummary
      - cloudformation:UpdateTerminationProtection
    Resource: "*"
  
  # S3 permissions needed only if a template bucket is used.
  # Specify resource to restrict access to specific buckets.  
  - Sid: S3
    Effect: Allow
    Action:
      - s3:PutObject
    Resource: "*"
  
  # IAM permissions needed only if command roles are used  
  # Specify resource to restrict access to specific roles.  
  - Sid: IAM
    Effect: Allow
    Action:
      - sts:AssumeRole
    Resource: "*"
```

## Examples

Deploy all deployment targets

```bash
tkm targets deploy
```

Deploy only targets that belong to a deployment group **MyGroup** or to any other deployment group under it

```bash
tkm targets deploy MyGroup
```

Deploy only the deployment target named **my-target**

```bash
tkm targets deploy --target my-target
```

Deploy all deployment targets whose name ends with **-test**

```bash
tkm targets deploy --target %-test
```

Deploy all targets that have label **test** or **dev**

```bash
tkm targets deploy --label test --label dev
```


# Undeploy targets

Remove (undeploy) infrastructure configured with config sets from the specified deployment groups and targets.

## Usage

```bash
tkm targets undeploy [group-path...] \
  [--target <target>]... \
  [--exclude-target <target>]... \
  [--label <label>]... \
  [--exclude-label <label>]... \
  [--concurrent-targets <count>] \
  [--config-set <config-set>] \
  [--command-path <command-path>]
```

## Positional arguments

* `group-path`
  * Provide one or more deployment group paths to remove only the targets that belong to the deployment groups located under the given deployment group paths in the deployment groups hierarchy.
  * Optional.

## Options

In addition to the [common options](https://docs.takomo.io/command-line-usage/common-options), this command has the following options.

* `--label <label>`
  * Choose deployment targets by label. You can use this option multiple times to specify more labels.
  * Optional
* `--exclude-label <label>`
  * Exclude deployment targets by label. You can use this option multiple times to specify more labels.
  * Optional
* `--target <target>`
  * Deployment targets to remove. You can use this option multiple times to specify more targets. You can use **%** character as a wildcard at the beginning and/or end of the target name to more than one target.&#x20;
  * Optional
* `--exclude-target <target>`
  * Exclude deployment targets. You can use this option multiple times to specify more targets. You can use **%** character as a wildcard at the beginning and/or end of the target name to more than one target.&#x20;
  * Optional
* `--concurrent-targets <number>`
  * Number of deployment targets to remove concurrently. Defaults to 1. If you choose to review changes to each target, this is set to 1.
  * Optional
* `--config-set <config-set>`
  * Undeploy only this config set.
  * Optional
* `--command-path <command-path>`
  * Undeploy only stacks under this command path.
  * To use this option, also the `--config-set` option must be given.&#x20;

## IAM permissions

These are the minimum IAM permissions required to run this command.

```yaml
# Minimum permissions. Additional permissions are needed to actually 
# remove the resources defined in CloudFormation templates.
Statement: 
  - Sid: Stacks
    Effect: Allow
    Action:
      - cloudformation:DescribeStackEvents
      - cloudformation:DeleteStack
      - cloudformation:DescribeStacks
    Resource: "*"

  # IAM permissions needed only if command roles are used  
  # Specify resource to restrict access to specific roles.  
  - Sid: IAM
    Effect: Allow
    Action:
      - sts:AssumeRole
    Resource: "*" 
```

## Examples

Undeploy all deployment targets

```bash
tkm targets undeploy
```

Undeploy only targets that belong to a deployment group **MyGroup** or to any other deployment group under it

```bash
tkm targets undeploy MyGroup
```

Undeploy only the deployment target named **my-target**

```bash
tkm targets undeploy --target my-target
```

Undeploy all deployment targets whose name ends with **-test**

```bash
tkm targets undeploy --target %-test
```

Undeploy all targets that have label **application**

```bash
tkm targets undeploy --label application
```


# Bootstrap targets

Bootstrap infrastructure configured with bootstrap config sets to the specified deployment groups and targets.

## Usage

```bash
tkm targets bootstrap [group-path...] \
  [--target <target>]... \
  [--exclude-target <target>]... \
  [--label <label>]... \
  [--exclude-label <label>]... \
  [--concurrent-targets <count>] \
  [--config-set <config-set>] \
  [--command-path <command-path>] \
  [--expect-no-changes]
```

## Positional arguments

* `group-path`
  * Provide one or more deployment group paths to bootstrap only the targets that belong to the deployment groups located under the given deployment group paths in the deployment groups hierarchy.
  * Optional.

## Options

In addition to the [common options](https://docs.takomo.io/command-line-usage/common-options), this command has the following options.

* `--label <label>`
  * Choose deployment targets by label. You can use this option multiple times to specify more labels.
  * Optional
* `--exclude-label <label>`
  * Exclude deployment targets by label. You can use this option multiple times to specify more labels.
  * Optional
* `--target <target>`
  * Deployment targets to bootstrap. You can use this option multiple times to specify more targets. You can use **%** character as a wildcard at the beginning and/or end of the target name to more than one target.&#x20;
  * Optional
* `--exclude-target <target>`
  * Exclude deployment targets. You can use this option multiple times to specify more targets. You can use **%** character as a wildcard at the beginning and/or end of the target name to more than one target.&#x20;
  * Optional
* `--concurrent-targets <number>`
  * Number of deployment targets to bootstrap concurrently. Defaults to 1. If you choose to review changes to each target, this is set to 1.
  * Optional
* `--config-set <config-set>`
  * Bootstrap only this config set.
  * Optional
* `--command-path <command-path>`
  * Bootstrap only stacks under this command path.
  * To use this option, also the `--config-set` option must be given.&#x20;
* `--expect-no-changes`
  * Fail the deployment if at least one stack has changes.

## IAM permissions

These are the minimum IAM permissions required to run this command.

```yaml
# Minimum permissions. Additional permissions are needed to actually 
# modify resources defined in the CloudFormation templates.
Statement: 
  - Sid: CloudFormation
    Effect: Allow
    Action:
      - cloudformation:CancelUpdateStack
      - cloudformation:DescribeStackEvents
      - cloudformation:CreateStack
      - cloudformation:GetTemplate
      - cloudformation:DeleteStack
      - cloudformation:UpdateStack
      - cloudformation:CreateChangeSet
      - cloudformation:DescribeChangeSet
      - cloudformation:DeleteChangeSet
      - cloudformation:ValidateTemplate
      - cloudformation:DescribeStacks
      - cloudformation:GetTemplateSummary
      - cloudformation:UpdateTerminationProtection
    Resource: "*"
  
  # S3 permissions needed only if a template bucket is used.
  # Specify resource to restrict access to specific buckets.  
  - Sid: S3
    Effect: Allow
    Action:
      - s3:PutObject
    Resource: "*"
  
  # IAM permissions needed only if command roles are used  
  # Specify resource to restrict access to specific roles.  
  - Sid: IAM
    Effect: Allow
    Action:
      - sts:AssumeRole
    Resource: "*"
```

## Examples

Bootstrap all deployment targets

```bash
tkm targets bootstrap
```

Bootstrap only targets that belong to a deployment group **MyGroup** or to any other deployment group under it

```bash
tkm targets bootstrap MyGroup
```

Bootstrap only the deployment target named **my-target**

```bash
tkm targets bootstrap --target my-target
```

Bootstrap all deployment targets whose name ends with **-test**

```bash
tkm targets bootstrap --target %-test
```

Bootstrap all targets that have label **test** or **dev**

```bash
tkm targets bootstrap --label test --label dev
```


# Tear down targets

Tear down infrastructure configured with bootstrap config sets to the specified deployment groups and targets.

## Usage

```bash
tkm targets tear-down [group-path...] \
  [--target <target>]... \
  [--exclude-target <target>]... \
  [--label <label>]... \
  [--exclude-label <label>]... \
  [--concurrent-targets <count>] \
  [--config-set <config-set>] \
  [--command-path <command-path>]
```

## Positional arguments

* `group-path`
  * Provide one or more deployment group paths to tear down only the targets that belong to the deployment groups located under the given deployment group paths in the deployment groups hierarchy.
  * Optional.

## Options

In addition to the [common options](https://docs.takomo.io/command-line-usage/common-options), this command has the following options.

* `--label <label>`
  * Choose deployment targets by label. You can use this option multiple times to specify more labels.
  * Optional
* `--exclude-label <label>`
  * Exclude deployment targets by label. You can use this option multiple times to specify more labels.
  * Optional
* `--target <target>`
  * Deployment targets to tear down. You can use this option multiple times to specify more targets. You can use **%** character as a wildcard at the beginning and/or end of the target name to more than one target.&#x20;
  * Optional
* `--exclude-target <target>`
  * Exclude deployment targets. You can use this option multiple times to specify more targets. You can use **%** character as a wildcard at the beginning and/or end of the target name to more than one target.&#x20;
  * Optional
* `--concurrent-targets <number>`
  * Number of deployment targets to deploy concurrently. Defaults to 1. If you choose to review changes to each target, this is set to 1.
  * Optional
* `--config-set <config-set>`
  * Tear down only this config set.
  * Optional
* `--command-path <command-path>`
  * Tear down only stacks under this command path.
  * To use this option, also the `--config-set` option must be given.&#x20;

## IAM permissions

These are the minimum IAM permissions required to run this command.

```yaml
# Minimum permissions. Additional permissions are needed to actually 
# modify resources defined in the CloudFormation templates.
Statement: 
  - Sid: CloudFormation
    Effect: Allow
    Action:
      - cloudformation:CancelUpdateStack
      - cloudformation:DescribeStackEvents
      - cloudformation:CreateStack
      - cloudformation:GetTemplate
      - cloudformation:DeleteStack
      - cloudformation:UpdateStack
      - cloudformation:CreateChangeSet
      - cloudformation:DescribeChangeSet
      - cloudformation:DeleteChangeSet
      - cloudformation:ValidateTemplate
      - cloudformation:DescribeStacks
      - cloudformation:GetTemplateSummary
      - cloudformation:UpdateTerminationProtection
    Resource: "*"
  
  # S3 permissions needed only if a template bucket is used.
  # Specify resource to restrict access to specific buckets.  
  - Sid: S3
    Effect: Allow
    Action:
      - s3:PutObject
    Resource: "*"
  
  # IAM permissions needed only if command roles are used  
  # Specify resource to restrict access to specific roles.  
  - Sid: IAM
    Effect: Allow
    Action:
      - sts:AssumeRole
    Resource: "*"
```

## Examples

Tear down all deployment targets

```bash
tkm targets bootstrap
```

Tear down only targets that belong to a deployment group **MyGroup** or to any other deployment group under it

```bash
tkm targets tear-down MyGroup
```

Tear down only the deployment target named **my-target**

```bash
tkm targets tear-down --target my-target
```

Tear down all deployment targets whose name ends with **-test**

```bash
tkm targets tear-down --target %-test
```

Tear down all targets that have label **test** or **dev**

```bash
tkm targets tear-down --label test --label dev
```


# Run targets

Run command against the given set of deployment targets.

## Usage

```bash
tkm targets run [group-path...] \
  --map <command> \
  [--reduce <command>] \
  [--map-role-name <role-name>] \
  [--map-args <args>] \
  [--disable-map-role] \
  [--reduce-role-arn <role-arn>] \
  [--target <target>]... \
  [--exclude-target <target>]... \
  [--label <label>]... \
  [--exclude-label <label>]... \
  [--capture-after <line>] \
  [--capture-before <line>] \
  [--capture-last-line] \
  [--output <format>] \
  [--concurrent-targets <count>]
```

## Positional arguments

* `group-path`
  * Provide one or more deployment group paths to run command only against the targets that belong to the deployment groups located under the given deployment group paths in the deployment groups hierarchy.
  * Optional.

## Options

In addition to the [common options](https://docs.takomo.io/command-line-usage/common-options), this command has the following options.

* `--map <command>`
  * Command to run against each target.
  * To invoke a JavaScript function from a file, give path to the file prefixed with `js:`
    * The JavaScript file must export a function.
    * For each target, the function is invoked with an object that contains the following properties:
      * `target` = Current target configuration
      * `deploymentGroupPath` = Deployment group path of the current target
      * `credentials` = AWS credentials bound to the current target
      * `args` = Arguments passed with the `--map-args` option
    * The function can return anything. Takomo collects the returned values to a list and invokes the reduce command with it.&#x20;
* `--reduce <command>`
  * Command to invoke with results from the map command.
  * To invoke a JavaScript function from a file, give path to the file prefixed with `js:`
    * The JavaScript file must export a function which accepts a an object with the following properties:
      * `credentials` = Credentials from the command line or credentials bound to the IAM role specified in `--reduce-role-arn` option.
      * `targets` = List of results from the map command
* `--map-role-name <role-name>`
  * Name of IAM role Takomo should assume from each account when invoking the map command.
* `--map-args <args>`
  * Additional arguments passed to the map command
  * To read the argument value from a file, prefix the argument with `file:`
    * If the file's extension is `.json`, its contents are parsed as JSON and stored to an object.
    * If the file's extension is `.yaml` or `.yml`, its contents are parsed as YAML and stored to an object.
    * Otherwise, the file's contents are passed as is.
* `--disable-map-role`
  * By default, Takomo assumes an IAM role from each account. Use this option to disable this functionality.&#x20;
* `--reduce-role-arn <role arn>`
  * ARN of IAM role Takomo should assume when running the reduce command.
* `--label <label>`
  * Choose deployment targets by label. You can use this option multiple times to specify more labels.
* `--exclude-label <label>`
  * Exclude deployment targets by label. You can use this option multiple times to specify more labels.
* `--target <target>`
  * Deployment targets to include in the run. You can use this option multiple times to specify more targets. You can use **%** character as a wildcard at the beginning and/or end of the target name to more than one target.&#x20;
* `--exclude-target <target>`
  * Exclude deployment targets. You can use this option multiple times to specify more targets. You can use **%** character as a wildcard at the beginning and/or end of the target name to more than one target.&#x20;
* `--capture-after <line>`
  * Capture all output from the map command after this line.
* `--capture-before <line>`
  * Capture all output from the map command before this line.
* `--capture-last-line`
  * Capture only the last line from the map command.
* `--output <format>`
  * Print the result from the reduce command using this format
  * Supported values: `text`, `json`, `yaml`
* `--concurrent-targets <number>`
  * Number of deployment targets to run concurrently. Defaults to 1.

## IAM permissions

These are the minimum IAM permissions required to run this command.

```yaml
# Minimum permissions. Additional permissions are needed to actually 
# modify resources defined in the CloudFormation templates.
Statement: 
  
  # IAM permissions needed only if targets are located in more
  # than one AWS account. Specify resource to restrict access 
  # to specific roles.  
  - Sid: IAM
    Effect: Allow
    Action:
      - sts:AssumeRole
    Resource: "*"
```

## Examples

Run `aws s3 ls` command against all targets. Assume role MyRunnerRole from each target account.

```bash
tkm targets run --map "aws s3 ls" --map-role-name MyRunnerRole
```

Invoke a JavaScript function defined in a file found from path /Documents/my-mapper.js:

```bash
tkm targets run --map js:/Documents/my-mapper.js --map-role-name MyRunnerRole
```

Invoke a JavaScript function defined in a file found from path /Documents/my-mapper.js then invoke another JavaScript function from a file /Documents/reducer.js with the list of results collected from the map function.

```bash
tkm targets run \
  --map js:/Documents/my-mapper.js \
  --reduce js:/Documents/reducer.js \
  --map-role-name MyRunnerRole
```


