

# CodeDeploy AppSpec file reference
AppSpec file reference

This section is a reference only. For a conceptual overview of the AppSpec file, see [CodeDeploy application specification (AppSpec) files](application-specification-files.md).

The application specification file (AppSpec file) is a [YAML](http://www.yaml.org)-formatted or JSON-formatted file used by CodeDeploy to manage a deployment.

**Note**  
The AppSpec file for an EC2/On-Premises deployment must be named `appspec.yml`, unless you are performing a local deployment. For more information, see [Create a local deployment](deployments-local.md#deployments-local-deploy).

**Topics**
+ [

## AppSpec files on an Amazon ECS compute platform
](#appspec-reference-ecs)
+ [

## AppSpec files on an AWS Lambda compute platform
](#appspec-reference-lambda)
+ [

## AppSpec files on an EC2/on-premises compute platform
](#appspec-reference-server)
+ [

# AppSpec File structure
](reference-appspec-file-structure.md)
+ [

# AppSpec File example
](reference-appspec-file-example.md)
+ [

## AppSpec File spacing
](#reference-appspec-file-spacing)
+ [

# Validate your AppSpec File and file location
](reference-appspec-file-validate.md)

## AppSpec files on an Amazon ECS compute platform


For Amazon ECS compute platform applications, the AppSpec file is used by CodeDeploy to determine: 
+  Your Amazon ECS task definition file. This is specified with its ARN in the `TaskDefinition` instruction in the AppSpec file. 
+  The container and port in your replacement task set where your Application Load Balancer or Network Load Balancer reroutes traffic during a deployment. This is specified with the `LoadBalancerInfo` instruction in the AppSpec file. 
+  Optional information about your Amazon ECS service, such the platform version on which it runs, its subnets, and its security groups. 
+  Optional Lambda functions to run during hooks that correspond with lifecycle events during an Amazon ECS deployment. For more information, see [AppSpec 'hooks' section for an Amazon ECS deployment](reference-appspec-file-structure-hooks.md#appspec-hooks-ecs). 

## AppSpec files on an AWS Lambda compute platform


For AWS Lambda compute platform applications, the AppSpec file is used by CodeDeploy to determine: 
+ Which Lambda function version to deploy.
+ Which Lambda functions to use as validation tests.

An AppSpec file can be YAML-formatted or JSON-formatted. You can also enter the contents of an AppSpec file directly into CodeDeploy console when you create a deployment.

## AppSpec files on an EC2/on-premises compute platform


 If your application uses the EC2/On-Premises compute platform, the AppSpec file must be a YAML-formatted file named `appspec.yml` and it must be placed in the root of the directory structure of an application's source code. Otherwise, deployments fail. It is used by CodeDeploy to determine:
+ What it should install onto your instances from your application revision in Amazon S3 or GitHub.
+ Which lifecycle event hooks to run in response to deployment lifecycle events.

After you have a completed AppSpec file, you bundle it, along with the content to deploy, into an archive file (zip, tar, or compressed tar). For more information, see [Working with application revisions for CodeDeploy](application-revisions.md).

**Note**  
The tar and compressed tar archive file formats (.tar and .tar.gz) are not supported for Windows Server instances.

After you have a bundled archive file (known in CodeDeploy as a *revision*), you upload it to an Amazon S3 bucket or Git repository. Then you use CodeDeploy to deploy the revision. For instructions, see [Create a deployment with CodeDeploy](deployments-create.md).

The appspec.yml for an EC2/On-Premises compute platform deployment is saved in the root directory of your revision. For more information, see [Add an AppSpec file for an EC2/On-Premises deployment](application-revisions-appspec-file.md#add-appspec-file-server) and [Plan a revision for CodeDeploy](application-revisions-plan.md). 

# AppSpec File structure


The following is the high-level structure for an AppSpec file used for deployments to AWS Lambda and EC2/On-Premises compute platforms.

A value in a YAML-formatted AppSpec file that is a string must not be wrapped in quotation marks ("") unless otherwise specified.

## AppSpec file structure for Amazon ECS deployments


**Note**  
This AppSpec file is written in YAML, but you can use the same structure to write one in JSON. A string in a JSON-formatted AppSpec file is always wrapped in quotation marks ("").

```
version: 0.0
resources: 
  ecs-service-specifications
hooks: 
  deployment-lifecycle-event-mappings
```

In this structure:

** **version** **  
This section specifies the version of the AppSpec file. Do not change this value. It is required. Currently, the only allowed value is **0.0**. It is reserved by CodeDeploy for future use.  
Specify **version** with a string.

** **resources** **  
This section specifies information about Amazon ECS application to deploy.  
For more information, see [AppSpec 'resources' section for Amazon ECS deployments](reference-appspec-file-structure-resources.md#reference-appspec-file-structure-resources-ecs).

** **hooks** **  
This section specifies Lambda functions to run at specific deployment lifecycle event hooks to validate the deployment.  
For more information, see [List of lifecycle event hooks for an Amazon ECS deployment](reference-appspec-file-structure-hooks.md#reference-appspec-file-structure-hooks-list-ecs).

## AppSpec file structure for AWS Lambda deployments


**Note**  
This AppSpec file is written in YAML, but you can use the same structure to write an AppSpec file for a Lambda deployment in JSON. A string in a JSON-formatted AppSpec file is always wrapped in quotation marks ("").

```
version: 0.0
resources: 
  lambda-function-specifications
hooks: 
  deployment-lifecycle-event-mappings
```

In this structure:

** **version** **  
This section specifies the version of the AppSpec file. Do not change this value. It is required. Currently, the only allowed value is **0.0**. It is reserved by CodeDeploy for future use.  
Specify **version** with a string.

** **resources** **  
This section specifies information about the Lambda function to deploy.  
For more information, see [AppSpec 'resources' section (Amazon ECS and AWS Lambda deployments only)](reference-appspec-file-structure-resources.md).

** **hooks** **  
This section specifies Lambda functions to run at specific deployment lifecycle events to validate the deployment.  
For more information, see [AppSpec 'hooks' section](reference-appspec-file-structure-hooks.md).

## AppSpec file structure for EC2/On-Premises deployments


```
version: 0.0
os: operating-system-name
files:
  source-destination-files-mappings
permissions:
  permissions-specifications
hooks:
  deployment-lifecycle-event-mappings
```

In this structure:

** **version** **  
This section specifies the version of the AppSpec file. Do not change this value. It is required. Currently, the only allowed value is **0.0**. It is reserved by CodeDeploy for future use.  
Specify **version** with a string.

** **os** **  
This section specifies the operating system value of the instance to which you deploy. It is required. The following values can be specified:  
+ **linux** – The instance is an Amazon Linux, Ubuntu Server, or RHEL instance.
+ **windows** – The instance is a Windows Server instance.
Specify **os** with a string.

** **files** **  
This section specifies the names of files that should be copied to the instance during the deployment's **Install** event.  
For more information, see [AppSpec 'files' section (EC2/On-Premises deployments only)](reference-appspec-file-structure-files.md).

** **permissions** **  
This section specifies how special permissions, if any, should be applied to the files in the `files` section as they are being copied over to the instance. This section applies to Amazon Linux, Ubuntu Server, and Red Hat Enterprise Linux (RHEL) instances only.  
For more information see, [AppSpec 'permissions' section (EC2/On-Premises deployments only)](reference-appspec-file-structure-permissions.md).

** **hooks** **  
This section specifies scripts to run at specific deployment lifecycle events during the deployment.  
For more information, see [AppSpec 'hooks' section](reference-appspec-file-structure-hooks.md).

**Topics**
+ [

## AppSpec file structure for Amazon ECS deployments
](#ecs-appspec-structure)
+ [

## AppSpec file structure for AWS Lambda deployments
](#lambda-appspec-structure)
+ [

## AppSpec file structure for EC2/On-Premises deployments
](#server-appspec-structure)
+ [

# AppSpec 'files' section (EC2/On-Premises deployments only)
](reference-appspec-file-structure-files.md)
+ [

# AppSpec 'resources' section (Amazon ECS and AWS Lambda deployments only)
](reference-appspec-file-structure-resources.md)
+ [

# AppSpec 'permissions' section (EC2/On-Premises deployments only)
](reference-appspec-file-structure-permissions.md)
+ [

# AppSpec 'hooks' section
](reference-appspec-file-structure-hooks.md)

# AppSpec 'files' section (EC2/On-Premises deployments only)


Provides information to CodeDeploy about which files from your application revision should be installed on the instance during the deployment's **Install** event. This section is required only if you are copying files from your revision to locations on the instance during deployment. 

This section has the following structure:

```
files:
  - source: source-file-location-1
    destination: destination-file-location-1
file_exists_behavior: DISALLOW|OVERWRITE|RETAIN
```

Multiple `source` and `destination` pairs can be set.

The `source` instruction identifies a file or directory from your revision to copy to the instance:
+ If `source` refers to a file, only the specified files are copied to the instance.
+ If `source` refers to a directory, then all files in the directory are copied to the instance.
+ If `source` is a single slash ("/" for Amazon Linux, RHEL, and Ubuntu Server instances, or "\$1" for Windows Server instances), then all of the files from your revision are copied to the instance.

The paths used in `source` are relative to the `appspec.yml` file, which should be at the root of your revision. For details on the file structure of a revision, see [Plan a revision for CodeDeploy](application-revisions-plan.md).

The `destination` instruction identifies the location on the instance where the files should be copied. This must be a fully qualified path such as `/root/destination/directory` (on Linux, RHEL, and Ubuntu) or `c:\destination\folder` (on Windows).

`source` and `destination` are each specified with a string.

The `file_exists_behavior` instruction is optional, and specifies how CodeDeploy handles files that already exist in a deployment target location but weren't part of the previous successful deployment. This setting can take any of the following values:
+ DISALLOW: The deployment fails. This is also the default behavior if no option is specified. 
+ OVERWRITE: The version of the file from the application revision currently being deployed replaces the version already on the instance. 
+ RETAIN: The version of the file already on the instance is kept and used as part of the new deployment.

When using the `file_exists_behavior` setting, understand that this setting:
+ can only be specified once, and applies to all files and directories listed under `files:`.
+ takes precedence over the `--file-exists-behavior` AWS CLI option and the `fileExistsBehavior` API option (both of which are also optional).

Here's an example `files` section for an Amazon Linux, Ubuntu Server, or RHEL instance.

```
files:
  - source: Config/config.txt
    destination: /webapps/Config
  - source: source
    destination: /webapps/myApp
```

In this example, the following two operations are performed during the **Install** event:

1. Copy the `Config/config.txt` file in your revision to the `/webapps/Config/config.txt` path on the instance.

1. Recursively copy all of the files in your revision's `source` directory to the `/webapps/myApp` directory on the instance.

## 'Files' section examples


The following examples show how to specify the `files` section. Although these examples describe Windows Server file and directory (folder) structures, they can easily be adapted for Amazon Linux, Ubuntu Server, and RHEL instances.

**Note**  
Only EC2/On-Premises deployments use the `files` section. It does not apply to AWS Lambda deployments.

For the following examples, we assume these files appear in the bundle in the root of `source`:
+ `appspec.yml`
+ `my-file.txt`
+ `my-file-2.txt`
+ `my-file-3.txt`

```
# 1) Copy only my-file.txt to the destination folder c:\temp.
#
files:
  - source: .\my-file.txt
    destination: c:\temp
#
# Result:
#   c:\temp\my-file.txt
#
# ---------------------
#
# 2) Copy only my-file-2.txt and my-file-3.txt to the destination folder c:\temp.
#
files:
  - source: my-file-2.txt
    destination: c:\temp
  - source: my-file-3.txt
    destination: c:\temp
#
# Result:
#   c:\temp\my-file-2.txt
#   c:\temp\my-file-3.txt
#
# ---------------------
#
# 3) Copy my-file.txt, my-file-2.txt, and my-file-3.txt (along with the appspec.yml file) to the destination folder c:\temp.
#
files:
  - source: \
    destination: c:\temp
#
# Result:
#   c:\temp\appspec.yml
#   c:\temp\my-file.txt
#   c:\temp\my-file-2.txt
#   c:\temp\my-file-3.txt
```

For the following examples, we assume the `appspec.yml` appears in the bundle in the root of `source` along with a folder named `my-folder` that contains three files:
+ `appspec.yml`
+ `my-folder\my-file.txt`
+ `my-folder\my-file-2.txt`
+ `my-folder\my-file-3.txt`

```
# 4) Copy the 3 files in my-folder (but do not copy my-folder itself) to the destination folder c:\temp. 
#
files:
  - source: .\my-folder
    destination: c:\temp
#
# Result:
#   c:\temp\my-file.txt
#   c:\temp\my-file-2.txt
#   c:\temp\my-file-3.txt
#
# ---------------------
#
# 5) Copy my-folder and its 3 files to my-folder within the destination folder c:\temp.
#
files:
  - source: .\my-folder
    destination: c:\temp\my-folder
#
# Result:
#   c:\temp\my-folder\my-file.txt
#   c:\temp\my-folder\my-file-2.txt
#   c:\temp\my-folder\my-file-3.txt
#
# ---------------------
#
# 6) Copy the 3 files in my-folder to other-folder within the destination folder c:\temp.
#
files:
  - source: .\my-folder
    destination: c:\temp\other-folder
#
# Result:
#   c:\temp\other-folder\my-file.txt
#   c:\temp\other-folder\my-file-2.txt
#   c:\temp\other-folder\my-file-3.txt	
#
# ---------------------
#
# 7) Copy only my-file-2.txt and my-file-3.txt to my-folder within the destination folder c:\temp.
#
files:
  - source: .\my-folder\my-file-2.txt
    destination: c:\temp\my-folder
  - source: .\my-folder\my-file-3.txt
    destination: c:\temp\my-folder
#
# Result:
#   c:\temp\my-folder\my-file-2.txt
#   c:\temp\my-folder\my-file-3.txt
#
# ---------------------
#
# 8) Copy only my-file-2.txt and my-file-3.txt to other-folder within the destination folder c:\temp.
#
files:
  - source: .\my-folder\my-file-2.txt
    destination: c:\temp\other-folder
  - source: .\my-folder\my-file-3.txt
    destination: c:\temp\other-folder
#
# Result:
#   c:\temp\other-folder\my-file-2.txt
#   c:\temp\other-folder\my-file-3.txt
#
# ---------------------
#
# 9) Copy my-folder and its 3 files (along with the appspec.yml file) to the destination folder c:\temp. If any of the files already exist on the instance, overwrite them.
#
files:
  - source: \
    destination: c:\temp
file_exists_behavior: OVERWRITE
#
# Result:
#   c:\temp\appspec.yml
#   c:\temp\my-folder\my-file.txt
#   c:\temp\my-folder\my-file-2.txt
#   c:\temp\my-folder\my-file-3.txt
```

# AppSpec 'resources' section (Amazon ECS and AWS Lambda deployments only)


 The content in the `'resources'` section of the AppSpec file varies, depending on the compute platform of your deployment. The `'resources'` section for an Amazon ECS deployment contains your Amazon ECS task definition, container and port for routing traffic to your updated Amazon ECS task set, and other optional information. The `'resources'` section for an AWS Lambda deployment contains the name, alias, current version, and target version of a Lambda function. 

**Topics**
+ [

## AppSpec 'resources' section for AWS Lambda deployments
](#reference-appspec-file-structure-resources-lambda)
+ [

## AppSpec 'resources' section for Amazon ECS deployments
](#reference-appspec-file-structure-resources-ecs)

## AppSpec 'resources' section for AWS Lambda deployments


The `'resources'` section specifies the Lambda function to deploy and has the following structure:

YAML:

```
resources:
  - name-of-function-to-deploy:
      type: "AWS::Lambda::Function"
      properties:
        name: name-of-lambda-function-to-deploy
        alias: alias-of-lambda-function-to-deploy
        currentversion: version-of-the-lambda-function-traffic-currently-points-to
        targetversion: version-of-the-lambda-function-to-shift-traffic-to
```

JSON:

```
"resources": [
    {
        "name-of-function-to-deploy" {
            "type": "AWS::Lambda::Function",
            "properties": {
                "name": "name-of-lambda-function-to-deploy",
                "alias": "alias-of-lambda-function-to-deploy",
                "currentversion": "version-of-the-lambda-function-traffic-currently-points-to",
                "targetversion": "version-of-the-lambda-function-to-shift-traffic-to"
            }
        }
    }
]
```

Each property is specified with a string. 
+ `name` – Required. This is the name of the Lambda function to deploy.
+ `alias` – Required. This is the name of the alias to the Lambda function.
+ `currentversion` – Required. This is the version of the Lambda function traffic currently points to. This value must be a valid positive integer.
+ `targetversion` – Required. This is the version of the Lambda function traffic is shifted to. This value must be a valid positive integer.

## AppSpec 'resources' section for Amazon ECS deployments


 The `'resources'` section specifies the Amazon ECS service to deploy and has the following structure: 

YAML:

```
Resources:
  - TargetService:
      Type: AWS::ECS::Service
      Properties:
        TaskDefinition: "task-definition-arn"
        LoadBalancerInfo: 
          ContainerName: "ecs-container-name" 
          ContainerPort: "ecs-application-port"
# Optional properties
        PlatformVersion: "ecs-service-platform-version"
        NetworkConfiguration:
          AwsvpcConfiguration:
            Subnets: ["ecs-subnet-1","ecs-subnet-n"] 
            SecurityGroups: ["ecs-security-group-1","ecs-security-group-n"] 
            AssignPublicIp: "ENABLED | DISABLED"
        CapacityProviderStrategy:
          - Base: integer
            CapacityProvider: "capacityProviderA"
            Weight: integer
          - Base: integer
            CapacityProvider: "capacityProviderB"
            Weight: integer
```

JSON:

```
"Resources": [
    {
        "TargetService": {
            "Type": "AWS::ECS::Service",
            "Properties": {
                "TaskDefinition": "task-definition-arn",
                "LoadBalancerInfo": {
                    "ContainerName": "ecs-container-name",
                    "ContainerPort": "ecs-application-port"
                },
                "PlatformVersion": "ecs-service-platform-version",
                "NetworkConfiguration": {
                    "AwsvpcConfiguration": {
                        "Subnets": [
                            "ecs-subnet-1",
                            "ecs-subnet-n"
                        ],
                        "SecurityGroups": [
                            "ecs-security-group-1",
                            "ecs-security-group-n"
                        ],
                        "AssignPublicIp": "ENABLED | DISABLED"
                    }
                },
                "CapacityProviderStrategy": [
                    {
                        "Base": integer,
                        "CapacityProvider": "capacityProviderA",
                        "Weight": integer
                    },
                    {
                        "Base": integer,
                        "CapacityProvider": "capacityProviderB",
                        "Weight": integer
                    }
                ]
            }
        }
    }
]
```

Each property is specified with a string except for `ContainerPort`, which is a number. 
+ `TaskDefinition` – Required. This is the task definition for the Amazon ECS service to deploy. It is specified with the ARN of the task definition. The ARN format is `arn:aws:ecs:aws-region:account-id:task-definition/task-definition-family:task-definition-revision`. For more information, see [Amazon Resource Names (ARNs) and AWS service namespaces](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html).
**Note**  
The `:task-definition-revision` portion of the ARN is optional. If it is omitted, Amazon ECS uses the latest ACTIVE revision of the task definition.
+ `ContainerName` – Required. This is the name of the Amazon ECS container that contains your Amazon ECS application. It must be a container specified in your Amazon ECS task definition.
+ `ContainerPort` – Required. This is the port on the container where traffic will be routed to.
+ `PlatformVersion`: Optional. The platform version of the Fargate tasks in the deployed Amazon ECS service. For more information, see [AWS Fargate platform versions](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/platform_versions.html). If not specified, `LATEST` is used by default.
+  `NetworkConfiguration`: Optional. Under `AwsvpcConfiguration`, you can specify the following. For more information, see [AwsVpcConfiguration](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_AwsVpcConfiguration.html) in the *Amazon ECS Container Service API Reference*. 
  + `Subnets`: Optional. A comma-separated list of one or more subnets in your Amazon ECS service.
  + `SecurityGroups`: Optional. A comma-separated list of one or more security groups in your Amazon Elastic Container Service.
  + `AssignPublicIp`: Optional. A string that specifies whether your Amazon ECS service's elastic network interface receives a public IP address. The valid values are `ENABLED` and `DISABLED`.
**Note**  
 All or none of the settings under `NetworkConfiguration` must be specified. For example, if you want to specify `Subnets`, you must also specify `SecurityGroups` and `AssignPublicIp`. If none is specified, CodeDeploy uses the current network Amazon ECS settings. 
+ `CapacityProviderStrategy`: Optional. A list of Amazon ECS capacity providers you want to use for your deployment. For more information, see [Amazon ECS capacity providers](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/cluster-capacity-providers.html) in the *Amazon Elastic Container Service Developer Guide*. For each capacity provider, you can specify the following settings. For details on these settings, see [AWS::ECS::ServiceCapacityProviderStrategyItem](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-service-capacityproviderstrategyitem.html) in the *AWS CloudFormation User Guide*
  + `Base`: Optional. The base value designates how many tasks, at a minimum, to run on the specified capacity provider. Only one capacity provider in a capacity provider strategy can have a base defined. If no value is specified, the default value of 0 is used.
  + `CapacityProvider`: Optional. The short name of the capacity provider. Example: *capacityProviderA*
  + `Weight`: Optional.

    The *weight* value designates the relative percentage of the total number of tasks launched that should use the specified capacity provider. The `weight` value is taken into consideration after the `base` value, if defined, is satisfied.

    If no `weight` value is specified, the default value of `0` is used. When multiple capacity providers are specified within a capacity provider strategy, at least one of the capacity providers must have a weight value greater than zero and any capacity providers with a weight of `0` will not be used to place tasks. If you specify multiple capacity providers in a strategy that all have a weight of `0`, any `RunTask` or `CreateService` actions using the capacity provider strategy will fail.

     An example scenario for using weights is defining a strategy that contains two capacity providers and both have a weight of `1`, then when the `base` is satisfied, the tasks will be split evenly across the two capacity providers. Using that same logic, if you specify a weight of `1` for *capacityProviderA* and a weight of `4` for *capacityProviderB*, then for every one task that is run using *capacityProviderA*, four tasks would use *capacityProviderB*.

# AppSpec 'permissions' section (EC2/On-Premises deployments only)


The `'permissions'` section specifies how special permissions, if any, should be applied to the files and directories/folders in the `'files'` section after they are copied to the instance. You can specify multiple `object` instructions. This section is optional. It applies to Amazon Linux, Ubuntu Server, and RHEL instances only.

**Note**  
The `'permissions'` section is used for EC2/On-Premises deployments only. It is not used for AWS Lambda or Amazon ECS deployments.

This section has the following structure:

```
permissions:
  - object: object-specification
    pattern: pattern-specification
    except: exception-specification
    owner: owner-account-name
    group: group-name
    mode: mode-specification
    acls: 
      - acls-specification 
    context:
      user: user-specification
      type: type-specification
      range: range-specification
    type:
      - object-type
```

The instructions are as follows:
+ `object` – Required. This is a set of file system objects (files or directories/folders) that the specified permissions are applied to after the file system objects are copied to the instance.

  Specify `object` with a string.
+ `pattern` – Optional. Specifies a pattern to apply permissions. If not specified or specified with the special characters **"\$1\$1"**, the permissions are applied to all matching files or directories, depending on the `type`. 

  Specify `pattern` with a string with quotation marks ("").
+ `except` – Optional. Specifies any files or directories that are exceptions to `pattern`. 

  Specify `except` with a comma-separated list of strings inside square brackets.
+ `owner` – Optional. The name of the owner of `object`. If not specified, all existing owners applied to the original file or directory/folder structure remain unchanged after the copy operation.

  Specify `owner` with a string.
+ `group` – Optional. The name of the group for `object`. If not specified, all existing groups applied to the original file or directory/folder structure remain unchanged after the copy operation.

  Specify `group` with a string.
+ `mode` – Optional. A numeric value specifying the permissions to be applied to `object`. The mode setting follows the Linux chmod command syntax.
**Important**  
If the value includes a leading zero, you must surround it with double-quotes, or remove the leading zero so that only three digits remain.
**Note**  
Symbolic notation such as **u\$1x** is not supported for the `mode` setting.

  Examples:
  + `mode: "0644"` gives read and write permissions to the owner of the object (6), read-only permissions to the group (4), and read-only permissions to all other users (4).
  + `mode: 644` grants the same permissions as `mode: "0644"`.
  + `mode: 4755` sets the setuid attribute (4), gives full control permissions to the owner (7), gives read and execute permissions to the group (5), and gives read and execute permissions to all other users (5).

    For more examples, see the Linux chmod command documentation.

    If mode is not specified, all existing modes applied to the original file or folder structure remain unchanged after the copy operation.
+ `acls` – Optional. A list of character strings representing one or more access control list (ACL) entries applied to `object`. For example, **u:bob:rw** represents read and write permissions for user **bob**. (For more examples, see ACL entry format examples in the Linux `setfacl` command documentation.) You can specify multiple ACL entries. If `acls` is not specified, any existing ACLs applied to the original file or directory/folder structure remain unchanged after the copy operation. These replace any existing ACLs.

  Specify an `acls` with a dash (-), followed by a space, and then a string (for example, `- u:jane:rw`). If you have more than one ACL, each is specified on a separate line.
**Note**  
Setting unnamed users, unnamed groups, or other similar ACL entries causes the AppSpec file to fail. Use `mode` to specify these types of permissions instead.
+ `context` – Optional. For Security-Enhanced Linux (SELinux)-enabled instances, a list of security-relevant context labels to apply to the copied objects. Labels are specified as keys containing `user`, `type`, and `range`. (For more information, see the SELinux documentation.) Each key is entered with a string. If not specified, any existing labels applied to the original file or directory/folder structure remain unchanged after the copy operation.
  + `user` – Optional. The SELinux user.
  + `type` – Optional. The SELinux type name.
  + `range` – Optional. The SELinux range specifier. This has no effect unless Multi-Level Security (MLS) and Multi-Category Security (MCS) are enabled on the machine. If not enabled, `range` defaults to **s0**.

  Specify `context` with a string (for example, `user: unconfined_u`). Each `context` is specified on a seperate line.
+ `type` – Optional. The types of objects to which to apply the specified permissions. `type` is a string that can be set to **file** or **directory**. If **file** is specified, the permissions are applied only to files that are immediately contained in `object` after the copy operation (and not to `object` itself). If **directory** is specified, the permissions are recursively applied to all directories/folders that are anywhere in `object` after the copy operation (but not to `object` itself).

  Specify `type` with a dash (-), followed by a space, and then a string (for example, `- file`).

## 'Permissions' section example


The following example shows how to specify the `'permissions'` section with the `object`, `pattern`, `except`, `owner`, `mode`, and `type` instructions. This example applies to Amazon Linux, Ubuntu Server, and RHEL instances only. In this example, assume the following files and folders are copied to the instance in this hierarchy:

```
/tmp
  `-- my-app
       |-- my-file-1.txt
       |-- my-file-2.txt
       |-- my-file-3.txt
       |-- my-folder-1
       |     |-- my-file-4.txt
       |     |-- my-file-5.txt
       |     `-- my-file-6.txt
       `-- my-folder-2
             |-- my-file-7.txt
             |-- my-file-8.txt
             |-- my-file-9.txt
	           `-- my-folder-3
```

The following AppSpec file shows how to set permissions on these files and folders after they are copied:

```
version: 0.0
os: linux
# Copy over all of the folders and files with the permissions they
#  were originally assigned.
files:
  - source: ./my-file-1.txt
    destination: /tmp/my-app
  - source: ./my-file-2.txt
    destination: /tmp/my-app
  - source: ./my-file-3.txt
    destination: /tmp/my-app
  - source: ./my-folder-1
    destination: /tmp/my-app/my-folder-1
  - source: ./my-folder-2
    destination: /tmp/my-app/my-folder-2
# 1) For all of the files in the /tmp/my-app folder ending in -3.txt
#  (for example, just my-file-3.txt), owner = adm, group = wheel, and
#  mode = 464 (-r--rw-r--).
permissions:
  - object: /tmp/my-app
    pattern: "*-3.txt"
    owner: adm
    group: wheel
    mode: 464
    type:
      - file
# 2) For all of the files ending in .txt in the /tmp/my-app
#  folder, but not for the file my-file-3.txt (for example,
#  just my-file-1.txt and my-file-2.txt),
#  owner = ec2-user and mode = 444 (-r--r--r--).
  - object: /tmp/my-app
    pattern: "*.txt"
    except: [my-file-3.txt]
    owner: ec2-user
    mode: 444
    type:
      - file
# 3) For all the files in the /tmp/my-app/my-folder-1 folder except
#  for my-file-4.txt and my-file-5.txt, (for example,
#  just my-file-6.txt), owner = operator and mode = 646 (-rw-r--rw-).
  - object: /tmp/my-app/my-folder-1
    pattern: "**"
    except: [my-file-4.txt, my-file-5.txt]
    owner: operator
    mode: 646
    type:
      - file
# 4) For all of the files that are immediately under
#  the /tmp/my-app/my-folder-2 folder except for my-file-8.txt,
#  (for example, just my-file-7.txt and
#  my-file-9.txt), owner = ec2-user and mode = 777 (-rwxrwxrwx).
  - object: /tmp/my-app/my-folder-2
    pattern: "**"
    except: [my-file-8.txt]
    owner: ec2-user
    mode: 777
    type:
      - file
# 5) For all folders at any level under /tmp/my-app that contain
#  the name my-folder but not
#  /tmp/my-app/my-folder-2/my-folder-3 (for example, just
#  /tmp/my-app/my-folder-1 and /tmp/my-app/my-folder-2),
#  owner = ec2-user and mode = 555 (dr-xr-xr-x).
  - object: /tmp/my-app
    pattern: "*my-folder*"
    except: [tmp/my-app/my-folder-2/my-folder-3]
    owner: ec2-user
    mode: 555
    type:
      - directory
# 6) For the folder /tmp/my-app/my-folder-2/my-folder-3,
#  group = wheel and mode = 564 (dr-xrw-r--).
  - object: /tmp/my-app/my-folder-2/my-folder-3
    group: wheel
    mode: 564
    type:
      - directory
```

The resulting permissions are as follows:

```
-r--r--r-- ec2-user root  my-file-1.txt
-r--r--r-- ec2-user root  my-file-2.txt
-r--rw-r-- adm      wheel my-file-3.txt

dr-xr-xr-x ec2-user root  my-folder-1
-rw-r--r-- root     root  my-file-4.txt
-rw-r--r-- root     root  my-file-5.txt
-rw-r--rw- operator root  my-file-6.txt

dr-xr-xr-x ec2-user root  my-folder-2
-rwxrwxrwx ec2-user root  my-file-7.txt
-rw-r--r-- root     root  my-file-8.txt
-rwxrwxrwx ec2-user root  my-file-9.txt

dr-xrw-r-- root     wheel my-folder-3
```

The following example shows how to specify the `'permissions'` section with the addition of the `acls` and `context` instructions. This example applies to Amazon Linux, Ubuntu Server, and RHEL instances only.

```
permissions:
  - object: /var/www/html/WordPress
    pattern: "**"
    except: [/var/www/html/WordPress/ReadMe.txt]
    owner: bob
    group: writers
    mode: 644
    acls: 
      - u:mary:rw
      - u:sam:rw
      - m::rw
    context:
      user: unconfined_u
      type: httpd_sys_content_t
      range: s0
    type:
      - file
```

# AppSpec 'hooks' section


The content in the `'hooks'` section of the AppSpec file varies, depending on the compute platform for your deployment. The `'hooks'` section for an EC2/On-Premises deployment contains mappings that link deployment lifecycle event hooks to one or more scripts. The `'hooks'` section for a Lambda or an Amazon ECS deployment specifies Lambda validation functions to run during a deployment lifecycle event. If an event hook is not present, no operation is executed for that event. This section is required only if you are running scripts or Lambda validation functions as part of the deployment.

**Topics**
+ [

## AppSpec 'hooks' section for an Amazon ECS deployment
](#appspec-hooks-ecs)
+ [

## AppSpec 'hooks' section for an AWS Lambda deployment
](#appspec-hooks-lambda)
+ [

## AppSpec 'hooks' section for an EC2/On-Premises deployment
](#appspec-hooks-server)

## AppSpec 'hooks' section for an Amazon ECS deployment


**Topics**
+ [

### List of lifecycle event hooks for an Amazon ECS deployment
](#reference-appspec-file-structure-hooks-list-ecs)
+ [

### Run order of hooks in an Amazon ECS deployment.
](#reference-appspec-file-structure-hooks-run-order-ecs)
+ [

### Structure of 'hooks' section
](#reference-appspec-file-structure-hooks-section-structure-ecs)
+ [

### Sample Lambda 'hooks' function
](#reference-appspec-file-structure-hooks-section-structure-ecs-sample-function)

### List of lifecycle event hooks for an Amazon ECS deployment


An AWS Lambda hook is one Lambda function specified with a string on a new line after the name of the lifecycle event. Each hook is executed once per deployment. Following are descriptions of the lifecycle events where you can run a hook during an Amazon ECS deployment. 
+  `BeforeInstall` – Use to run tasks before the replacement task set is created. One target group is associated with the original task set. If an optional test listener is specified, it is associated with the original task set. A rollback is not possible at this point. 
+  `AfterInstall` – Use to run tasks after the replacement task set is created and one of the target groups is associated with it. If an optional test listener is specified, it is associated with the original task set. The results of a hook function at this lifecycle event can trigger a rollback.
+  `AfterAllowTestTraffic` – Use to run tasks after the test listener serves traffic to the replacement task set. The results of a hook function at this point can trigger a rollback.
+  `BeforeAllowTraffic` – Use to run tasks after the second target group is associated with the replacement task set, but before traffic is shifted to the replacement task set. The results of a hook function at this lifecycle event can trigger a rollback. 
+  `AfterAllowTraffic` – Use to run tasks after the second target group serves traffic to the replacement task set. The results of a hook function at this lifecycle event can trigger a rollback. 

For more information, see [What happens during an Amazon ECS deployment](deployment-steps-ecs.md#deployment-steps-what-happens) and [Tutorial: Deploy an Amazon ECS service with a validation test](tutorial-ecs-deployment-with-hooks.md).

### Run order of hooks in an Amazon ECS deployment.


In an Amazon ECS deployment, event hooks run in the following order:

![\[The order of event hooks in an Amazon ECS deployment.\]](http://docs.aws.amazon.com/codedeploy/latest/userguide/images/lifecycle-event-order-ecs.png)


**Note**  
The **Start**, **Install**, **TestTraffic**, **AllowTraffic**, and **End** events in the deployment cannot be scripted, which is why they appear in gray in this diagram.

### Structure of 'hooks' section


The following are examples of the structure of the `'hooks'` section.

Using YAML:

```
Hooks:
  - BeforeInstall: "BeforeInstallHookFunctionName"
  - AfterInstall: "AfterInstallHookFunctionName"
  - AfterAllowTestTraffic: "AfterAllowTestTrafficHookFunctionName"
  - BeforeAllowTraffic: "BeforeAllowTrafficHookFunctionName"
  - AfterAllowTraffic: "AfterAllowTrafficHookFunctionName"
```

Using JSON:

```
"Hooks": [
		{
			"BeforeInstall": "BeforeInstallHookFunctionName"
		},
		{
			"AfterInstall": "AfterInstallHookFunctionName"
		},
		{
			"AfterAllowTestTraffic": "AfterAllowTestTrafficHookFunctionName"
		},
		{
			"BeforeAllowTraffic": "BeforeAllowTrafficHookFunctionName"
		},
		{
			"AfterAllowTraffic": "AfterAllowTrafficHookFunctionName"
		}
	]
}
```

### Sample Lambda 'hooks' function


Use the `'hooks'` section to specify a Lambda function that CodeDeploy can call to validate an Amazon ECS deployment. You can use the same function or a different one for the `BeforeInstall`, `AfterInstall`, `AfterAllowTestTraffic`, `BeforeAllowTraffic`, and `AfterAllowTraffic` deployment lifecycle events. Following completion of the validation tests, the Lambda `AfterAllowTraffic` function calls back CodeDeploy and delivers a result of `Succeeded` or `Failed`. 

**Important**  
The deployment is considered to have failed if CodeDeploy is not notified by the Lambda validation function within one hour.

 Before invoking a Lambda hook function, the server must be notified of the deployment ID and the lifecycle event hook execution ID using the `putLifecycleEventHookExecutionStatus` command.

 The following is a sample Lambda hook function written in Node.js. 

```
'use strict';

const aws = require('aws-sdk');
const codedeploy = new aws.CodeDeploy({apiVersion: '2014-10-06'});

exports.handler = (event, context, callback) => {
    //Read the DeploymentId from the event payload.
    var deploymentId = event.DeploymentId;

    //Read the LifecycleEventHookExecutionId from the event payload
    var lifecycleEventHookExecutionId = event.LifecycleEventHookExecutionId;

    /*
     Enter validation tests here.
    */

    // Prepare the validation test results with the deploymentId and
    // the lifecycleEventHookExecutionId for CodeDeploy.
    var params = {
        deploymentId: deploymentId,
        lifecycleEventHookExecutionId: lifecycleEventHookExecutionId,
        status: 'Succeeded' // status can be 'Succeeded' or 'Failed'
    };
    
    // Pass CodeDeploy the prepared validation test results.
    codedeploy.putLifecycleEventHookExecutionStatus(params, function(err, data) {
        if (err) {
            // Validation failed.
            callback('Validation test failed');
        } else {
            // Validation succeeded.
            callback(null, 'Validation test succeeded');
        }
    });
};
```

## AppSpec 'hooks' section for an AWS Lambda deployment


**Topics**
+ [

### List of lifecycle event hooks for an AWS Lambda deployment
](#reference-appspec-file-structure-hooks-list-lambda)
+ [

### Run order of hooks in a Lambda function version deployment
](#reference-appspec-file-structure-hooks-run-order-lambda)
+ [

### Structure of 'hooks' section
](#reference-appspec-file-structure-hooks-section-structure-lambda)
+ [

### Sample Lambda 'hooks' function
](#reference-appspec-file-structure-hooks-section-structure-lambda-sample-function)

### List of lifecycle event hooks for an AWS Lambda deployment


An AWS Lambda hook is one Lambda function specified with a string on a new line after the name of the lifecycle event. Each hook is executed once per deployment. Here are descriptions of the hooks available for use in your AppSpec file. 
+ **BeforeAllowTraffic** – Use to run tasks before traffic is shifted to the deployed Lambda function version.
+ **AfterAllowTraffic** – Use to run tasks after all traffic is shifted to the deployed Lambda function version.

### Run order of hooks in a Lambda function version deployment


In a serverless Lambda function version deployment, event hooks run in the following order:

![\[The order of event hooks in a Lambda deployment.\]](http://docs.aws.amazon.com/codedeploy/latest/userguide/images/lifecycle-event-order-lambda.png)


**Note**  
The **Start**, **AllowTraffic**, and **End** events in the deployment cannot be scripted, which is why they appear in gray in this diagram.

### Structure of 'hooks' section


The following are examples of the structure of the 'hooks' section.

Using YAML:

```
hooks:
   - BeforeAllowTraffic: BeforeAllowTrafficHookFunctionName
   - AfterAllowTraffic: AfterAllowTrafficHookFunctionName
```

Using JSON:

```
"hooks": [{
    "BeforeAllowTraffic": "BeforeAllowTrafficHookFunctionName"
    },
    {
    "AfterAllowTraffic": "AfterAllowTrafficHookFunctionName"
}]
```

### Sample Lambda 'hooks' function


Use the 'hooks' section to specify a Lambda function that CodeDeploy can call to validate a Lambda deployment. You can use the same function or a different one for the `BeforeAllowTraffic` and `AfterAllowTraffic` deployment lifecycle events. Following completion of the validation tests, the Lambda validation function calls back CodeDeploy and delivers a result of `Succeeded` or `Failed`. 

**Important**  
The deployment is considered to have failed if CodeDeploy is not notified by the Lambda validation function within one hour.

 Before invoking a Lambda hook function, the server must be notified of the deployment ID and the lifecycle event hook execution ID using the `putLifecycleEventHookExecutionStatus` command.

 The following is a sample Lambda hook function written in Node.js. 

```
'use strict';

const aws = require('aws-sdk');
const codedeploy = new aws.CodeDeploy({apiVersion: '2014-10-06'});

exports.handler = (event, context, callback) => {
    //Read the DeploymentId from the event payload.
    var deploymentId = event.DeploymentId;

    //Read the LifecycleEventHookExecutionId from the event payload
    var lifecycleEventHookExecutionId = event.LifecycleEventHookExecutionId;

    /*
     Enter validation tests here.
    */

    // Prepare the validation test results with the deploymentId and
    // the lifecycleEventHookExecutionId for CodeDeploy.
    var params = {
        deploymentId: deploymentId,
        lifecycleEventHookExecutionId: lifecycleEventHookExecutionId,
        status: 'Succeeded' // status can be 'Succeeded' or 'Failed'
    };
    
    // Pass CodeDeploy the prepared validation test results.
    codedeploy.putLifecycleEventHookExecutionStatus(params, function(err, data) {
        if (err) {
            // Validation failed.
            callback('Validation test failed');
        } else {
            // Validation succeeded.
            callback(null, 'Validation test succeeded');
        }
    });
};
```

## AppSpec 'hooks' section for an EC2/On-Premises deployment


**Topics**
+ [

### List of lifecycle event hooks
](#reference-appspec-file-structure-hooks-list)
+ [

### Lifecycle event hook availability
](#reference-appspec-file-structure-hooks-availability)
+ [

### Run order of hooks in a deployment
](#reference-appspec-file-structure-hooks-run-order)
+ [

### Structure of 'hooks' section
](#reference-appspec-file-structure-hooks-section-structure)
+ [

### Referencing files in your hook scripts
](#codedeploy-agent-working-directory)
+ [

### Environment variable availability for hooks
](#reference-appspec-file-structure-environment-variable-availability)
+ [

### Hooks example
](#reference-appspec-file-structure-hooks-example)

### List of lifecycle event hooks


An EC2/On-Premises deployment hook is executed once per deployment to an instance. You can specify one or more scripts to run in a hook. Each hook for a lifecycle event is specified with a string on a separate line. Here are descriptions of the hooks available for use in your AppSpec file. 

For information about which lifecycle event hooks are valid for which deployment and rollback types, see [Lifecycle event hook availability](#reference-appspec-file-structure-hooks-availability).
+ `ApplicationStop` – This deployment lifecycle event occurs even before the application revision is downloaded. You can specify scripts for this event to gracefully stop the application or remove currently installed packages in preparation for a deployment. The AppSpec file and scripts used for this deployment lifecycle event are from the previous successfully deployed application revision.
**Note**  
An AppSpec file does not exist on an instance before you deploy to it. For this reason, the `ApplicationStop` hook does not run the first time you deploy to the instance. You can use the `ApplicationStop` hook the second time you deploy to an instance.

   To determine the location of the last successfully deployed application revision, the CodeDeploy agent looks up the location listed in the `deployment-group-id_last_successful_install` file. This file is located in:

   `/opt/codedeploy-agent/deployment-root/deployment-instructions` folder on Amazon Linux, Ubuntu Server, and RHEL Amazon EC2 instances. 

  `C:\ProgramData\Amazon\CodeDeploy\deployment-instructions` folder on Windows Server Amazon EC2 instances.

  To troubleshoot a deployment that fails during the `ApplicationStop` deployment lifecycle event, see [Troubleshooting a failed ApplicationStop, BeforeBlockTraffic, or AfterBlockTraffic deployment lifecycle event](troubleshooting-deployments.md#troubleshooting-deployments-lifecycle-event-failures).
+ `DownloadBundle` – During this deployment lifecycle event, the CodeDeploy agent copies the application revision files to a temporary location: 

  `/opt/codedeploy-agent/deployment-root/deployment-group-id/deployment-id/deployment-archive` folder on Amazon Linux, Ubuntu Server, and RHEL Amazon EC2 instances. 

  `C:\ProgramData\Amazon\CodeDeploy\deployment-group-id\deployment-id\deployment-archive` folder on Windows Server Amazon EC2 instances. 

  This event is reserved for the CodeDeploy agent and cannot be used to run scripts.

  To troubleshoot a deployment that fails during the `DownloadBundle` deployment lifecycle event, see [Troubleshooting a failed DownloadBundle deployment lifecycle event with UnknownError: not opened for reading](troubleshooting-deployments.md#troubleshooting-deployments-downloadbundle).
+ `BeforeInstall` – You can use this deployment lifecycle event for preinstall tasks, such as decrypting files and creating a backup of the current version.
+ `Install` – During this deployment lifecycle event, the CodeDeploy agent copies the revision files from the temporary location to the final destination folder. This event is reserved for the CodeDeploy agent and cannot be used to run scripts.
+ `AfterInstall` – You can use this deployment lifecycle event for tasks such as configuring your application or changing file permissions.
+ `ApplicationStart` – You typically use this deployment lifecycle event to restart services that were stopped during `ApplicationStop`.
+ `ValidateService` – This is the last deployment lifecycle event. It is used to verify the deployment was completed successfully.
+ `BeforeBlockTraffic` – You can use this deployment lifecycle event to run tasks on instances before they are deregistered from a load balancer.

  To troubleshoot a deployment that fails during the `BeforeBlockTraffic` deployment lifecycle event, see [Troubleshooting a failed ApplicationStop, BeforeBlockTraffic, or AfterBlockTraffic deployment lifecycle event](troubleshooting-deployments.md#troubleshooting-deployments-lifecycle-event-failures).
+ `BlockTraffic` – During this deployment lifecycle event, internet traffic is blocked from accessing instances that are currently serving traffic. This event is reserved for the CodeDeploy agent and cannot be used to run scripts. 
+ `AfterBlockTraffic` – You can use this deployment lifecycle event to run tasks on instances after they are deregistered from their respective load balancer. 

  To troubleshoot a deployment that fails during the `AfterBlockTraffic` deployment lifecycle event, see [Troubleshooting a failed ApplicationStop, BeforeBlockTraffic, or AfterBlockTraffic deployment lifecycle event](troubleshooting-deployments.md#troubleshooting-deployments-lifecycle-event-failures).
+ `BeforeAllowTraffic` – You can use this deployment lifecycle event to run tasks on instances before they are registered with a load balancer.
+ `AllowTraffic` – During this deployment lifecycle event, internet traffic is allowed to access instances after a deployment. This event is reserved for the CodeDeploy agent and cannot be used to run scripts.
+ `AfterAllowTraffic` – You can use this deployment lifecycle event to run tasks on instances after they are registered with a load balancer.

### Lifecycle event hook availability


The following table lists the lifecycle event hooks available for each deployment and rollback scenario.


| Lifecycle event name | Auto Scaling launch deployment¹ | Auto Scaling termination deployment¹ | In-place deployment² | Blue/green deployment: Original instances | Blue/green deployment: Replacement instances | Blue/green deployment rollback: Original instances | Blue/green deployment rollback: Replacement instances | 
| --- | --- | --- | --- | --- | --- | --- | --- | 
| ApplicationStop | ✓ | ✓ | ✓ |  | ✓ |  |  | 
| DownloadBundle³ | ✓ |  | ✓ |  | ✓ |  |  | 
| BeforeInstall | ✓ |  | ✓ |  | ✓ |  |  | 
| Install³ | ✓ |  | ✓ |  | ✓ |  |  | 
| AfterInstall | ✓ |  | ✓ |  | ✓ |  |  | 
| ApplicationStart | ✓ |  | ✓ |  | ✓ |  |  | 
| ValidateService | ✓ |  | ✓ |  | ✓ |  |  | 
| BeforeBlockTraffic |  | ✓ | ✓ | ✓ |  |  | ✓ | 
| BlockTraffic³ |  | ✓ | ✓ | ✓ |  |  | ✓ | 
| AfterBlockTraffic |  | ✓ | ✓ | ✓ |  |  | ✓ | 
| BeforeAllowTraffic | ✓ |  | ✓ |  | ✓ | ✓ |  | 
| AllowTraffic³ | ✓ |  | ✓ |  | ✓ | ✓ |  | 
| AfterAllowTraffic | ✓ |  | ✓ |  | ✓ | ✓ |  | 
|  ¹ For information about Amazon EC2 Auto Scaling deployments, see [How Amazon EC2 Auto Scaling works with CodeDeploy](integrations-aws-auto-scaling.md#integrations-aws-auto-scaling-behaviors). ² Also applies to the rollback of an in-place deployment. ³ Reserved for CodeDeploy operations. Cannot be used to run scripts.  | 

### Run order of hooks in a deployment


**Auto Scaling launch deployments**

During an Auto Scaling launch deployment, CodeDeploy runs event hooks in the following order.

For more information about Auto Scaling launch deployments, see [How Amazon EC2 Auto Scaling works with CodeDeploy](integrations-aws-auto-scaling.md#integrations-aws-auto-scaling-behaviors).

![\[The order of event hooks during an Auto Scaling launch deployment.\]](http://docs.aws.amazon.com/codedeploy/latest/userguide/images/lifecycle-event-order-scale-out.png)


**Note**  
The **Start**, **DownloadBundle**, **Install**, **AllowTraffic**, and **End** events in the deployment cannot be scripted, which is why they appear in gray in this diagram. However, you can edit the `'files'` section of the AppSpec file to specify what's installed during the **Install** event.

**Auto Scaling termination deployments**

During an Auto Scaling termination deployment, CodeDeploy runs event hooks in the following order.

For more information about Auto Scaling termination deployments, see [Enabling termination deployments during Auto Scaling scale-in events](integrations-aws-auto-scaling.md#integrations-aws-auto-scaling-behaviors-hook-enable).

![\[The order of event hooks during an Auto Scaling termination deployment.\]](http://docs.aws.amazon.com/codedeploy/latest/userguide/images/lifecycle-event-order-scale-in.png)


**Note**  
The **Start**, **BlockTraffic**, and **End** events in the deployment cannot be scripted, which is why they appear in gray in this diagram. 

**In-place deployments**

In an in-place deployment, including the rollback of an in-place deployment, event hooks are run in the following order:

**Note**  
For in-place deployments, the six hooks related to blocking and allowing traffic apply only if you specify a Classic Load Balancer, Application Load Balancer, or Network Load Balancer from Elastic Load Balancing in the deployment group.

![\[The order of event hooks during the rollback of an in-place deployment.\]](http://docs.aws.amazon.com/codedeploy/latest/userguide/images/lifecycle-event-order-in-place.png)


**Note**  
The **Start**, **DownloadBundle**, **Install**, and **End** events in the deployment cannot be scripted, which is why they appear in gray in this diagram. However, you can edit the `'files'` section of the AppSpec file to specify what's installed during the **Install** event.

**Blue/green deployments**

In a blue/green deployment, event hooks are run in the following order:

![\[The order of event hooks in a blue/green deployment.\]](http://docs.aws.amazon.com/codedeploy/latest/userguide/images/lifecycle-event-order-blue-green.png)


**Note**  
The **Start**, **DownloadBundle**, **Install**, **BlockTraffic**, **AllowTraffic**, and **End** events in the deployment cannot be scripted, which is why they appear in gray in this diagram. However, you can edit the 'files' section of the AppSpec file to specify what's installed during the **Install** event.

### Structure of 'hooks' section


The `'hooks'` section has the following structure:

```
hooks:
   deployment-lifecycle-event-name:
     - location: script-location
       timeout: timeout-in-seconds
       runas: user-name
```

You can include the following elements in a **hook** entry after the deployment lifecycle event name:

** location **  
Required. The location in the bundle of the script file for the revision. The location of scripts you specify in the `hooks` section is relative to the root of the application revision bundle. For more information, see [Plan a revision for CodeDeploy](application-revisions-plan.md).

** timeout **  
Optional. The number of seconds to allow the script to execute before it is considered to have failed. The default is 3600 seconds (1 hour).  
3600 seconds (1 hour) is the maximum amount of time allowed for script execution for each deployment lifecycle event. If scripts exceed this limit, the deployment stops and the deployment to the instance fails. Make sure the total number of seconds specified in **timeout** for all scripts in each deployment lifecycle event does not exceed this limit.

** runas **  
Optional. The user to impersonate when running the script. By default, this is the CodeDeploy agent running on the instance. CodeDeploy does not store passwords, so the user cannot be impersonated if the **runas** user needs a password. This element applies to Amazon Linux and Ubuntu Server instances only.

### Referencing files in your hook scripts


If you are hooking up a script to a CodeDeploy lifecycle event as described in [AppSpec 'hooks' section](#reference-appspec-file-structure-hooks), and you want to reference a file (for example, `helper.sh`) in your script, then you will need to specify `helper.sh` using:
+ (Recommended) An absolute path. See [Using absolute paths](#codedeploy-agent-working-dir-absolute).
+ A relative path. See [Using relative paths](#codedeploy-agent-working-dir-relative).

#### Using absolute paths


To reference a file using its *absolute* path, you can either:
+ Specify the absolute path in the `files` section of the AppSpec file, in the `destination` property. Then, specify the same absolute path in your hook script. For more information, see [AppSpec 'files' section (EC2/On-Premises deployments only)](reference-appspec-file-structure-files.md). 
+ Specify a dynamic absolute path in your hook script. For more information, see [Deployment archive location](#codedeploy-agent-working-dir-archive).

**Deployment archive location**

During the [DownloadBundle](#reference-appspec-file-structure-hooks-list) lifecycle event, the CodeDeploy agent extracts the [revision](application-revisions.md) for the deployment to a directory that has the following format:

`root-directory/deployment-group-id/deployment-id/deployment-archive`

The *root-directory* portion of the path is always set to either the default shown in the following table, or is controlled by the `:root_dir` configuration setting. For more information about configuration settings, see [CodeDeploy agent configuration reference](reference-agent-configuration.md).


| Agent platform | Default root directory | 
| --- | --- | 
| Linux – all rpm distributions |  /opt/codedeploy-agent/deployment-root  | 
| Ubuntu Server – all deb distributions |  /opt/codedeploy-agent/deployment-root  | 
| Windows Server |  %ProgramData%\$1Amazon\$1CodeDeploy  | 

From your hook scripts, you could access the current deployment archive using the the root directory path and the `DEPLOYMENT_ID` and `DEPLOYMENT_GROUP_ID` environment variables. For more information about variables you can use, see [Environment variable availability for hooks](#reference-appspec-file-structure-environment-variable-availability).

For example, here is how you could access a `data.json` file that resides at the root of your revision on Linux:

```
#!/bin/bash

rootDirectory="/opt/codedeploy-agent/deployment-root" # note: this will be different if you
                                                      # customize the :root_dir configuration
dataFile="$rootDirectory/$DEPLOYMENT_GROUP_ID/$DEPLOYMENT_ID/deployment-archive/data.json"
data=$(cat dataFile)
```

As another example, here is how you could access a `data.json` file that resides at the root of your revision using Powershell on Windows:

```
$rootDirectory="$env:ProgramData\Amazon\CodeDeploy" # note: this will be different if you
                                                    # customize the :root_dir configuration
$dataFile="$rootDirectory\$env:DEPLOYMENT_GROUP_ID\$env:DEPLOYMENT_ID\deployment-archive\data.json"
$data=(Get-Content $dataFile)
```

#### Using relative paths


To reference a file using its *relative* path, you'll need to know the CodeDeploy agent's working directory. File paths are relative to this directory.

The following table shows the working directory for each supported platform of the CodeDeploy agent.

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/codedeploy/latest/userguide/reference-appspec-file-structure-hooks.html)

### Environment variable availability for hooks


During each deployment lifecycle event, hook scripts can access the following environment variables:

** APPLICATION\$1NAME **  
The name of the application in CodeDeploy that is part of the current deployment (for example, `WordPress_App`).

** DEPLOYMENT\$1ID **  
The ID CodeDeploy has assigned to the current deployment (for example, `d-AB1CDEF23`).

** DEPLOYMENT\$1GROUP\$1NAME **  
The name of the deployment group in CodeDeploy that is part of the current deployment (for example, `WordPress_DepGroup`).

** DEPLOYMENT\$1GROUP\$1ID **  
The ID of the deployment group in CodeDeploy that is part of the current deployment (for example, `b1a2189b-dd90-4ef5-8f40-4c1c5EXAMPLE`).

** LIFECYCLE\$1EVENT **  
The name of the current deployment lifecycle event (for example, `AfterInstall`).

These environment variables are local to each deployment lifecycle event.

 There are additional environment variables available to hook scripts depending on the source of the deployment bundle:

**Bundle from Amazon S3**
+ **BUNDLE\$1BUCKET**

  The name of the Amazon S3 bucket from which the deployment bundle was downloaded (for example, `my-s3-bucket`).
+ **BUNDLE\$1KEY**

  The object key for the downloaded bundle within the Amazon S3 bucket (for example, `WordPress_App.zip`).
+ **BUNDLE\$1VERSION**

  The object version for the bundle (for example, `3sL4kqtJlcpXroDTDmJ+rmSpXd3dIbrHY+MTRCxf3vjVBH40Nr8X8gdRQBpUMLUo`). This variable is only set if the Amazon S3 bucket has [object versioning](https://docs.aws.amazon.com/AmazonS3/latest/userguide/Versioning.html) enabled.
+ **BUNDLE\$1ETAG**

  The object etag for the bundle (for example, `b10a8db164e0754105b7a99be72e3fe5-4`).

**Bundle from GitHub**
+ **BUNDLE\$1COMMIT**

  The SHA256 commit hash of the bundle generated by Git (for example, `d2a84f4b8b650937ec8f73cd8be2c74add5a911ba64df27458ed8229da804a26`).

The following script changes the listening port on an Apache HTTP server to 9090 instead of 80 if the value of **DEPLOYMENT\$1GROUP\$1NAME** is equal to `Staging`. This script must be invoked during the `BeforeInstall` deployment lifecycle event:

```
if [ "$DEPLOYMENT_GROUP_NAME" == "Staging" ]
then
    sed -i -e 's/Listen 80/Listen 9090/g' /etc/httpd/conf/httpd.conf
fi
```

The following script example changes the verbosity level of messages recorded in its error log from warning to debug if the value of the **DEPLOYMENT\$1GROUP\$1NAME** environment variable is equal to `Staging`. This script must be invoked during the `BeforeInstall` deployment lifecycle event:

```
if [ "$DEPLOYMENT_GROUP_NAME" == "Staging" ]
then
    sed -i -e 's/LogLevel warn/LogLevel debug/g' /etc/httpd/conf/httpd.conf
fi
```

The following script example replaces the text in the specified webpage with text that displays the value of these environment variables. This script must be invoked during the `AfterInstall` deployment lifecycle event:

```
#!/usr/bin/python

import os
 
strToSearch="<h2>This application was deployed using CodeDeploy.</h2>"
strToReplace="<h2>This page for "+os.environ['APPLICATION_NAME']+" application and "+os.environ['DEPLOYMENT_GROUP_NAME']+" deployment group with "+os.environ['DEPLOYMENT_GROUP_ID']+" deployment group ID was generated by a "+os.environ['LIFECYCLE_EVENT']+" script during "+os.environ['DEPLOYMENT_ID']+" deployment.</h2>"
 
fp=open("/var/www/html/index.html","r")
buffer=fp.read()
fp.close()
 
fp=open("/var/www/html/index.html","w")
fp.write(buffer.replace(strToSearch,strToReplace))
fp.close()
```

### Hooks example


Here is an example of a **hooks** entry that specifies two hooks for the `AfterInstall` lifecycle event:

```
hooks:
   AfterInstall:
     - location: Scripts/RunResourceTests.sh
       timeout: 180
     - location: Scripts/PostDeploy.sh
       timeout: 180
```

The `Scripts/RunResourceTests.sh` script runs during the `AfterInstall` stage of the deployment process. The deployment is unsuccessful if it takes the script more than 180 seconds (3 minutes) to run.

The location of scripts you specify in the 'hooks' section is relative to the root of the application revision bundle. In the preceding example, a file named `RunResourceTests.sh` is in a directory named `Scripts`. The `Scripts` directory is at the root level of the bundle. For more information, see [Plan a revision for CodeDeploy](application-revisions-plan.md).

# AppSpec File example


This topic provides example AppSpec files for an AWS Lambda and an EC2/On-Premises deployment.

**Topics**
+ [

## AppSpec File example for an Amazon ECS deployment
](#appspec-file-example-ecs)
+ [

## AppSpec File example for an AWS Lambda deployment
](#appspec-file-example-lambda)
+ [

## AppSpec File example for an EC2/On-Premises deployment
](#appspec-file-example-server)

## AppSpec File example for an Amazon ECS deployment


 Here is an example of an AppSpec file written in YAML for deploying an Amazon ECS service. 

```
version: 0.0
Resources:
  - TargetService:
      Type: AWS::ECS::Service
      Properties:
        TaskDefinition: "arn:aws:ecs:us-east-1:111222333444:task-definition/my-task-definition-family-name:1"
        LoadBalancerInfo:
          ContainerName: "SampleApplicationName"
          ContainerPort: 80
# Optional properties
        PlatformVersion: "LATEST"
        NetworkConfiguration:
          AwsvpcConfiguration:
            Subnets: ["subnet-1234abcd","subnet-5678abcd"]
            SecurityGroups: ["sg-12345678"]
            AssignPublicIp: "ENABLED"
        CapacityProviderStrategy:
          - Base: 1
            CapacityProvider: "FARGATE_SPOT"
            Weight: 2
          - Base: 0
            CapacityProvider: "FARGATE"
            Weight: 1
Hooks:
  - BeforeInstall: "LambdaFunctionToValidateBeforeInstall"
  - AfterInstall: "LambdaFunctionToValidateAfterInstall"
  - AfterAllowTestTraffic: "LambdaFunctionToValidateAfterTestTrafficStarts"
  - BeforeAllowTraffic: "LambdaFunctionToValidateBeforeAllowingProductionTraffic"
  - AfterAllowTraffic: "LambdaFunctionToValidateAfterAllowingProductionTraffic"
```

 Here is a version of the preceding example written in JSON. 

```
{
    "version": 0.0,
    "Resources": [
        {
            "TargetService": {
                "Type": "AWS::ECS::Service",
                "Properties": {
                    "TaskDefinition": "arn:aws:ecs:us-east-1:111222333444:task-definition/my-task-definition-family-name:1",
                    "LoadBalancerInfo": {
                        "ContainerName": "SampleApplicationName",
                        "ContainerPort": 80
                    },
                    "PlatformVersion": "LATEST",
                    "NetworkConfiguration": {
                        "AwsvpcConfiguration": {
                            "Subnets": [
                                "subnet-1234abcd",
                                "subnet-5678abcd"
                            ],
                            "SecurityGroups": [
                                "sg-12345678"
                            ],
                            "AssignPublicIp": "ENABLED"
                        }
                    },
                    "CapacityProviderStrategy": [
                        {
                            "Base" : 1,
                            "CapacityProvider" : "FARGATE_SPOT",
                            "Weight" : 2
                        },
                        {
                            "Base" : 0,
                            "CapacityProvider" : "FARGATE",
                            "Weight" : 1
                        }
                    ]
                }               
            }
        }
    ],
    "Hooks": [
        {
            "BeforeInstall": "LambdaFunctionToValidateBeforeInstall"
        },
        {
            "AfterInstall": "LambdaFunctionToValidateAfterInstall"
        },
        {
            "AfterAllowTestTraffic": "LambdaFunctionToValidateAfterTestTrafficStarts"
        },
        {
            "BeforeAllowTraffic": "LambdaFunctionToValidateBeforeAllowingProductionTraffic"
        },
        {
            "AfterAllowTraffic": "LambdaFunctionToValidateAfterAllowingProductionTraffic"
        }
    ]
}
```

Here is the sequence of events during deployment:

1.  Before the updated Amazon ECS application is installed on the replacement task set, the Lambda function called `LambdaFunctionToValidateBeforeInstall` runs. 

1.  After the updated Amazon ECS application is installed on the replacement task set, but before it receives any traffic, the Lambda function called `LambdaFunctionToValidateAfterInstall` runs. 

1.  After the Amazon ECS application on the replacement task set starts receiving traffic from the test listener, the Lambda function called `LambdaFunctionToValidateAfterTestTrafficStarts` runs. This function likely runs validation tests to determine if the deployment continues. If you do not specify a test listener in your deployment group, this hook is ignored. 

1.  After any validation tests in the `AfterAllowTestTraffic` hook are completed, and before production traffic is served to the updated Amazon ECS application, the Lambda function called `LambdaFunctionToValidateBeforeAllowingProductionTraffic` runs. 

1.  After production traffic is served to the updated Amazon ECS application on the replacement task set, the Lambda function called `LambdaFunctionToValidateAfterAllowingProductionTraffic` runs. 

 The Lambda functions that run during any hook can perform validation tests or gather traffic metrics. 

## AppSpec File example for an AWS Lambda deployment


 Here is an example of an AppSpec file written in YAML for deploying a Lambda function version. 

```
version: 0.0
Resources:
  - myLambdaFunction:
      Type: AWS::Lambda::Function
      Properties:
        Name: "myLambdaFunction"
        Alias: "myLambdaFunctionAlias"
        CurrentVersion: "1"
        TargetVersion: "2"
Hooks:
  - BeforeAllowTraffic: "LambdaFunctionToValidateBeforeTrafficShift"
  - AfterAllowTraffic: "LambdaFunctionToValidateAfterTrafficShift"
```

 Here is a version of the preceding example written in JSON. 

```
{
 	"version": 0.0,
 	"Resources": [{
 		"myLambdaFunction": {
 			"Type": "AWS::Lambda::Function",
 			"Properties": {
 				"Name": "myLambdaFunction",
 				"Alias": "myLambdaFunctionAlias",
 				"CurrentVersion": "1",
 				"TargetVersion": "2"
 			}
 		}
 	}],
 	"Hooks": [{
 			"BeforeAllowTraffic": "LambdaFunctionToValidateBeforeTrafficShift"
      },
      {
 			"AfterAllowTraffic": "LambdaFunctionToValidateAfterTrafficShift"
 		}
 	]
 }
```

Here is the sequence of events during deployment:

1. Before shifting traffic from version 1 of a Lambda function called `myLambdaFunction` to version 2, run a Lambda function called `LambdaFunctionToValidateBeforeTrafficShift` that validates the deployment is ready to start traffic shifting.

1. If `LambdaFunctionToValidateBeforeTrafficShift` returned an exit code of 0 (success), begin shifting traffic to version 2 of `myLambdaFunction`. The deployment configuration for this deployment determines the rate at which traffic is shifted.

1. After the shifting of traffic from version 1 of a Lambda function called `myLambdaFunction` to version 2 is complete, run a Lambda function called `LambdaFunctionToValidateAfterTrafficShift` that validates the deployment was completed successfully.

## AppSpec File example for an EC2/On-Premises deployment


Here is an example of an AppSpec file for an in-place deployment to an Amazon Linux, Ubuntu Server, or RHEL instance. 

**Note**  
 Deployments to Windows Server instances do not support the `runas` element. If you are deploying to Windows Server instances, do not include it in your AppSpec file. 

```
version: 0.0
os: linux
files:
  - source: Config/config.txt
    destination: /webapps/Config
  - source: source
    destination: /webapps/myApp
hooks:
  BeforeInstall:
    - location: Scripts/UnzipResourceBundle.sh
    - location: Scripts/UnzipDataBundle.sh
  AfterInstall:
    - location: Scripts/RunResourceTests.sh
      timeout: 180
  ApplicationStart:
    - location: Scripts/RunFunctionalTests.sh
      timeout: 3600
  ValidateService:
    - location: Scripts/MonitorService.sh
      timeout: 3600
      runas: codedeployuser
```

For a Windows Server instance, change `os: linux` to `os: windows`. Also, you must fully qualify the `destination` paths (for example, `c:\temp\webapps\Config` and `c:\temp\webapps\myApp`). Do not include the `runas` element. 

Here is the sequence of events during deployment:

1. Run the script located at `Scripts/UnzipResourceBundle.sh`.

1. If the previous script returned an exit code of 0 (success), run the script located at `Scripts/UnzipDataBundle.sh`.

1. Copy the file from the path of `Config/config.txt` to the path `/webapps/Config/config.txt`.

1. Recursively copy all the files in the `source` directory to the `/webapps/myApp` directory.

1. Run the script located at `Scripts/RunResourceTests.sh` with a timeout of 180 seconds (3 minutes).

1. Run the script located at `Scripts/RunFunctionalTests.sh` with a timeout of 3600 seconds (1 hour).

1. Run the script located at `Scripts/MonitorService.sh` as the user `codedeploy` with a timeout of 3600 seconds (1 hour).

## AppSpec File spacing


The following is the correct format for AppSpec file spacing. The numbers in square brackets indicate the number of spaces that must occur between items. For example, `[4]` means to insert four spaces between the items. CodeDeploy raises an error that might be difficult to debug if the locations and number of spaces in an AppSpec file are not correct.

```
version:[1]version-number
os:[1]operating-system-name
files:
[2]-[1]source:[1]source-files-location
[4]destination:[1]destination-files-location
permissions:
[2]-[1]object:[1]object-specification
[4]pattern:[1]pattern-specification
[4]except:[1]exception-specification
[4]owner:[1]owner-account-name
[4]group:[1]group-name
[4]mode:[1]mode-specification
[4]acls: 
[6]-[1]acls-specification 
[4]context:
[6]user:[1]user-specification
[6]type:[1]type-specification
[6]range:[1]range-specification
[4]type:
[6]-[1]object-type
hooks:
[2]deployment-lifecycle-event-name:
[4]-[1]location:[1]script-location
[6]timeout:[1]timeout-in-seconds
[6]runas:[1]user-name
```

Here is an example of a correctly spaced AppSpec file:

```
version: 0.0
os: linux
files:
  - source: /
    destination: /var/www/html/WordPress
hooks:
  BeforeInstall:
    - location: scripts/install_dependencies.sh
      timeout: 300
      runas: root
  AfterInstall:
    - location: scripts/change_permissions.sh
      timeout: 300
      runas: root
  ApplicationStart:
    - location: scripts/start_server.sh
    - location: scripts/create_test_db.sh
      timeout: 300
      runas: root
  ApplicationStop:
    - location: scripts/stop_server.sh
      timeout: 300
      runas: root
```

For more information about spacing, see the [YAML](http://www.yaml.org) specification.

# Validate your AppSpec File and file location


 **File syntax** 

You can use the AWS-provided AppSpec Assistant script to validate the contents of an AppSpec file. You can find the script along with AppSpec file templates on [GitHub](https://github.com/aws-samples/aws-codedeploy-appspec-assistant).

You can also use a browser-based tool such as [YAML lint](http://www.yamllint.com/) or [Online YAML parser](http://yaml-online-parser.appspot.com/) to help you check your YAML syntax.

 **File location** 

To verify that you have placed your AppSpec file in the root directory of the application's source content's directory structure, run one of the following commands:

On local Linux, macOS, or Unix instances:

```
ls path/to/root/directory/appspec.yml
```

If the AppSpec file is not located there, a "No such file or directory" error is displayed.

On local Windows instances:

```
dir path\to\root\directory\appspec.yml
```

If the AppSpec file is not located there, a "File Not Found" error is displayed.