How to pass error code from userdata to code pipeline to indicate the failure

In your CloudFormation template it's possible to wait until receiving a signal before completing. If this signal isn't received within the timeout window, it'll ROLLBACK the template and your deploy should fail. There are a few ways to do this. Here's some documentation options.

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-signal.html https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-waitcondition.html

I'd prefer the first option, just add a CreationPolicy on the EC2 Instance and then signal it in UserData. Like So:

Resources:
  AppEC2Instance:
    Type: "AWS::EC2::Instance"
    CreationPolicy:
      ResourceSignal:
        Timeout: "PT5M"
    Properties:
      UserData:
        Fn::Base64:
          Fn::Join:
            - ""
            - - "#!/bin/bash -x\n"
              - "aws s3 sync s3://mybucket-id/ ./\n"
              - "java -jar ./app.jar\n"
              - "/opt/aws/bin/cfn-signal -e $? --stack ",
              - !Ref AWS::StackName
              - " --resource AppEC2Instance --region "
              - !Ref AWS::Region
              - "\n"

Using -e $? should provide the exit code back to the stack and, I would hope, would then push it back to the pipeline.