Pipeline fails with YAML syntax error on push but not when run manually

We’ve had pipelines setup for multiple GitLab.com repos that run successfully using shared runners for some time now but just recently they started failing when triggered from a commit/push with this error:

Found errors in your .gitlab-ci.yml:

  • Included file .gitlab-ci.yml does not have valid YAML syntax!

You can also test your .gitlab-ci.yml in CI Lint

The CI Lint indicates the yml is valid and when using the GitLab.com UI and going to Pipelines > Run Pipeline it executes without any issues. Here’s the CI with sensitive info removed (it deploys an AWS Lambda):

From: https://gist.github.com/m8r1x/8b5c8267078007984a29b03c2db1fe05
variables:
  LAMBDA_NAME: 'LambdaName'   # Replace it with the name of aws lambda function you want.
  LAMBDA_ARN: 'arn:aws:lambda:us-east-1:AccountNumber:function:LambdaName' # ARN associated with this lambda function.
  ZIP_FILENAME: 'LambdaName.zip' # This is the name of the ZIP package that will be created and uploaded to S3
  LAMBDA_ENVIRONMENT_DEFAULT: "Variables={ENV=dev}"
  LAMBDA_ENVIRONMENT_STAGE: "Variables={ENV=stage}"
  LAMBDA_ENVIRONMENT_PROD: "Variables={ENV=prod}"
  # The following vars generally stay the same
  LAMBDA_HANDLER: 'lambda_function.lambda_handler'  # This is default lambda handler.
  LAMBDA_RUNTIME: 'python3.7'
  S3_BUCKET: 'BucketName'   # Replace it with the name of Bucket that will hold the zip code.
  LAMBDA_ROLE_ARN: 'arn:aws:iam::AccountNumber:role/RoleName'
  LAYERS_ARN: 'arn:aws:lambda:us-east-1:AccountNumber:layer:LayerName:114 arn:aws:lambda:us-east-1:AccountNumber:layer:OtherLayerName:108'
  LAMBDA_TIMEOUT: 900  # Default is 3, up to 900. Setting this to 30 for all "local" functions, and 90 for ones using external APIs
  LAMBDA_MEMORY: 3008  # Default is 128, up to 3008 in 64 MB increments

image: python:latest

before_script:
  - apt-get update -y  # Updating the Ubuntu Docker instance.
  - python -V  # Print out python version for debugging.
  - apt install -y zip jq
  - pip install awscli --upgrade --user --trusted-host=pypi.python.org --trusted-host=pypi.org --trusted-host=files.pythonhosted.org
  - export PATH=~/.local/bin:$PATH # Required for awscli.
  - aws --version  # Print out aws cli version for debugging.

stages:
  - deploy-dev
  - deploy-stage # manual deploy
  - deploy-prod # manual deploy


