aws-amplify / amplify-cli

The AWS Amplify CLI is a toolchain for simplifying serverless web and mobile development.
Apache License 2.0
2.83k stars 823 forks source link

Access to pinpoint app id using cloudformation #7844

Open jeanbaptistepriez opened 3 years ago

jeanbaptistepriez commented 3 years ago

Before opening, please confirm:

JavaScript Framework

React Native

Amplify APIs

Authentication, Analytics, REST API, Push Notifications

Amplify Categories

auth, function, api, analytics, notifications

Environment information

``` System: OS: macOS 11.4 CPU: (4) x64 Intel(R) Core(TM) i7-5557U CPU @ 3.10GHz Memory: 1.50 GB / 16.00 GB Shell: 5.8 - /bin/zsh Binaries: Node: 16.3.0 - /usr/local/bin/node Yarn: 1.22.10 - /usr/local/bin/yarn npm: 7.16.0 - /usr/local/bin/npm Watchman: 2021.05.31.00 - /usr/local/bin/watchman Browsers: Chrome: 92.0.4515.107 npmPackages: @aws-amplify/pushnotification: ^4.1.2 => 4.1.2 @aws-amplify/ui-react: ^1.2.2 => 1.2.2 @babel/core: ^7.12.9 => 7.14.5 @babel/plugin-proposal-decorators: ^7.14.5 => 7.14.5 @babel/runtime: ^7.12.5 => 7.14.5 @react-native-async-storage/async-storage: ^1.15.5 => 1.15.5 @react-native-community/eslint-config: ^2.0.0 => 2.0.0 @react-native-community/netinfo: ^6.0.0 => 6.0.0 @react-native-community/push-notification-ios: ^1.8.0 => 1.8.0 (1.0.3) @react-native-picker/picker: ^1.16.1 => 1.16.1 HelloWorld: 0.0.1 RNCameraExample: 0.0.1 advanced: 0.0.1 amazon-cognito-identity-js: ^5.0.3 => 5.0.3 aws-amplify: ^4.1.0 => 4.1.0 aws-amplify-react-native: ^5.0.2 => 5.0.2 babel-jest: ^26.6.3 => 26.6.3 eslint: 7.14.0 => 7.14.0 hermes-inspector-msggen: 1.0.0 javascript-time-ago: ^2.3.7 => 2.3.7 javascript-time-ago-cache: 1.0.0 javascript-time-ago-gradation: 1.0.0 javascript-time-ago-prop-types: 1.0.0 javascript-time-ago-steps: 1.0.0 jest: ^26.6.3 => 26.6.3 metro-react-native-babel-preset: ^0.64.0 => 0.64.0 mlkit: 0.0.1 mobx: ^6.3.2 => 6.3.2 mobx-react: ^7.2.0 => 7.2.0 react: 17.0.1 => 17.0.1 react-chat-elements: ^10.15.0 => 10.15.0 react-native: 0.64.2 => 0.64.2 react-native-camera: git+https://git@github.com/react-native-community/react-native-camera.git => 4.0.0 react-native-device-info: ^8.1.3 => 8.1.3 react-native-elements: ^3.4.2 => 3.4.2 react-native-get-random-values: ^1.7.0 => 1.7.0 react-native-gifted-chat: ^0.16.3 => 0.16.3 react-native-inappbrowser-reborn: ^3.5.1 => 3.5.1 react-native-permissions: ^3.0.5 => 3.0.5 (2.2.2) react-native-push-notification: ^7.4.0 => 7.4.0 react-native-qrcode-scanner: ^1.5.4 => 1.5.4 react-native-safe-area-context: ^3.2.0 => 3.2.0 react-native-svg: ^12.1.1 => 12.1.1 react-native-vector-icons: ^8.1.0 => 8.1.0 (4.6.0) react-test-renderer: 17.0.1 => 17.0.1 src: undefined () tests: 0.0.1 npmGlobalPackages: @aws-amplify/cli: 5.2.0 ios-deploy: 1.11.4 npm: 7.16.0 yarn: 1.22.10 ```

Describe the bug

There it is my amplify stack:

Category Resource name Operation Provider plugin
Function fooEndpoint No Change awscloudformation
Auth cognito10309729 No Change awscloudformation
Api fooapi No Change awscloudformation
Notifications foo No Change
Analytics foo No Change awscloudformation

I try to retrieve the pinpoint app id (associated to Notifications foo) and to use it in the definition of my lambda function fooEndpoint.

When I try do an amplify push when fooEndpoint define a dependency with Notification foo such it is supposed to looking for the pinpoint notification app id, the command raise the following error:

Template error: instance of Fn::GetAtt references undefined resource notificationsfoo
An error occurred during the push operation: Template error: instance of Fn::GetAtt references undefined resource notificationstestdOdfZ

Expected behavior

I expected to be able to retrieve and use the pinpoint notification app id as a parameters of my lambda function

Reproduction steps

Step 1: create an amplify project with notifications and a lambda functions.

(Even if you allow the lambda function to create/delete and so on with notifications services nothing happen)

Step 2:

Based on the documentation https://docs.amplify.aws/cli/usage/customcf#n3-optional-reference-existing-parameters I configure the following files as below:

amplify/backend/backend-config.json :

{
   ...
   "fooEndpoint": {
       ...
       "dependOn": [{
            "category": "notifications",
            "resourceName": "foo",
            "attributes": ["Id"]
        }]
   }
   ...
}

