Skip to content

Instantly share code, notes, and snippets.

@lwoodson
Last active June 1, 2020 18:32
Show Gist options
  • Save lwoodson/67fab974c41230d5514efb0cfba77568 to your computer and use it in GitHub Desktop.
Save lwoodson/67fab974c41230d5514efb0cfba77568 to your computer and use it in GitHub Desktop.
Supporting a new file extension in Vim based on existing file extension

I use this for identifying *.cfn.json and *.cfn.yml files as JSON and YAML format cloudformation templates. Their filetypes are set to cfn_json and cfn_yaml respectively. I can then have custom highlighting of key attributes and/or custom snippets set up that are not polluting my editor when I am working with straight javascript/yaml intended for other purposes. This in on mac os x after installing vim 7.3 along with vim-snipmate and vim-snippets plugins. Someone feel free to improve on this.

1. in ~/.vimrc:

au BufRead,BufNewFile *.cfn.json set ft=cfn_json
au BufRead,BufNewFile *.cfn.yml set ft=cfn_yaml
au BufRead,BufNewFile *.cfn.yaml set ft=cfn_yaml

2. Make necessary directories in ~/.vim

mkdir -p ~/.vim/ftplugin
mkdir -p ~/.vim/syntax

3. Copy existing *.vim files for JSON and YAML files into override locations

# cloudformation json
cp /usr/share/vim/vim73/ftplugin/javascript.vim ~/.vim/ftplugin/cfn_json.vim
cp /usr/share/vim/vim73/syntax/javascript.vim ~/.vim/syntax/cfn_json.vim

# cloudformation yaml
cp /usr/share/vim/vim73/ftplugin/yaml.vim ~/.vim/ftplugin/cfn_yaml.vim
cp /usr/share/vim/vim73/syntax/yaml.vim ~/.vim/syntax/cfn_yaml.vim

4. Paste in contents of snippets files below

Snippets Reference

  • Top-level
    • skeleton: outputs a basic skeleton of a cloudformation template
    • param: outputs a snippet for an input parameter element
    • meta: outputs a snippet for a metadata element
    • map: outputs a snippet for a mapping element
    • cond: outputs a snippet for a condition element
    • rsrc: outputs a snippet for a resource element
    • out: outputs a snippet for an output element
  • functions
    • ref: ouputs a shorthand Ref fn snippet
    • gat: ouputs a shorthand GetAtt fn snippet
    • sub: outputs a shorthand Sub fn snippet
    • sub+: outputs a shorthand Sub fn snippet for a multiline string
    • join: Outputs a shorthand Join fn snippet
    • ==: outputs a shorthand Equals expression
    • !=: outputs a shorthand Not expression
    • if: outputs a shorthand If statement
    • fim: outputs a shorthand FindInMap expression
  • resources
    • lconfig: Outputs an AWS::AutoScaling::LaunchConfiguration snippet
    • asg: Outputs an AWS::AutoScaling::AutoScalingGroup snippet
    • role: Outputs an AWS::IAM::Role snippet
    • policy: Outputs a policy snippet for an AWS::IAM::Role
    • iprof: Outputs an AWS::IAM::InstanceProfile snippet
    • elb: Outputs an AWS::ElasticLoadBalancing::LoadBalancer snippet