deploy-dev:
  stage: deploy-dev

  only:
    - dev   # We will run the CD only when something is going to change in dev branch.

  before_script:
    - apt-get update -y  # Updating the Ubuntu Docker instance.
    - python -V  # Print out python version for debugging.
    - apt install -y zip jq
    - pip install awscli --upgrade --user
    - export PATH=~/.local/bin:$PATH # Required for awscli.
    - aws --version  # Print out aws cli version for debugging.
    # set dev LAMBDA_ENVIRONMENT and vars
    - export LAMBDA_ENVIRONMENT=$LAMBDA_ENVIRONMENT_DEFAULT
    - echo $LAMBDA_ENVIRONMENT
    - export LAMBDA_ALIAS="DEV"
    - echo $LAMBDA_ALIAS

  script:
    # Archive the code repository.
    - zip -r $ZIP_FILENAME . -x \*.pyc *.git*
    # Upload archive into s3.
    - aws s3 cp $ZIP_FILENAME s3://$S3_BUCKET/$ZIP_FILENAME
    # Update the Lambda with the uploaded code
    - aws lambda update-function-code --function-name $LAMBDA_NAME --zip-file fileb://$ZIP_FILENAME || aws lambda create-function --function-name $LAMBDA_NAME --runtime $LAMBDA_RUNTIME --role $LAMBDA_ROLE_ARN --handler $LAMBDA_HANDLER --code S3Bucket=$S3_BUCKET,S3Key=$ZIP_FILENAME --memory-size $LAMBDA_MEMORY --layers $LAYERS_ARN --environment $LAMBDA_ENVIRONMENT --timeout $LAMBDA_TIMEOUT
    # Create lambda alias in case it doesn't exist
    # Update the Lambda config to use the layers specified above, and the environment vars corresponding to this branch
    - aws lambda create-alias --function-name $LAMBDA_NAME --name $LAMBDA_ALIAS --function-version '$LATEST' || aws lambda update-function-configuration --function-name $LAMBDA_NAME --layers $LAYERS_ARN --handler $LAMBDA_HANDLER --environment $LAMBDA_ENVIRONMENT --memory-size $LAMBDA_MEMORY --timeout $LAMBDA_TIMEOUT
    # Publish a new version of the Lambda (including the environment vars set in the previous step), catch the Version number from the output
    - "export LAMBDA_VERSION=$(aws lambda publish-version --function-name $LAMBDA_NAME --query \'Version\' --output text)"
    # Update the Lambda alias corresponding to this branch to use the Version we just published
    - aws lambda update-alias --function-name $LAMBDA_NAME --name $LAMBDA_ALIAS --function-version $LAMBDA_VERSION
    # Reset Lambda config environment vars to default so Latest has the dev vars
    - aws lambda update-function-configuration --function-name $LAMBDA_NAME --layers $LAYERS_ARN --handler $LAMBDA_HANDLER --environment $LAMBDA_ENVIRONMENT_DEFAULT --memory-size $LAMBDA_MEMORY --timeout $LAMBDA_TIMEOUT

  environment:
    name: dev


deploy-stage:
  stage: deploy-stage

  only:
    - stage   # We will run the CD only when something is going to change in stage branch.

  before_script:
    - apt-get update -y  # Updating the Ubuntu Docker instance.
    - python -V  # Print out python version for debugging.
    - apt install -y zip jq
    - pip install awscli --upgrade --user
    - export PATH=~/.local/bin:$PATH # Required for awscli.
    - aws --version  # Print out aws cli version for debugging.
    # set stage LAMBDA_ENVIRONMENT and vars
    - export LAMBDA_ENVIRONMENT=$LAMBDA_ENVIRONMENT_STAGE
    - echo $LAMBDA_ENVIRONMENT
    - export LAMBDA_ALIAS="STAGE"
    - echo $LAMBDA_ALIAS

  script:
    # Archive the code repository.
    - zip -r $ZIP_FILENAME . -x \*.pyc *.git*
    # Upload archive into s3.
    - aws s3 cp $ZIP_FILENAME s3://$S3_BUCKET/$ZIP_FILENAME
    # Update the Lambda with the uploaded code
    - aws lambda update-function-code --function-name $LAMBDA_NAME --zip-file fileb://$ZIP_FILENAME || aws lambda create-function --function-name $LAMBDA_NAME --runtime $LAMBDA_RUNTIME --role $LAMBDA_ROLE_ARN --handler $LAMBDA_HANDLER --code S3Bucket=$S3_BUCKET,S3Key=$ZIP_FILENAME --memory-size $LAMBDA_MEMORY --layers $LAYERS_ARN --environment $LAMBDA_ENVIRONMENT --timeout $LAMBDA_TIMEOUT --runtime $LAMBDA_RUNTIME
    # Create lambda alias in case it doesn't exist
    # Update the Lambda config to use the layers specified above, and the environment vars corresponding to this branch
    - aws lambda create-alias --function-name $LAMBDA_NAME --name $LAMBDA_ALIAS --function-version '$LATEST' || aws lambda update-function-configuration --function-name $LAMBDA_NAME --layers $LAYERS_ARN --handler $LAMBDA_HANDLER --environment $LAMBDA_ENVIRONMENT --memory-size $LAMBDA_MEMORY --timeout $LAMBDA_TIMEOUT --runtime $LAMBDA_RUNTIME
    # Publish a new version of the Lambda (including the environment vars set in the previous step), catch the Version number from the output
    - "export LAMBDA_VERSION=$(aws lambda publish-version --function-name $LAMBDA_NAME --query \'Version\' --output text)"
    # Update the Lambda alias corresponding to this branch to use the Version we just published
    - aws lambda update-alias --function-name $LAMBDA_NAME --name $LAMBDA_ALIAS --function-version $LAMBDA_VERSION
    # Reset Lambda config environment vars to default so Latest has the dev vars
    - aws lambda update-function-configuration --function-name $LAMBDA_NAME --layers $LAYERS_ARN --handler $LAMBDA_HANDLER --environment $LAMBDA_ENVIRONMENT_DEFAULT --memory-size $LAMBDA_MEMORY --timeout $LAMBDA_TIMEOUT --runtime $LAMBDA_RUNTIME

  environment:
    name: stage

  when: manual


