Terraforming my world
@nathandench
https://ndench.github.io
#BrisPHP
From "interested but scared" to never manually provisioning infrastructure again
Who am I?
- Co-founder of ProcurePro.co
- Fullstack Symfony + Aurelia engineer
- Begrudging DevOps engineer
- Absolutely hate manual repetitive tasks
In the beginning
- Handcrafted snowflake servers
- Confluence page documentation
- No CI pipeline
- Manual deploys with SSH + git pull
- Weekly downtime with manual fixes
- Shared Virtualbox images for dev
- High bus factor
Is there a better way?
- Improve developer experience
- Improve development speed
- Autoscaling/autohealing infrastructure
- Less bugs/errors in production
- Infrastructure shouldn't need constant maintenance
- Smaller bus factor
Step 1
- Series of bash scripts to create a server
- Make an AMI
- Packer = bonus points
- One "special" server for cron jobs, etc
- Other servers can be duplicated for scale
- Dev box built from same script + extras
- Packer = bonus points
Step 2
- Create CI build servers
- Use existing scripts
- Containers or dedicated server
- CI build tasks
- Automated tests
- Database fixtures = bonus points
- Static analysis
- Deployment
- Can script ssh deploys
- Or use CodeDeploy, Deployer, etc
- Migrations = bonus points
Step 3
- VPC
- Subnets
- CIDR blocks
- DHCP options
- Internet gateway
- NAT gateways/instances
- Route tables
- Subnet groups
- Database
- Elasticache
- Redshift
- Security groups
- IAM roles
- Network ACLs
- Customer gateways
- VPN gateways
Terraform the hard parts
Step 3
Terraform the hard parts
Step 3
Terraform the hard parts
$ cd terraform
$ terraform import aws_vpc.this vpc-a01106c2
Successfully imported!
$ terraform import aws_internet_gateway.this igw-c0a643a9
Successfully imported!
$ terraform import aws_subnet.public subnet-9d4a7b6c
Successfully imported!
$ terraform import aws_subnet.private subnet-9d4a7b6c
Successfully imported!
$ terraform import aws_nat_gateway.this nat-05dba92075d71c408
Successfully imported!
terraform/
├─ main.tf
Step 4
Custom modules
Step 4
$ terraform state aws_vpc.this module.infra.aws_vpc.this
Successfully moved!
$ terraform state mv aws_internet_gateway.this module.infra.aws_internet_gateway.this
Successfully moved!
$ terraform state mv aws_subnet.public module.infra.aws_subnet.public
Successfully moved!
$ terraform state mv aws_subnet.private module.infra.aws_subnet.private
Successfully moved!
$ terraform state mv aws_nat_gateway.this module.infra.aws_nat_gateway.this
Successfully moved!
Custom modules
terraform/
├─ modules/
│ ├─ main.tf
├─ staging/
│ ├─ main.tf
├─ producton/
│ ├─ main.tf
Step 5
Third party modules
Pros
- Easily use more features
- Use better more well maintained code
Cons
- Need to ensure module is maintained
- Might not have the options you need
Step 5
Third party modules
What did all this get me?
- Create separate environments easily
- Completely ignore infrastructure
- Easier to re-learn after a break
- Easier to teach to others (bus factor)
- Create an entirely separate app in a few days
- 80+ resources per environment
- 70+ resources in CI pipeline
Question time!
@nathandench
https://ndench.github.io
#BrisPHP
Terraforming my world
By Nathan Dench
Terraforming my world
- 346