Hi - I’m trying to create a Cognito User Pool &amp...
# aws
s
Hi - I’m trying to create a Cognito User Pool & Cognito App Client set up which allows both user/pass sign in and SAML. Previously this was achieved using CDK and worked fine and I’m trying to migrate to using Pulumi (we were using SST v2 and are migrating to v3) Creating a standard pool without SAML seems to be ok. however, once I add the creation of a
awsNative.cognito.UserPoolIdentityProvider
I get an odd error on deployment:
Copy code
Error: 13 INTERNAL: Request message serialization failure: b.Va is not a function
       at callErrorFromStatus (/Users/rosscoundon/Documents/GitHub/omw-pso-be/.sst/platform/node_modules/@grpc/grpc-js/src/call.ts:82:17)
       at Object.onReceiveStatus (/Users/rosscoundon/Documents/GitHub/omw-pso-be/.sst/platform/node_modules/@grpc/grpc-js/src/client.ts:360:55)
       at Object.onReceiveStatus (/Users/rosscoundon/Documents/GitHub/omw-pso-be/.sst/platform/node_modules/@grpc/grpc-js/src/client-interceptors.ts:458:34)
       at Object.onReceiveStatus (/Users/rosscoundon/Documents/GitHub/omw-pso-be/.sst/platform/node_modules/@grpc/grpc-js/src/client-interceptors.ts:419:48)
       at /Users/rosscoundon/Documents/GitHub/omw-pso-be/.sst/platform/node_modules/@grpc/grpc-js/src/resolving-call.ts:132:24
       at processTicksAndRejections (node:internal/process/task_queues:77:11)
   for call at
time=2024-12-13T12:04:30.020Z level=INFO msg="INFO unlocking app=omw-pso-be stage=local-dev"
       at ServiceClientImpl.makeUnaryRequest (/Users/rosscoundon/Documents/GitHub/omw-pso-be/.sst/platform/node_modules/@grpc/grpc-js/src/client.ts:325:42)
       at ServiceClientImpl.registerResourceOutputs (/Users/rosscoundon/Documents/GitHub/omw-pso-be/.sst/platform/node_modules/@grpc/grpc-js/src/make-client.ts:189:15)
       at /Users/rosscoundon/Documents/GitHub/omw-pso-be/.sst/platform/node_modules/@pulumi/runtime/resource.ts:1161:33
       at new Promise (<anonymous>)
       at Object.<anonymous> (/Users/rosscoundon/Documents/GitHub/omw-pso-be/.sst/platform/node_modules/@pulumi/runtime/resource.ts:1160:21)
       at Generator.next (<anonymous>)
       at fulfilled (/Users/rosscoundon/Documents/GitHub/omw-pso-be/.sst/platform/node_modules/@pulumi/pulumi/runtime/resource.js:18:58)
       at processTicksAndRejections (node:internal/process/task_queues:95:5) {
     code: 13,
     details: 'Request message serialization failure: b.Va is not a function',
     metadata: Metadata { internalRepr: Map(0) {}, options: {} },
     promise: Promise { <rejected> [Circular *1] }
   }
I’ll share code in a thread
The code looks like this:
Copy code
import * as awsNative from '@pulumi/aws-native';
import { UserPoolClientArgs } from '@pulumi/aws/cognito';

import getRetainOnDelete from '../helpers/utils/getRetainOnDelete';
import { CognitoUserPoolArgs } from '../../.sst/platform/src/components/aws';

const SAML_PROVIDER_NAME = process.env.SAML_PROVIDER_NAME || 'SingleSignOn';

const VALID_EMAIL_DOMAINS = process.env.VALID_EMAIL_DOMAINS;
const DEMO_PERMISSIONS = process.env.DEMO_PERMISSIONS || 'false';

const standardAttributes = [
  'name',
  'family_name',
  'given_name',
  'middle_name',
  'nickname',
  'preferred_username',
  'profile',
  'picture',
  'website',
  'gender',
  'birthdate',
  'zoneinfo',
  'locale',
  'updated_at',
  'address',
  'email',
  'phone_number',
  'sub',
];

const retainOnDelete = getRetainOnDelete();

const clientReadAttributes = structuredClone(standardAttributes);