deploy-prod:
  stage: deploy-prod

  only:
    - prod   # We will run the CD only when something is going to change in prod branch.

  before_script:
    - apt-get update -y  # Updating the Ubuntu Docker instance.
    - python -V  # Print out python version for debugging.
    - apt install -y zip jq
    - pip install awscli --upgrade --user
    - export PATH=~/.local/bin:$PATH # Required for awscli.
    - aws --version  # Print out aws cli version for debugging.
    # set prod LAMBDA_ENVIRONMENT and vars
    - export LAMBDA_ENVIRONMENT=$LAMBDA_ENVIRONMENT_PROD
    - echo $LAMBDA_ENVIRONMENT
    - export LAMBDA_ALIAS="PROD"
    - echo $LAMBDA_ALIAS

  script:
    # Archive the code repository.
    - zip -r $ZIP_FILENAME . -x \*.pyc *.git*
    # Upload archive into s3.
    - aws s3 cp $ZIP_FILENAME s3://$S3_BUCKET/$ZIP_FILENAME
    # Update the Lambda with the uploaded code
    - aws lambda update-function-code --function-name $LAMBDA_NAME --zip-file fileb://$ZIP_FILENAME || aws lambda create-function --function-name $LAMBDA_NAME --runtime $LAMBDA_RUNTIME --role $LAMBDA_ROLE_ARN --handler $LAMBDA_HANDLER --code S3Bucket=$S3_BUCKET,S3Key=$ZIP_FILENAME --memory-size $LAMBDA_MEMORY --layers $LAYERS_ARN --environment $LAMBDA_ENVIRONMENT --timeout $LAMBDA_TIMEOUT
    # Create lambda alias in case it doesn't exist
    # Update the Lambda config to use the layers specified above, and the environment vars corresponding to this branch
    - aws lambda create-alias --function-name $LAMBDA_NAME --name $LAMBDA_ALIAS --function-version '$LATEST' || aws lambda update-function-configuration --function-name $LAMBDA_NAME --layers $LAYERS_ARN --handler $LAMBDA_HANDLER --environment $LAMBDA_ENVIRONMENT --memory-size $LAMBDA_MEMORY --timeout $LAMBDA_TIMEOUT
    # Publish a new version of the Lambda (including the environment vars set in the previous step), catch the Version number from the output
    - "export LAMBDA_VERSION=$(aws lambda publish-version --function-name $LAMBDA_NAME --query \'Version\' --output text)"
    # Update the Lambda alias corresponding to this branch to use the Version we just published
    - aws lambda update-alias --function-name $LAMBDA_NAME --name $LAMBDA_ALIAS --function-version $LAMBDA_VERSION
    # Reset Lambda config environment vars to default so Latest has the dev vars
    - aws lambda update-function-configuration --function-name $LAMBDA_NAME --layers $LAYERS_ARN --handler $LAMBDA_HANDLER --environment $LAMBDA_ENVIRONMENT_DEFAULT --memory-size $LAMBDA_MEMORY --timeout $LAMBDA_TIMEOUT

  environment:
    name: prod

  when: manual