Deploy fails with AppSpec formatting error from CLI, same file works in console

1k Views Asked by At

I'm kicking off a CodeDeploy deployment with the following command:

aws deploy create-deployment --cli-input-json file://create-deployment.json

My create-deployment.json file looks like this:

{
    "applicationName": "myapp",
    "deploymentGroupName": "myapp-test",
    "revision": {
        "revisionType": "AppSpecContent",
        "appSpecContent": {
            "content": "appspec.json"
        }
    }
}

I get a deployment ID response. The deploy is kicked off successfully, but it immediately fails with the error

The deployment failed because the AppSpec file that specifies the deployment configuration is missing or has an invalid configuration. The input AppSpec file is a not well-formed yaml. The template cannot be parsed.

My appspec file is clearly JSON, not YAML. I have successfully launched a deployment with the same appspec.json file from the console, where you can explicitly tell AWS that the appspec is a JSON file. The docs for create-deployment indicate that a JSON file should be acceptable. There is no option to explicitly state the format of the appspec file if you're using AppSpecContent instead of an S3 Bucket. It seems like CodeDeploy can't actually figure out that it has received a JSON appspec file instead of YAML.

I tried using an YAML file as well, and it also failed with the same error message. I started deploys with the same appspec files (both JSON and YAML) from the console successfully.

2

There are 2 best solutions below

0
On

content expects a raw JSON or YAML string, but you're passing a file name (appspec.json). That is why the deployment throws an error that it can't parse the template. And that is no matter whether you're using a JSON or YAML file as input, the problem is the same as the raw string is expected, not a file name. This is also why you're seeing a different behavior as compared to the console, where this is automatically converted to a raw string behind the scenes.

To fix your problem, the content of your create-deployment.json should instead look similar to the below:

{
    "applicationName": "myapp",
    "deploymentGroupName": "myapp-test",
    "revision": {
        "revisionType": "AppSpecContent",
        "appSpecContent": {
            "content": "{\"Resources\":[{\"my-function\":{\"Properties\":{\"Alias\":\"my-alias\",\"CurrentVersion\":\"1\",\"Name\":\"my-name\",\"TargetVersion\":\"1\"},\"Type\":\"AWS::Lambda::Function\"}}],\"version\":\"0.0\"}"
        }
    }
}
0
On

In the yaml syntax you can use:

aws deploy create-deployment --cli-input-yaml file://create-deployment.yaml

Where create-deployment.yaml would have the following structure (example for ecs service):

applicationName: 'myapp'
deploymentGroupName: 'myapp-test'
revision:
  revisionType: AppSpecContent
  appSpecContent:
    content: |
      version: 0.0
      Resources:
        - TargetService:
            Type: AWS::ECS::Service
            Properties:
              TaskDefinition: "[YOUR_TASK_DEFINITION_ARN]"
              LoadBalancerInfo:
                ContainerName: "ecs-service-container"
                ContainerPort: 8080

Or other service as you prefer for your deployment group for example: EC2