amplify/backend/function/fooEndpoint/parameters.json :

{
  "notificationsFooId": {
    "Fn::GetAtt": [
      "notificationsfoo",
      "Outputs.Id"
    ]
}

and amplify/backend/function/fooEndpoint/fooEndpoint-cloudformation-template.json with notificationsFooId in Parameters section (+ where I need it...)

Step 3: amplify push

Code Snippet

// Put your code below this line.

Log output

``` (base) elix@mbpdejebaptiste test % amplify push βœ” Successfully pulled backend environment dev from the cloud. Current Environment: dev | Category | Resource name | Operation | Provider plugin | | ------------- | --------------- | --------- | ----------------- | | Function | fooEndpoint | Update | awscloudformation | | Auth | cognitoe2a041e8 | No Change | awscloudformation | | Notifications | foo | No Change | | ? Are you sure you want to continue? Yes Installing dependencies from Pipfile.lock (e02f68)... 🐍 β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰β–‰ 0/0 β€” 00:00:00 To activate this project's virtualenv, run pipenv shell. Alternatively, run a command inside the virtualenv with pipenv run. βœ– An error occurred when pushing the resources to the cloud Template error: instance of Fn::GetAtt references undefined resource notificationsfoo An error occurred during the push operation: Template error: instance of Fn::GetAtt references undefined resource notificationsfoo ```

aws-exports.js

No response

Manual configuration

No response

Additional configuration

No response

Mobile Device

No response

Mobile Operating System

No response

Mobile Browser

No response

Mobile Browser Version

No response

Additional information and screenshots

No response

chrisbonifacio commented 3 years ago

Hey @jeanbaptistepriez πŸ‘‹ Thanks for raising this! This seems to be more of a CLI issue so I will transfer it over for you.

josefaidt commented 3 years ago

Hey @jeanbaptistepriez :wave: thanks for raising this! Unfortunately given the current implementation where notifications are created via the AWS SDK and not CloudFormation, this is currently not possible out-of-the-box as we are unable reference the output. For that I will mark this as a feature-request.

As a workaround we can leverage environment variables or secrets with Lambda functions to manually input the notification's ID for consumption inside your Lambda. For reference, the ID's value is captured as an output in the amplify-meta.json file.

jeanbaptistepriez commented 3 years ago

Ok thanks for your answer. I found a workaround:

  1. As you describe I retrieve the pinpoint id in amplify/backend/amplify-meta.json
  2. I add this id (xxxxxxxx for dev environment & yyyyyyyy for prod one) in the amplify/team-provider-info.json file:
    {
    "dev": {
     ...
     "categories": {
        ...
        "function": {
           ...
           "maFunction": {
              "pinpointId": "xxxxxxxx",
              "deploymentBucketName" ...
              ...
    Β Β      }
        }
    Β     }
    },
    "prod": {
     ...
     "categories": {
        ...
        "function": {
           ...
           "maFunction": {
              "pinpointId": "yyyyyyyyyy",
              "deploymentBucketName" ...
              ...
    Β Β      }
        }
    Β     }
    } 
    }
  3. I add this pinpointId as a parameter of the cloudformation template
  4. the amplify push (+ amplify env checkout ...; amplify push) works.

Is it a "not so bad practices" or I risk to get some side effect ?

If it makes sense I suggest to you to enrich the documentation https://docs.amplify.aws/cli/usage/customcf#n3-optional-reference-existing-parameters to describe this ability to pass env specific parameters from outside of cloudformation

josefaidt commented 3 years ago

Hey @jeanbaptistepriez glad you were able to find a workaround.

Is it a "not so bad practices" or I risk to get some side effect ?

This value will be included in your stack's CloudFormation template.

chancyk commented 3 years ago

I have a similar issue where I'm trying to configure a DynamoDB trigger to point to a lambda function in the respective dev and prod Amplify environments. Is this a sanctioned approach, @josefaidt? It seemed to work upon pushing to each of my environments. Is manually modifying team-provider-info.json something the Amplify team expects or might this blow up in the future?

To expand on the solution from @jeanbaptistepriez...

Within my amplify/team-provider-info.json:

  "prod": {
      "....": {},
      "function": {
        "myFunction": {
            "deploymentBucketName": "amplify-...-deployment",
            "s3Key": "amplify-builds/...-build.zip",
            "dynamodbTransitStreamARN": "arn:aws:dynamodb:us-east-1:..."
         }
     }
}

And at the top of my amplify/function/myFunction/myFunction-cloudformation-template.json:

"Parameters": {
  "dynamodbAccountItemStreamARN": {
        "Type": "String"
  }
}
josefaidt commented 3 years ago

Hey @chancyk :wave: from the documentation page for Amplify files and folders it is not recommended to manually edit the team-provider-info.json file. We may see these values are removed after performing additional amplify commands to the resource.

chancyk commented 3 years ago

@josefaidt Thanks! Is there a recommended approach to achieve the same affect? It seems like the parameters.json files may be intended for a similar purpose, but they don't seem environment aware like team-provider-info.json.

In my case I'm trying to attach a Lambda function to a DynamoDB stream, so I need to grab the stream ARN for both dev and prod. This is kind of a band-aid though due my ignorance of how to properly sequence the stream association and DynamoDB table creation to just grab it using CloudFormation in the first place.