Hi! I was trying to use `awsx.apigateway.API` to c...
# aws
l
Hi! I was trying to use
awsx.apigateway.API
to create a PRIVATE APIGW Rest endpoint. I documented it here: https://github.com/pulumi/pulumi-awsx/issues/627 This doesn't work because private APIGWs need a RestApiPolicy.
Copy code
let endpoint = new awsx.apigateway.API(`ea-orders-${stackEnv}`, {
    
    restApiArgs: {
        endpointConfiguration: {
            types: "PRIVATE",
            vpcEndpointIds: [execApiVpcEndpointId],        
        },
    },
    
    routes: [{
        path: "/",
        method: "GET",
        eventHandler: async (event) => {
            // This code runs in an AWS Lambda and will be invoked any time `/` is hit.
            return {
                statusCode: 200,
                body: "hello",
            };
        },
    }],

},
);
Yeah, restApiArgs takes a policy arg but that doesn't work. This is my current hack. I run
pulumi up
twice, yep twice, with the below and it works. The first time partially works but the deploy of the API fails because the policy isn't created before the deploy fires. The second
pulumi up
works because the policy is in place and the deploy can work now. Is this just how the APIGW crosswalk works right now or am I missing something?
Copy code
let endpoint = new awsx.apigateway.API(`ea-orders-${stackEnv}`, {
    
    restApiArgs: {
        endpointConfiguration: {
            types: "PRIVATE",
            vpcEndpointIds: [execApiVpcEndpointId],        
        },
    },
    
    routes: [{
        path: "/",
        method: "GET",
        eventHandler: async (event) => {
            // This code runs in an AWS Lambda and will be invoked any time `/` is hit.
            return {
                statusCode: 200,
                body: "hello",
            };
        },
    }],

},
);

const eaOrdersApiPolicy = new aws.apigateway.RestApiPolicy(`ea-orders-${stackEnv}`, {
    restApiId: endpoint.restAPI.id,
    policy: executeApiPolicy,
});
b
Hi Chad, Rather than specifying a separate
RestApiPolicy
, there is an extra property available in `restApiArgs`called policy. Looking at the docs I think it does the same as the
RestApiPolicy
. It takes a policy as json but you can do something like the following (this is an example policy so obviously swap it for your own one):
Copy code
const policy = aws.iam.getPolicyDocument({
        statements: [{
            actions: ["dynamodb:*"],
            effect: "Allow",
            resources: ["*"]
        }]
});

const api = new awsx.apigateway.API("my-api",{
    routes: [{
        path: "/",
        method: "GET",
        eventHandler: async (event) => {
            // This code runs in an AWS Lambda and will be invoked any time `/` is hit.
            return {
                statusCode: 200,
                body: "hello",
            };
        },
    }],
    restApiArgs: {
        endpointConfiguration: {
            types: "PRIVATE", 
            vpcEndpointIds: [execApiVpcEndpointId]    
        },
        policy: policy.then(policy => policy.json)
    },
});
Try that and let me know if it works
l
Hi @brave-planet-10645 I tried the policy on restApiArgs first. It doesn't work. Now what?
b
Didn't work as in there was an error when updating the stack, or when you tried to call the api endpoint, or something else?
l
The stack wouldn't deploy. "Can't deploy private API Gateway without a RestApiPolicy"
b
ok. So the reason that you can deploy it but only in two steps is because of the way these are linked together.
l
First deploy fails the deploy phase of the APIGW because there is no RestApiPolicy. However the policy finishes deploying during the first deploy. So the second pulumi up succeeds and deploys the APIGW because there is now a policy. Hack-o-rama
b
If you were to use the base aws package and create an apigateway using that rather than the awsx package (which does a lot of magic under the hood) you'll probably fine that you'll be able to do this because you can set up the api gateway first, then set up the restapipolicy and then whatever else needs to happen to link the apigateway to the vpc endpoint
l
I would like to pass the policy in, have the crosswalk deploy it before the APIGW deploy phase, and have it work in one shot.
If I use the base package, I have to create paths, integrations, etc to create the whole API and I get no crosswalk magic doing all of that for me. I think the apigateway wasn't tested with or developed for PRIVATE APIs. And unfortunately, that's what I need
An alternative to passing the policy in would be to pass the APIGW object in to the crosswalk. Which would be a new feature
b
Crosswalk was created to make common IAAC tasks easier. This is one that we haven't been asked for before. I can see you've raised an issue so that'll bring it to the attention of our engineering team.
l
Cool. I'll see if I can or get somebody to do a simple PR to apply the policy that's being passed in.
passed in, in the
restApiArgs
b
that would be awesome
l
Hi @brave-planet-10645 Somebody pushed a PR for this. However, I still have to run
pulumi up
twice on the initial deploy. Subsequent deploys work on a single run, weird.