const cognitoUserPoolArgs: CognitoUserPoolArgs = {
  transform: {
    userPool: (args, opts) => {
      opts.retainOnDelete = retainOnDelete;
      args.aliasAttributes = ['email'];
      args.autoVerifiedAttributes = ['email'];
      // Missing selfSignUpEnabled: true,
      args.passwordPolicy = {
        minimumLength: 8,
        requireLowercase: true,
        requireNumbers: true,
        requireSymbols: false,
        requireUppercase: true,
      };
      args.accountRecoverySetting = {
        recoveryMechanisms: [
          {
            name: 'verifiedEmail',
            priority: 1,
          },
        ],
      };
      args.emailVerificationSubject = 'Your Appointment Assistant Portal verification code';
      args.emailVerificationMessage =
        'Thanks for signing up to the Appointment Assistant Portal! Your verification code is {####}';
      // missing emailStyle: cognito.VerificationEmailStyle.CODE,
    },
  },
};

const cognitoUserPool = new aws.cognito.UserPool(`${$app.stage}-cognitoUserPool`, cognitoUserPoolArgs);

const samlProviderArgs: awsNative.cognito.UserPoolIdentityProviderArgs = {
  providerType: 'SAML',
  providerName: SAML_PROVIDER_NAME,
  userPoolId: cognitoUserPool.id,
  attributeMapping: {
    email: '<http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress>',
  },
  providerDetails: {
    IDPInit: 'true',
    IDPSignout: 'true',
    EncryptedResponses: 'true',
    MetadataURL: process.env.SAML_METADATA_URL,
    RequestSigningAlgorithm: 'rsa-sha256',
  },
};

console.log('about to create samlProvider');
const samlProvider = new awsNative.cognito.UserPoolIdentityProvider(`${$app.stage}-samlIdentityProvider`, samlProviderArgs);
console.log('created samlProvider');
let userPoolClientArgs: UserPoolClientArgs = {
  userPoolId: cognitoUserPool.id,
  name: `${$app.stage}-cognitoUserPoolClient`,
  generateSecret: false,
  readAttributes: clientReadAttributes,
  supportedIdentityProviders: ['COGNITO'],
  explicitAuthFlows: ['ALLOW_USER_SRP_AUTH', 'ALLOW_REFRESH_TOKEN_AUTH'],
};

if (process.env.SAML_METADATA_URL) {
  if (!process.env.PORTAL_URL) {
    throw new Error('PORTAL_URL environment variable is required');
  }

  userPoolClientArgs = {
    ...userPoolClientArgs,
    preventUserExistenceErrors: 'ENABLED',
    allowedOauthFlows: ['code'],
    allowedOauthScopes: ['email', 'openid', 'profile', 'aws.cognito.signin.user.admin'],
    allowedOauthFlowsUserPoolClient: true,
    defaultRedirectUri: `${process.env.PORTAL_URL}/dashboard`,
    callbackUrls: [
      process.env.PORTAL_URL,
      `${process.env.PORTAL_URL}/dashboard`,
      `${process.env.PORTAL_URL}/sso`,
      `${process.env.PORTAL_URL}/signin`,
    ],
    supportedIdentityProviders: [SAML_PROVIDER_NAME, 'COGNITO'],
  };
}

console.log('about to create cognitoUserPoolClient');
const cognitoUserPoolClient = new aws.cognito.UserPoolClient(`${$app.stage}-cognitoUserPoolClient`, userPoolClientArgs);
console.log('created cognitoUserPoolClient');

export { cognitoUserPool, cognitoUserPoolClient };
Any thoughts on what’s going on here? The error message is rather opaque. Any guidance very gratefully received as I’m very stuck! Thanks
After battling with this for a while, I switched to
@pulumi/aws
from
@pulumi/aws-native
for the Identity Provider and removed
IDPInit: 'true'
and it can deploy correctly.
g
I wanted to add.. rule no.1 … avoid
aws-native
as much as you can.
s
I see, thanks for the advice, I’m very new to this ecosystem so shared and shown battle scars are very welcome
g
another good thing to know is that 90% of pulumi providers are ported from terraform so it is often useful to search the terraform problem instead of pulumi
s
I see, good advice. Thank you
q
This might be an issue with incompatible protobuf versions in your
node_modules
. See https://github.com/pulumi/pulumi/issues/17421 Try nuking your
node_modules
and lock file, I've seen that help in those cases