Search code examples
amazon-web-servicesamazon-s3aws-lambdaaws-cloudformationaws-cloudformation-custom-resource

AWS cloudformation nested stacks failed by template URL


I'm new with cloudformation but on currently project have a template that have all resources in a unique file and we try to separate in multiple files with nested stacks option. When I try to deploy templates, execution failed by next message:

$ aws s3 cp testing-substack.yml s3://gitlab-cicd

upload: ./testing-substack.yml to s3://gitlab-cicd/testing-substack.yml


$ aws cloudformation package --template-file testing-mainstack.yml --s3-bucket gitlab-cicd --output-template testing-packstack.yaml

Unable to upload artifact substack-amp.yml referenced by TemplateURL parameter of SubstackA resource.
TemplateURL parameter of SubstackA resource is invalid. It must be a S3 URL or path to CloudFormation template file. Actual: /builds/project-0/substack-amp.yml

Next include both template (lambda functions only have a "Hello world":

testing-mainstack.yml

testing A

Resources:
  SubstackA:
    Type: 'AWS::CloudFormation::Stack'
    Properties:
      TemplateURL: testing-substack.yml

testing B

Resources:
  SubstackA:
    Type: 'AWS::CloudFormation::Stack'
    Properties:
      TemplateURL: s3://gitlab-cicd/testing-substack.yml

substack template: testing-substack.yml

  TestingSubLambda:
    Type: AWS::Serverless::Function
    Properties:
      Description: "Testing lambda inside substack"
      CodeUri: ./
      Handler: lambda-two.lambda_handler
      Runtime: python3.8
      FunctionName: TestingSubLambda
      # Role: arn:aws:iam::000365055762:role/lambda-essential-role
      Timeout: 480
      # Events:
      #   B2bCImportOrdersApiEvent:
      #     Type: Api
      #     Properties:
      #       Path: /b2b-channels/import-orders
      #       Method: GET
      #       RestApiId: !Ref B2bCAPIDev

How can I identify which is the correct method to define the substack into main stack?


Solution

  • I Fix the problem with @Shimo response, additionally, use SAM client.

    Substack A

    AWSTemplateFormatVersion: '2010-09-09'
    Transform: 'AWS::Serverless-2016-10-31'
    
    Resources:
      TestingSubLambdaA:
        Type: AWS::Serverless::Function
        Properties:
          Description: "Testing lambda mnain substack"
          CodeUri: lambda-one/
          Handler: lambda-one.lambda_handler
          Runtime: python3.8
          FunctionName: TestingSubLambdaA
          Timeout: 480
    

    Substack B

    AWSTemplateFormatVersion: '2010-09-09'
    Transform: 'AWS::Serverless-2016-10-31'
    
    Resources:
      TestingSubLambdaB:
        Type: AWS::Serverless::Function
        Properties:
          Description: "Testing lambda secondar substack"
          CodeUri: lambda-two/
          Handler: lambda-two.lambda_handler
          Runtime: python3.8
          FunctionName: TestingSubLambdaB
          Timeout: 480
    

    Main Stack

    Resources:
      SubstackA:
        Type: 'AWS::CloudFormation::Stack'
        Properties:
          TemplateURL: https://<S3-BUCKET>.s3.<AWS-REGION>.amazonaws.com/test-subkstack-a.yml
          TimeoutInMinutes: 5
          
      SubstackB:
        Type: 'AWS::CloudFormation::Stack'
        Properties:
          TemplateURL: https://<S3-BUCKET>.s3.<AWS-REGION>.amazonaws.com/test-subkstack-b.yml
          TimeoutInMinutes: 5
    

    Finally, I package substacks template before send to S3 container.

    sam package -t testing-substack-a.yml --s3-bucket <S3-BUCKET> --output-template-file test-subkstack-a.yml --region ap-northeast-1
    
    sam package -t testing-substack-b.yml --s3-bucket <S3-BUCKET> --output-template-file test-subkstack-b.yml --region <AWS-REGION>
    
    aws s3 cp test-subkstack-a.yml s3://<S3-BUCKET>
    
    aws s3 cp test-subkstack-b.yml s3://<S3-BUCKET>
    
    sam package -t testing-mainstack.yml --s3-bucket <S3-BUCKET> --output-template-file testing-packstack.yml --region <AWS-REGION>
    
    sam deploy --template-file testing-packstack.yml --stack-name TestingStackDeploy --region <AWS-REGION> --capabilities CAPABILITY_AUTO_EXPAND CAPABILITY_IAM