'Export and ImportValue in another stack under sub

I am trying to get a value from one stack to another using the below syntax.

stack one-

Outputs:
  CompRestAPI:
    Description: Rest Api Id
    Value: !Ref CompRestAPI
    Export:
      Name: 'CompRestAPI'

Stack two -

CompRestApiWaf:
    Type: AWS::WAFv2::WebACLAssociation
    DependsOn: CompApiGatewayStage
    Properties:
      RestApiId: !ImportValue 'CompRestAPI'
      ResourceArn: !Sub 'arn:aws:apigateway:${REGION}:/${RestApiId}/${STAGENAME}-apistage'
      WebACLArn: !Ref WafId

I am able to get the values for other resources using 1st syntax, but I am not able to get the value for RestApiId under !Sub

RestApiId: !ImportValue 'CompRestAPI'

ResourceArn: !Sub 'arn:aws:apigateway:${REGION}:/${RestApiId}/apistage'

So is there any way to use !ImportValue under !Sub condition?

I tried it using below code, validation is pass but still showing me an error Error reason: The ARN isn't valid. A valid ARN begins with arn: and includes other information separated by colons or slashes., field: RESOURCE_ARN, parameter:

 CompRestApiWaf:
    Type: AWS::WAFv2::WebACLAssociation
    DependsOn: CompApiGatewayStage
    Properties:
      ResourceArn: !Sub 'arn:aws:apigateway:${REGION}:/{!ImportValue CompRestAPI}/stages/apistage'
      WebACLArn: !Ref WafId


Solution 1:[1]

I am done with it using Fn::join:

SourceArn: 
    Fn::Join: 
    - ""
    - - 'arn:aws:execute-api:'
      - !Ref AWS::Region
      - ':'
      - !Ref AWS::AccountId
      - ':'
      - !Ref ApiGatewayRestApiResource
      - '/*'

Solution 2:[2]

this should work

ResourceArn: !Sub
  - 'arn:aws:apigateway:${REGION}:/${CompRestAPI}/stages/apistage'
  - CompRestAPI: !ImportValue CompRestAPI

you can expand the second parameter to have multiple keys for multiple imports like so

SecretString: !Sub
  - 'postgres://${username}:${password}@${dbhost}:${dbport}/${dbname}'
  - username: !Ref 'DBUser'
    password: !Ref 'DBPassword'
    dbhost: !Ref DbMasterDnsEntry
    dbport: !GetAtt AuroraPgCluster.Endpoint.Port
    dbname: !Ref 'DBName'

Solution 3:[3]

You could loop over like so and remove the newline chars.

const data = ["foo\n", "bar"]

const res = data.map(str => str.replaceAll('\n', ''))
console.log(res)

Solution 4:[4]

Instead of trimming after the split. Split wisely and then map to replace unwanted string. No need to loop multiple times.

const str = ` - foo
 - bar`;
let chunks = str.split("\n").map(s => s.replace(/^\W+/, ""));
console.log(chunks)

let chunks2 = str.split("\n").map(s => s.split(" ")[2]);
console.log(chunks2)

Solution 5:[5]

You could use regex match with:

Match prefix "- " but exclude from capture (?<=- ) and any number of character different of "\n" [^\n]*.

const str = `
- foo
- bar
`

console.log(str.match(/(?<=- )[^\n]*/g))

Solution 6:[6]

You could for example split, remove all the empty entries, and then trim each item to also remove all the leading and trailing whitespace characters including the newlines.

Note that you don't have to escape the space and the hyphen.

const input = `- foo
- bar`;
const chunks = input.split(/ ?- ?/)
  .filter(Boolean)
  .map(s => s.trim());

console.log(chunks);

Or the same approach removing only the newlines:

const input = `- foo
- bar`;
const chunks = input.split(/ ?- ?/)
  .filter(Boolean)
  .map(s => s.replace(/\r?\n|\r/g, ''));

console.log(chunks);

Instead of split, you might also use a match with a capture group:

^ ?- ?(.*)

The pattern matches:

  • ^ Start of string
  • ?- ? Match - between optional spaces
  • (.*) Capture group 1, match the rest of the line

const input = `- foo
- bar`;
const chunks = Array.from(input.matchAll(/^ ?- ?(.*)/gm), m => m[1]);
console.log(chunks);

Solution 7:[7]

chunks.map((data) => {
    data = data.replace(/(\r\n|\n|\r|\\n|\\r)/gm, "");

   return data;
})

Solution 8:[8]

    const str = ` - foo
     - bar`;
     
     const result = str.replace(/([\r\n|\n|\r])/gm, "")
     console.log(result)

That should remove all kinds of line break in a string and after that you can perform other actions to get the expected result like.

const str = ` - foo
         - bar`;
         
         const result = str.replace(/([\r\n|\n|\r|^\s+])/gm, "")
         console.log(result)
         
         const actualResult = result.split('-')
         actualResult.splice(0,1)
         console.log(actualResult)
         
         

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 allixsenos
Solution 3 Vincent Menzel
Solution 4
Solution 5
Solution 6
Solution 7 Wang YinXing
Solution 8