Created
August 8, 2019 19:03
-
-
Save ericdmoore/42b05b4f1f15fbb52c1e5c63f15cd0be to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* To get this list go to:https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ask-skill.html | |
* and run this in the console. | |
*/ | |
/* | |
;(async () => { | |
const sleep = N => { | |
return new Promise(resolve => { | |
setTimeout(() => { | |
resolve() | |
}, N) | |
}) | |
} | |
const init = Array.from( | |
document.querySelectorAll( | |
'#toc > ul > li.awstoc.opened > ul > li.awstoc.opened > ul > li.awstoc' | |
) | |
) | |
init.forEach(el => el.click()) | |
await sleep(500) | |
const opened = Array.from( | |
document.querySelectorAll( | |
'#toc > ul > li.awstoc.opened > ul > li.awstoc.opened > ul > li.awstoc' | |
) | |
) | |
const AWS_LISTED_TYPES = opened.reduce((p, el) => { | |
// interate through the middle N | |
const types = Array.from(el.childNodes[1].childNodes).reduce((p2, c2) => { | |
return c2.childNodes.length > 0 ? [...p2, c2.childNodes[0].innerText] : [...p2] | |
}, []) | |
// close it up before returning | |
if (el.classList.contains('opened')) { | |
el.click() | |
} | |
return [...p, ...types] | |
}, []) | |
console.log(AWS_LISTED_TYPES.map(e => `'${e}'`).join(', ')) | |
})() | |
*/ | |
// precalcualted list from prior run | |
// runOn: 2019-08-08 10:53am CST | |
export const AWS_LISTED_TYPES = [ | |
'Alexa::ASK::Skill', | |
'AWS::AmazonMQ::Broker', | |
'AWS::AmazonMQ::Configuration', | |
'AWS::AmazonMQ::ConfigurationAssociation', | |
'AWS::Amplify::App', | |
'AWS::Amplify::Branch', | |
'AWS::Amplify::Domain', | |
'AWS::ApiGateway::Account', | |
'AWS::ApiGateway::ApiKey', | |
'AWS::ApiGateway::Authorizer', | |
'AWS::ApiGateway::BasePathMapping', | |
'AWS::ApiGateway::ClientCertificate', | |
'AWS::ApiGateway::Deployment', | |
'AWS::ApiGateway::DocumentationPart', | |
'AWS::ApiGateway::DocumentationVersion', | |
'AWS::ApiGateway::DomainName', | |
'AWS::ApiGateway::GatewayResponse', | |
'AWS::ApiGateway::Method', | |
'AWS::ApiGateway::Model', | |
'AWS::ApiGateway::RequestValidator', | |
'AWS::ApiGateway::Resource', | |
'AWS::ApiGateway::RestApi', | |
'AWS::ApiGateway::Stage', | |
'AWS::ApiGateway::UsagePlan', | |
'AWS::ApiGateway::UsagePlanKey', | |
'AWS::ApiGateway::VpcLink', | |
'AWS::ApiGatewayV2::Api', | |
'AWS::ApiGatewayV2::ApiMapping', | |
'AWS::ApiGatewayV2::Authorizer', | |
'AWS::ApiGatewayV2::Deployment', | |
'AWS::ApiGatewayV2::DomainName', | |
'AWS::ApiGatewayV2::Integration', | |
'AWS::ApiGatewayV2::IntegrationResponse', | |
'AWS::ApiGatewayV2::Model', | |
'AWS::ApiGatewayV2::Route', | |
'AWS::ApiGatewayV2::RouteResponse', | |
'AWS::ApiGatewayV2::Stage', | |
'AWS::ApplicationAutoScaling::ScalableTarget', | |
'AWS::ApplicationAutoScaling::ScalingPolicy', | |
'AWS::AppMesh::Mesh', | |
'AWS::AppMesh::Route', | |
'AWS::AppMesh::VirtualNode', | |
'AWS::AppMesh::VirtualRouter', | |
'AWS::AppMesh::VirtualService', | |
'AWS::AppStream::DirectoryConfig', | |
'AWS::AppStream::Fleet', | |
'AWS::AppStream::ImageBuilder', | |
'AWS::AppStream::Stack', | |
'AWS::AppStream::StackFleetAssociation', | |
'AWS::AppStream::StackUserAssociation', | |
'AWS::AppStream::User', | |
'AWS::AppSync::ApiKey', | |
'AWS::AppSync::DataSource', | |
'AWS::AppSync::FunctionConfiguration', | |
'AWS::AppSync::GraphQLApi', | |
'AWS::AppSync::GraphQLSchema', | |
'AWS::AppSync::Resolver', | |
'AWS::Athena::NamedQuery', | |
'AWS::AutoScalingPlans::ScalingPlan', | |
'AWS::AutoScaling::AutoScalingGroup', | |
'AWS::AutoScaling::LaunchConfiguration', | |
'AWS::AutoScaling::LifecycleHook', | |
'AWS::AutoScaling::ScalingPolicy', | |
'AWS::AutoScaling::ScheduledAction', | |
'AWS::Backup::BackupPlan', | |
'AWS::Backup::BackupSelection', | |
'AWS::Backup::BackupVault', | |
'AWS::Batch::ComputeEnvironment', | |
'AWS::Batch::JobDefinition', | |
'AWS::Batch::JobQueue', | |
'AWS::Budgets::Budget', | |
'AWS::CertificateManager::Certificate', | |
'AWS::Cloud9::EnvironmentEC2', | |
'AWS::CloudFormation::CustomResource', | |
'AWS::CloudFormation::Macro', | |
'AWS::CloudFormation::Stack', | |
'AWS::CloudFormation::WaitCondition', | |
'AWS::CloudFormation::WaitConditionHandle', | |
'AWS::CloudFront::CloudFrontOriginAccessIdentity', | |
'AWS::CloudFront::Distribution', | |
'AWS::CloudFront::StreamingDistribution', | |
'AWS::ServiceDiscovery::HttpNamespace', | |
'AWS::ServiceDiscovery::Instance', | |
'AWS::ServiceDiscovery::PrivateDnsNamespace', | |
'AWS::ServiceDiscovery::PublicDnsNamespace', | |
'AWS::ServiceDiscovery::Service', | |
'AWS::CloudTrail::Trail', | |
'AWS::CloudWatch::Alarm', | |
'AWS::CloudWatch::AnomalyDetector', | |
'AWS::CloudWatch::Dashboard', | |
'AWS::Logs::Destination', | |
'AWS::Logs::LogGroup', | |
'AWS::Logs::LogStream', | |
'AWS::Logs::MetricFilter', | |
'AWS::Logs::SubscriptionFilter', | |
'AWS::Events::EventBusPolicy', | |
'AWS::Events::Rule', | |
'AWS::CodeBuild::Project', | |
'AWS::CodeCommit::Repository', | |
'AWS::CodeDeploy::Application', | |
'AWS::CodeDeploy::DeploymentConfig', | |
'AWS::CodeDeploy::DeploymentGroup', | |
'AWS::CodePipeline::CustomActionType', | |
'AWS::CodePipeline::Pipeline', | |
'AWS::CodePipeline::Webhook', | |
'AWS::CodeStar::GitHubRepository', | |
'AWS::Cognito::IdentityPool', | |
'AWS::Cognito::IdentityPoolRoleAttachment', | |
'AWS::Cognito::UserPool', | |
'AWS::Cognito::UserPoolClient', | |
'AWS::Cognito::UserPoolGroup', | |
'AWS::Cognito::UserPoolUser', | |
'AWS::Cognito::UserPoolUserToGroupAttachment', | |
'AWS::Config::AggregationAuthorization', | |
'AWS::Config::ConfigRule', | |
'AWS::Config::ConfigurationAggregator', | |
'AWS::Config::ConfigurationRecorder', | |
'AWS::Config::DeliveryChannel', | |
'AWS::Config::RemediationConfiguration', | |
'AWS::DataPipeline::Pipeline', | |
'AWS::DAX::Cluster', | |
'AWS::DAX::ParameterGroup', | |
'AWS::DAX::SubnetGroup', | |
'AWS::DirectoryService::MicrosoftAD', | |
'AWS::DirectoryService::SimpleAD', | |
'AWS::DLM::LifecyclePolicy', | |
'AWS::DMS::Certificate', | |
'AWS::DMS::Endpoint', | |
'AWS::DMS::EventSubscription', | |
'AWS::DMS::ReplicationInstance', | |
'AWS::DMS::ReplicationSubnetGroup', | |
'AWS::DMS::ReplicationTask', | |
'AWS::DocDB::DBCluster', | |
'AWS::DocDB::DBClusterParameterGroup', | |
'AWS::DocDB::DBInstance', | |
'AWS::DocDB::DBSubnetGroup', | |
'AWS::DynamoDB::Table', | |
'AWS::EC2::CapacityReservation', | |
'AWS::EC2::ClientVpnAuthorizationRule', | |
'AWS::EC2::ClientVpnEndpoint', | |
'AWS::EC2::ClientVpnRoute', | |
'AWS::EC2::ClientVpnTargetNetworkAssociation', | |
'AWS::EC2::CustomerGateway', | |
'AWS::EC2::DHCPOptions', | |
'AWS::EC2::EC2Fleet', | |
'AWS::EC2::EgressOnlyInternetGateway', | |
'AWS::EC2::EIP', | |
'AWS::EC2::EIPAssociation', | |
'AWS::EC2::FlowLog', | |
'AWS::EC2::Host', | |
'AWS::EC2::Instance', | |
'AWS::EC2::InternetGateway', | |
'AWS::EC2::LaunchTemplate', | |
'AWS::EC2::NatGateway', | |
'AWS::EC2::NetworkAcl', | |
'AWS::EC2::NetworkAclEntry', | |
'AWS::EC2::NetworkInterface', | |
'AWS::EC2::NetworkInterfaceAttachment', | |
'AWS::EC2::NetworkInterfacePermission', | |
'AWS::EC2::PlacementGroup', | |
'AWS::EC2::Route', | |
'AWS::EC2::RouteTable', | |
'AWS::EC2::SecurityGroup', | |
'AWS::EC2::SecurityGroupEgress', | |
'AWS::EC2::SecurityGroupIngress', | |
'AWS::EC2::SpotFleet', | |
'AWS::EC2::Subnet', | |
'AWS::EC2::SubnetCidrBlock', | |
'AWS::EC2::SubnetNetworkAclAssociation', | |
'AWS::EC2::SubnetRouteTableAssociation', | |
'AWS::EC2::TransitGateway', | |
'AWS::EC2::TransitGatewayAttachment', | |
'AWS::EC2::TransitGatewayRoute', | |
'AWS::EC2::TransitGatewayRouteTable', | |
'AWS::EC2::TransitGatewayRouteTableAssociation', | |
'AWS::EC2::TransitGatewayRouteTablePropagation', | |
'AWS::EC2::Volume', | |
'AWS::EC2::VolumeAttachment', | |
'AWS::EC2::VPC', | |
'AWS::EC2::VPCCidrBlock', | |
'AWS::EC2::VPCDHCPOptionsAssociation', | |
'AWS::EC2::VPCEndpoint', | |
'AWS::EC2::VPCEndpointConnectionNotification', | |
'AWS::EC2::VPCEndpointService', | |
'AWS::EC2::VPCEndpointServicePermissions', | |
'AWS::EC2::VPCGatewayAttachment', | |
'AWS::EC2::VPCPeeringConnection', | |
'AWS::EC2::VPNConnection', | |
'AWS::EC2::VPNConnectionRoute', | |
'AWS::EC2::VPNGateway', | |
'AWS::EC2::VPNGatewayRoutePropagation', | |
'AWS::ECR::Repository', | |
'AWS::ECS::Cluster', | |
'AWS::ECS::Service', | |
'AWS::ECS::TaskDefinition', | |
'AWS::EFS::FileSystem', | |
'AWS::EFS::MountTarget', | |
'AWS::EKS::Cluster', | |
'AWS::ElastiCache::CacheCluster', | |
'AWS::ElastiCache::ParameterGroup', | |
'AWS::ElastiCache::ReplicationGroup', | |
'AWS::ElastiCache::SecurityGroup', | |
'AWS::ElastiCache::SecurityGroupIngress', | |
'AWS::ElastiCache::SubnetGroup', | |
'AWS::Elasticsearch::Domain', | |
'AWS::ElasticBeanstalk::Application', | |
'AWS::ElasticBeanstalk::ApplicationVersion', | |
'AWS::ElasticBeanstalk::ConfigurationTemplate', | |
'AWS::ElasticBeanstalk::Environment', | |
'AWS::ElasticLoadBalancing::LoadBalancer', | |
'AWS::ElasticLoadBalancingV2::Listener', | |
'AWS::ElasticLoadBalancingV2::ListenerCertificate', | |
'AWS::ElasticLoadBalancingV2::ListenerRule', | |
'AWS::ElasticLoadBalancingV2::LoadBalancer', | |
'AWS::ElasticLoadBalancingV2::TargetGroup', | |
'AWS::EMR::Cluster', | |
'AWS::EMR::InstanceFleetConfig', | |
'AWS::EMR::InstanceGroupConfig', | |
'AWS::EMR::SecurityConfiguration', | |
'AWS::EMR::Step', | |
'AWS::FSx::FileSystem', | |
'AWS::GameLift::Alias', | |
'AWS::GameLift::Build', | |
'AWS::GameLift::Fleet', | |
'AWS::Glue::Classifier', | |
'AWS::Glue::Connection', | |
'AWS::Glue::Crawler', | |
'AWS::Glue::Database', | |
'AWS::Glue::DataCatalogEncryptionSettings', | |
'AWS::Glue::DevEndpoint', | |
'AWS::Glue::Job', | |
'AWS::Glue::Partition', | |
'AWS::Glue::SecurityConfiguration', | |
'AWS::Glue::Table', | |
'AWS::Glue::Trigger', | |
'AWS::GuardDuty::Detector', | |
'AWS::GuardDuty::Filter', | |
'AWS::GuardDuty::IPSet', | |
'AWS::GuardDuty::Master', | |
'AWS::GuardDuty::Member', | |
'AWS::GuardDuty::ThreatIntelSet', | |
'AWS::IAM::AccessKey', | |
'AWS::IAM::Group', | |
'AWS::IAM::InstanceProfile', | |
'AWS::IAM::ManagedPolicy', | |
'AWS::IAM::Policy', | |
'AWS::IAM::Role', | |
'AWS::IAM::ServiceLinkedRole', | |
'AWS::IAM::User', | |
'AWS::IAM::UserToGroupAddition', | |
'AWS::Inspector::AssessmentTarget', | |
'AWS::Inspector::AssessmentTemplate', | |
'AWS::Inspector::ResourceGroup', | |
'AWS::IoT::Certificate', | |
'AWS::IoT::Policy', | |
'AWS::IoT::PolicyPrincipalAttachment', | |
'AWS::IoT::Thing', | |
'AWS::IoT::ThingPrincipalAttachment', | |
'AWS::IoT::TopicRule', | |
'AWS::IoT1Click::Device', | |
'AWS::IoT1Click::Placement', | |
'AWS::IoT1Click::Project', | |
'AWS::IoTAnalytics::Channel', | |
'AWS::IoTAnalytics::Dataset', | |
'AWS::IoTAnalytics::Datastore', | |
'AWS::IoTAnalytics::Pipeline', | |
'AWS::IoTEvents::DetectorModel', | |
'AWS::IoTEvents::Input', | |
'AWS::Greengrass::ConnectorDefinition', | |
'AWS::Greengrass::ConnectorDefinitionVersion', | |
'AWS::Greengrass::CoreDefinition', | |
'AWS::Greengrass::CoreDefinitionVersion', | |
'AWS::Greengrass::DeviceDefinition', | |
'AWS::Greengrass::DeviceDefinitionVersion', | |
'AWS::Greengrass::FunctionDefinition', | |
'AWS::Greengrass::FunctionDefinitionVersion', | |
'AWS::Greengrass::Group', | |
'AWS::Greengrass::GroupVersion', | |
'AWS::Greengrass::LoggerDefinition', | |
'AWS::Greengrass::LoggerDefinitionVersion', | |
'AWS::Greengrass::ResourceDefinition', | |
'AWS::Greengrass::ResourceDefinitionVersion', | |
'AWS::Greengrass::SubscriptionDefinition', | |
'AWS::Greengrass::SubscriptionDefinitionVersion', | |
'AWS::IoTThingsGraph::FlowTemplate', | |
'AWS::Kinesis::Stream', | |
'AWS::Kinesis::StreamConsumer', | |
'AWS::KinesisAnalytics::Application', | |
'AWS::KinesisAnalytics::ApplicationOutput', | |
'AWS::KinesisAnalytics::ApplicationReferenceDataSource', | |
'AWS::KinesisAnalyticsV2::Application', | |
'AWS::KinesisAnalyticsV2::ApplicationCloudWatchLoggingOption', | |
'AWS::KinesisAnalyticsV2::ApplicationOutput', | |
'AWS::KinesisAnalyticsV2::ApplicationReferenceDataSource', | |
'AWS::KinesisFirehose::DeliveryStream', | |
'AWS::KMS::Alias', | |
'AWS::KMS::Key', | |
'AWS::Lambda::Alias', | |
'AWS::Lambda::EventSourceMapping', | |
'AWS::Lambda::Function', | |
'AWS::Lambda::LayerVersion', | |
'AWS::Lambda::LayerVersionPermission', | |
'AWS::Lambda::Permission', | |
'AWS::Lambda::Version', | |
'AWS::MediaLive::Channel', | |
'AWS::MediaLive::Input', | |
'AWS::MediaLive::InputSecurityGroup', | |
'AWS::MediaStore::Container', | |
'AWS::MSK::Cluster', | |
'AWS::Neptune::DBCluster', | |
'AWS::Neptune::DBClusterParameterGroup', | |
'AWS::Neptune::DBInstance', | |
'AWS::Neptune::DBParameterGroup', | |
'AWS::Neptune::DBSubnetGroup', | |
'AWS::OpsWorks::App', | |
'AWS::OpsWorks::ElasticLoadBalancerAttachment', | |
'AWS::OpsWorks::Instance', | |
'AWS::OpsWorks::Layer', | |
'AWS::OpsWorks::Stack', | |
'AWS::OpsWorks::UserProfile', | |
'AWS::OpsWorks::Volume', | |
'AWS::OpsWorksCM::Server', | |
'AWS::Pinpoint::ADMChannel', | |
'AWS::Pinpoint::APNSChannel', | |
'AWS::Pinpoint::APNSSandboxChannel', | |
'AWS::Pinpoint::APNSVoipChannel', | |
'AWS::Pinpoint::APNSVoipSandboxChannel', | |
'AWS::Pinpoint::App', | |
'AWS::Pinpoint::ApplicationSettings', | |
'AWS::Pinpoint::BaiduChannel', | |
'AWS::Pinpoint::Campaign', | |
'AWS::Pinpoint::EmailChannel', | |
'AWS::Pinpoint::EventStream', | |
'AWS::Pinpoint::GCMChannel', | |
'AWS::Pinpoint::Segment', | |
'AWS::Pinpoint::SMSChannel', | |
'AWS::Pinpoint::VoiceChannel', | |
'AWS::PinpointEmail::ConfigurationSet', | |
'AWS::PinpointEmail::ConfigurationSetEventDestination', | |
'AWS::PinpointEmail::DedicatedIpPool', | |
'AWS::PinpointEmail::Identity', | |
'AWS::RAM::ResourceShare', | |
'AWS::RDS::DBCluster', | |
'AWS::RDS::DBClusterParameterGroup', | |
'AWS::RDS::DBInstance', | |
'AWS::RDS::DBParameterGroup', | |
'AWS::RDS::DBSecurityGroup', | |
'AWS::RDS::DBSecurityGroupIngress', | |
'AWS::RDS::DBSubnetGroup', | |
'AWS::RDS::EventSubscription', | |
'AWS::RDS::OptionGroup', | |
'AWS::Redshift::Cluster', | |
'AWS::Redshift::ClusterParameterGroup', | |
'AWS::Redshift::ClusterSecurityGroup', | |
'AWS::Redshift::ClusterSecurityGroupIngress', | |
'AWS::Redshift::ClusterSubnetGroup', | |
'AWS::RoboMaker::Fleet', | |
'AWS::RoboMaker::Robot', | |
'AWS::RoboMaker::RobotApplication', | |
'AWS::RoboMaker::RobotApplicationVersion', | |
'AWS::RoboMaker::SimulationApplication', | |
'AWS::RoboMaker::SimulationApplicationVersion', | |
'AWS::Route53::HealthCheck', | |
'AWS::Route53::HostedZone', | |
'AWS::Route53::RecordSet', | |
'AWS::Route53::RecordSetGroup', | |
'AWS::Route53Resolver::ResolverEndpoint', | |
'AWS::Route53Resolver::ResolverRule', | |
'AWS::Route53Resolver::ResolverRuleAssociation', | |
'AWS::S3::Bucket', | |
'AWS::S3::BucketPolicy', | |
'AWS::SageMaker::CodeRepository', | |
'AWS::SageMaker::Endpoint', | |
'AWS::SageMaker::EndpointConfig', | |
'AWS::SageMaker::Model', | |
'AWS::SageMaker::NotebookInstance', | |
'AWS::SageMaker::NotebookInstanceLifecycleConfig', | |
'AWS::SecretsManager::ResourcePolicy', | |
'AWS::SecretsManager::RotationSchedule', | |
'AWS::SecretsManager::Secret', | |
'AWS::SecretsManager::SecretTargetAttachment', | |
'AWS::ServiceCatalog::AcceptedPortfolioShare', | |
'AWS::ServiceCatalog::CloudFormationProduct', | |
'AWS::ServiceCatalog::CloudFormationProvisionedProduct', | |
'AWS::ServiceCatalog::LaunchNotificationConstraint', | |
'AWS::ServiceCatalog::LaunchRoleConstraint', | |
'AWS::ServiceCatalog::LaunchTemplateConstraint', | |
'AWS::ServiceCatalog::Portfolio', | |
'AWS::ServiceCatalog::PortfolioPrincipalAssociation', | |
'AWS::ServiceCatalog::PortfolioProductAssociation', | |
'AWS::ServiceCatalog::PortfolioShare', | |
'AWS::ServiceCatalog::ResourceUpdateConstraint', | |
'AWS::ServiceCatalog::StackSetConstraint', | |
'AWS::ServiceCatalog::TagOption', | |
'AWS::ServiceCatalog::TagOptionAssociation', | |
'AWS::SecurityHub::Hub', | |
'AWS::SES::ConfigurationSet', | |
'AWS::SES::ConfigurationSetEventDestination', | |
'AWS::SES::ReceiptFilter', | |
'AWS::SES::ReceiptRule', | |
'AWS::SES::ReceiptRuleSet', | |
'AWS::SES::Template', | |
'AWS::SDB::Domain', | |
'AWS::SNS::Subscription', | |
'AWS::SNS::Topic', | |
'AWS::SNS::TopicPolicy', | |
'AWS::SQS::Queue', | |
'AWS::SQS::QueuePolicy', | |
'AWS::StepFunctions::Activity', | |
'AWS::StepFunctions::StateMachine', | |
'AWS::SSM::Association', | |
'AWS::SSM::Document', | |
'AWS::SSM::MaintenanceWindow', | |
'AWS::SSM::MaintenanceWindowTarget', | |
'AWS::SSM::MaintenanceWindowTask', | |
'AWS::SSM::Parameter', | |
'AWS::SSM::PatchBaseline', | |
'AWS::SSM::ResourceDataSync', | |
'AWS::Transfer::Server', | |
'AWS::Transfer::User', | |
'AWS::WAF::ByteMatchSet', | |
'AWS::WAF::IPSet', | |
'AWS::WAF::Rule', | |
'AWS::WAF::SizeConstraintSet', | |
'AWS::WAF::SqlInjectionMatchSet', | |
'AWS::WAF::WebACL', | |
'AWS::WAF::XssMatchSet', | |
'AWS::WAFRegional::ByteMatchSet', | |
'AWS::WAFRegional::GeoMatchSet', | |
'AWS::WAFRegional::IPSet', | |
'AWS::WAFRegional::RateBasedRule', | |
'AWS::WAFRegional::RegexPatternSet', | |
'AWS::WAFRegional::Rule', | |
'AWS::WAFRegional::SizeConstraintSet', | |
'AWS::WAFRegional::SqlInjectionMatchSet', | |
'AWS::WAFRegional::WebACL', | |
'AWS::WAFRegional::WebACLAssociation', | |
'AWS::WAFRegional::XssMatchSet', | |
'AWS::WorkSpaces::Workspace' | |
] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// npx ts-node _scratch.ts | |
import fetch from 'node-fetch' | |
import { AWS_LISTED_TYPES } from './AWS_ListedTypesInTheDocs' | |
// import path from 'path' | |
// import fs from 'fs' | |
const zip = <T, U>(A: T[], B: U[]) => { | |
let ret: [T, U][] | |
if (A.length !== B.length) { | |
throw new Error('not same length') | |
} | |
if (A.length < B.length) { | |
ret = A.map((v, i) => { | |
return [A[i], B[i]] | |
}) | |
} else { | |
ret = B.map((v, i) => { | |
return [A[i], B[i]] | |
}) | |
} | |
return ret | |
} | |
const setDiff = (A: Set<string>, B: Set<string>): string[] => { | |
return Array.from(A.keys()).reduce( | |
(p, v) => { | |
return B.has(v) ? [...p] : [v, ...p] | |
}, | |
[] as string[] | |
) | |
} | |
const setInterSection = (A: Set<string>, B: Set<string>): string[] => { | |
return Array.from(A.keys()).reduce( | |
(p, v) => { | |
return B.has(v) ? [...p, v] : [...p] | |
}, | |
[] as string[] | |
) | |
} | |
;(async () => { | |
// setup the batch of network calls. | |
/* | |
on url: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-resource-specification.html | |
run this in console to update the URLs: | |
```js | |
const listofCDNEndpoints = Array.from(document.querySelectorAll('#w222ab1c21c14c13 > tbody > tr > td:nth-child(3) > p > a')) | |
listofCDNEndpoints.forEach(e=> console.log(e.href, '//' ,e.parentElement.parentElement.parentElement.childNodes[3].innerText)) | |
``` | |
*/ | |
const cloudfrontCDNs = [ | |
'd2senuesg1djtx', // ap-south-1 | |
'd2zq80gdmjim8k', // ap-northeast-3 | |
'd1ane3fvebulky', // ap-northeast-2 | |
'doigdx0kgq9el', // ap-southeast-1 | |
'd2stg8d246z9di', // ap-southeast-2 | |
'd33vqc0rt9ld30', // ap-northeast-1 | |
'd2s8ygphhesbe7', // ca-central-1 | |
'd1mta8qj7i28i2', // eu-central-1 | |
'd3teyb21fexa9r', // eu-west-1 | |
'd1742qcu2c1ncx', // eu-west-2 | |
'd2d0mfegowb3wk', // eu-west-3 | |
'diy8iv58sj6ba', // eu-north-1 | |
'd3c9jyj3w509b0', // sa-east-1 | |
'd1uauaxba7bl26', // us-east-1 | |
'dnwj8swjjbsbt', // us-east-2 | |
'd68hl49wbnanq', // us-west-1 | |
'd201a2mn26r7lk' // us-west-2 | |
] | |
const _path = 'latest/gzip/CloudFormationResourceSpecification.json' | |
const results = await Promise.all( | |
cloudfrontCDNs.map(subdomain => fetch(`https://${subdomain}.cloudfront.net/${_path}`)) | |
) | |
// with responses availble, drop them on to the fs via createWriteStream | |
const zipped = zip(cloudfrontCDNs, results) | |
// Section Deals with making a cache on the fs | |
// | |
/* | |
const fileDrops = zipped.map(async ([sub, r]) => { | |
const res = await r.json() | |
const _writePath = path.resolve(process.cwd(), `${sub}.json`) | |
const f = fs.createWriteStream(_writePath) | |
f.write(Buffer.from(JSON.stringify(res, null, 4))) | |
f.close() | |
}) | |
await Promise.all(fileDrops) | |
const jq_filter = | |
'[ .PropertyTypes | to_entries[] ] | map( select( .value | has( "Properties" )!=true ))' | |
// look throutgh responses on fs | |
fs.readdir('.', async (err, files) => { | |
const importedResponses = await Promise.all( | |
files.filter(f => f.endsWith('.json')).map(f => import(path.resolve(process.cwd(), `${f}`))) | |
) | |
console.log({ importedResponses }) | |
}) | |
*/ | |
const d1 = await Promise.all(zipped.map(async ([sub, Resp]) => [sub, await Resp.json()])) | |
const d2 = d1.reduce((prior, [sub, data]) => ({ ...prior, [`${sub}`]: data }), {}) as { | |
[s: string]: { | |
PropertyTypes: object | |
ResourceTypes: object | |
ResourceSpecificationVersion: '5.0.0' | |
} | |
} | |
// console.log({ d2 }) | |
/** | |
* ADD YOUR VALIDATION RULES, ADD THEM HERE | |
* REALLY WhAT EVER YOU CAN THINK OF | |
*/ | |
// Setup Validation Rules | |
const PropertyRules = [ | |
(name: string, data: any, propMap: any, resMap: any) => { | |
// Every Property Entry should have a `Properties` entry | |
return 'Properties' in data ? true : `${name} : Missing Properties` | |
}, | |
(name: string, data: any, propMap: any, resMap: any) => { | |
// Every Property Entry should have a `Documentation` entry | |
return 'Documentation' in data ? true : `${name} : Missing Documentation` | |
} | |
] as validationFn[] | |
const ResourceRules = [ | |
(name: string, data: any, propMap: any, resMap: any) => { | |
return 'Properties' in data ? true : `${name} : Missing Properties` | |
}, | |
(name: string, data: any, propMap: any, resMap: any) => { | |
return 'Documentation' in data ? true : `${name} : Missing Documentation` | |
}, | |
(name: string, data: any, propMap: any, resMap: any) => { | |
return AWS_LISTED_TYPES.includes(name) ? true : `Listed but not Covered w/ Sepcfile : ${name}` | |
} | |
] as validationFn[] | |
// perhaps grow this into more a structure output as oppose to a string output | |
interface validationFn { | |
(name: string, data: any, propMap: any, resMap: any): boolean | string | |
} | |
// Drive through the data | |
Object.entries(d2).map(([sub, urlRespData]) => { | |
console.log( | |
{ v: urlRespData.ResourceSpecificationVersion }, | |
`https://${sub}.cloudfront.net/${_path}` | |
) | |
const rValidations = Object.entries(urlRespData.ResourceTypes).map(([name, rData]) => { | |
const errList = ResourceRules.reduce( | |
(p, f) => { | |
const r = f(name, rData, urlRespData.ResourceTypes, urlRespData.PropertyTypes) | |
return typeof r === 'string' ? [...p, r] : [...p] | |
}, | |
[] as string[] | |
) | |
return errList.length > 0 ? errList : true | |
}) | |
const pValidations = Object.entries(urlRespData.PropertyTypes).map(([name, pData]) => { | |
const errList = PropertyRules.reduce( | |
(p, f) => { | |
const r = f(name, pData, urlRespData.ResourceTypes, urlRespData.PropertyTypes) | |
return typeof r === 'string' ? [...p, r] : [...p] | |
}, | |
[] as string[] | |
) | |
return errList.length > 0 ? errList : true | |
}) | |
const listedNotCovered = ((subdomain, data) => { | |
const listed = new Set(AWS_LISTED_TYPES) | |
const covered = new Set(Object.keys(data.ResourceTypes)) | |
return setDiff(listed, covered) | |
})(sub, urlRespData) | |
console.log({ pValidations: pValidations.filter(e => typeof e !== 'boolean') }) | |
console.log({ rValidations: rValidations.filter(e => typeof e !== 'boolean') }) | |
console.log({ listedNotCovered }) | |
console.log('\n\n') | |
// console.log({ resourceErrors: rValidations.filter(v => typeof v === 'string') }) | |
// console.log({ propertyErrors: pValidations.filter(v => typeof v === 'string') }) | |
}) | |
})() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
TLDR: AWS Data about Cloudformation types is dirty - and requiring data janitor work. Chose us-west-2 to minimize your work.
Conclusion
Should you care to process the
Cloudformation Specfile
published in the documentation of AWS Cloudformation - know a few things:All software has bugs; All Data is dirty; and All Absolute Statements should be examine carefully.
I want to start launching out from here regarding AWS outages and operational excellence varying across regions, and while very tempting I am fully aware that I have circumstantial evidence at best, and will refrain from flying too close to the sun for now. Let's just say it does not surprise me that us-west-2 is as close to golden child as it gets.