snippet +.skeleton
AWSTemplateFormatVersion: "2010-09-09"
Description: Write me
Metadata:
# add metadata
Parameters:
# add parameters
Mappings:
# add mapping
Conditions:
# add conditions
Resources:
# add resources
Outputs:
# add outputs
snippet +.param
${0:TODO_PARAM_NAME}:
Type: TODO_TYPE
Description: TODO_DESC
Default: TODO_DEFAULT
AllowedValues:
- TODO_ALLOWED_VALUE
snippet +.metadata
${0:TODO_METADATA_NAME}:
Description: TODO_DESC
snippet +.mapping
${0:TODO_MAPPING_NAME}:
TODO_KEY1:
TODO_KEY2: TODO_VALUE
snippet +.condition
${1:CONDITION_NAME}:
TODO_FN
snippet +.resource
${0:TODO_RESOURCE_NAME}:
Type: TODO_RESOURCE_TYPE
Properties:
TODO_PROPERTIES
snippet +.out
${0:TODO_OUTPUT_NAME}:
Description: TODO_DESC
Value: TODO_VALUE
Export:
TODO_EXPORTS
# Functions
snippet fn.ref
!Ref ${0:RESOURCE}
snippet fn.get-att
!GetAtt ${1:TARGET}.${2:ATTR}
snippet sub
!Sub ${1:STRING}
snippet sub+
!Sub |
${1}
snippet join
!Join [ ${1:DELIM}, [ ${2:VALUES} ] ]
snippet find-in-map
!FindInMap [ ${1:ELEMENTS} ]
# Condition functions
snippet ==
!Equals [ ${1:REFERNCE}, ${2:VALUE} ]
snippet +=
!Not [ !Equals [ ${1:REFERENCE}, ${2:VALUE} ] ]
snippet if
!If [ ${1:CONDITION}, ${2:TRUE_CASE}, ${3:FALSE_CASE} ]
snippet &&
!And [ ${1:CONDITIONS} ]
snippet ||
!Or [ ${1:CONDITIONS} ]
# pseudo params
snippet pp.account-id
AWS::AccountId
snippet pp.region
AWS::Region
snippet pp.stack-id
AWS::StackId
snippet pp.stack-name
AWS::StackName
snippet pp.no-value
AWS::NoValue
# Resources
snippet +.res.launch-config
${0:LaunchConfig}:
Type: "AWS::AutoScaling::LaunchConfiguration"
Properties:
KeyName: bv-nexus
ImageId: +.etAtt Image.ImageId
InstanceType: +.ef InstanceType
IamInstanceProfile: +.ef InstanceProfile
SecurityGroups:
- +.etAtt NexusSecurityGroups.InternalTrafficId
InstanceMonitoring: false
UserData:
Fn::Base64: >
#!/bin/bash
echo whats up
snippet +.res.asg
${0:AutoScalingGroup}:
Type: "AWS::AutoScaling::AutoScalingGroup"
Properties:
LaunchConfigurationName: +.ef LaunchConfig
AvailabilityZones: +.etAtt Vpc.PrivateSubnetAZs
VPCZoneIdentifier: +.etAtt Vpc.PrivateSubnetIds
MinSize: 1
MaxSize: 1
DesiredCapacity: 1
LoadBalancerNames: []
NotificationConfigurations:
-
NotificationTypes:
- autoscaling:EC2_INSTANCE_LAUNCH
TopicARN: +.ub arn:aws:sns:${AWS::Region}:${AWS::AccountId}:route53-private-record-set-asg
Tags:
-
Key: Name
Value: TODO_NAME
PropagateAtLaunch: true
-
Key: bv:nexus:role
Value: TODO_ROLE
PropagateAtLaunch: true
snippet +.res.role
${0:InstanceRole}:
Type: "AWS::IAM::Role"
Properties:
Path: /
Policies:
-
PolicyName: TODO_POLICY_NAME
PolicyDocument:
Statement:
-
Effect: Allow
Action:
- TODO_ACTION
Resource:
- TODO_RESOURCE
AssumeRolePolicyDocument:
Statement:
-
Effect: Allow
Principal:
Service:
- ec2.amazonaws.com
Action:
- sts:AssumeRole
snippet +.res.policy
-
PolicyName: ${1:NAME}
PolicyDocument:
Statement:
-
Effect: TODO_EFFECT
Action:
- TODO_ACTION
Resource:
- TODO_RESOURCE
snippet +.res.instance-profile
${0:InstanceProfile}:
Type: "AWS::IAM::InstanceProfile"
Properties:
Path: /
Roles:
- +.ef InstanceRole
snippet +.res.elb
${0:LoadBalancer}:
Type: "AWS::ElasticLoadBalancing::LoadBalancer"
Properties:
Scheme: internal
Subnets: +.etAtt Vpc.PrivateSubnetIds
SecurityGroups:
- +.etAtt NexusSecurityGroups.InternalTrafficId
Listeners:
-
Protocol: HTTP
LoadBalancerPort: 80
InstanceProtocol: HTTP
InstancePort: 8080
HealthCheck:
HealthyThreshold: 2
Interval: 15
Target: TCP:8080
Timeout: 5
UnhealthyThreshold: 3
# BV Resources
snippet +.bv.nexus-vpc
${0:Vpc}:
Type: "Custom::NexusVpc"
Version: "1.0"
Properties:
ServiceToken: +.ub "arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:CommonCfnResource"
snippet +.bv.image-info
${0:Image}:
Type: "Custom::EC2ImageInfo"
Version: "1.0"
Properties:
ServiceToken: +.ub "arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:CommonCfnResource"
Version: "2016.03.03"
# this
ImageName: TODO_IMAGE_NAME
# or this
Version: 2016.03.3
InstanceType: +.ef InstanceType
VirtualizationType: TODO_VIRTUALIZATION_TYPE
StorageType: TODO_STORAGE_TYPE
snippet +.bv.security-group
${0:NexusSecurityGroups}:
Type: "Custom::NexusSecurityGroups"
Version: "1.0"
Properties:
ServiceToken: +.ub "arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:CommonCfnResource"
${1}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment