This project offers a Kotlin DSL for Terraform. Kotlin brings the advantages of type safety, IDE autocomplete and the ability to embed code within templates + many other possibilities. This is an experiment in its early stages - there is a mapping of AWS resources only (in com.typedpath.terraform2kotlin.aws) - please provide feedback!
gradle build -x test cd terraform2kotlin gradle test
Beware the tests create cloud resources that cost money !
For the tests to work you need to:
Most of these tests create infrastructure which is destroyed at the end of the test to save money. In order to look at the infrastructure created comment this line: println(runner.destroy()) __EksGettingStarted_test__ takes a long time sometimes (>30 minutes) and is the most expensive so its worth considering "@Ignore ing".
The examples listed above create templates by extension e.g.:
class SecurityGroupEc2Template(webgreeting: String) : TerraformTemplate() {...
templates declared in this way will have a terraform resource for every property that extends com.typedpath.terraform.Resource.
In the case of SecurityGroupEc2Template.kt these 2 property declarations map to an ec2 instance, security group and output:
val myec2 = aws_instance(ami = "ami-0389b2a3c4948b1a0", instance_type = "t2.micro"). apply {
security_groups = listOf(securityGroupName) . . . .
val web_traffic = aws_security_group( . . . .
val public_ip = Output( ......
Note kotlin forces mandatory fields to be specified in the constructor. Non mandatory fields can be specified in an apply block
Templates are mapped to .tf format with the toTerraform function e.g.:
val template = SecurityGroupEc2Template(webGreeting)
println("template:\r\n ${toTerraform(template)}")
In this example this will give this .tf:
resource "aws_instance" "myec2" {
ami = "ami-0389b2a3c4948b1a0"
. . . .
resource "aws_security_group" "web_traffic" {
egress {
. . . .
output "public_ip" {
value = "${aws_instance.myec2.public_ip}"
}
Most of these examples parameterize templates via the Kotlin constructor e.g. :
class ApiGatewayBasicTemplate(function: aws_lambda_function, region: String, accountId: String) : TerraformTemplate() {
}
Please avoid the anti-pattern of declaring resource properties as constructor parameters:
//Warning declaring a resource property as a constructor parameter will cause unexpected results!
class ApiGatewayBasicTemplate(val function: aws_lambda_function, region: String, accountId: String) : TerraformTemplate() {
}
Description | Terraform2Kotlin | Terraform |
---|---|---|
Representation of Mandatory / Optional | Kotlin Language Feature | N / A |
Representation of Enumerated Values such as __aws_autoscaling_policy.policy_type__ | Kotlin Enum | N / A |
Rich Scoping / Modularisation | Functions and Classes | N / A |
Terraform Modules | Not supported - workaround for terraform global namespace via TerraformTemplate.scope property | Native |
Terraform Locals | Limited supported - Kotlin scoped variables preferred | Native |
(forward) attribute references | via scoped call e.g. gatewayResource.idRef() | via global reference e.g. __aws_api_gateway_resource.gatewayResource.id__ |
resource references | via scoped variable e.g. __depends_on = listOf(methodResource, integration)__ | via global reference e.g. __depends_on = [ aws_api_gateway_method.methodResource, aws_api_gateway_integration.integration]__ |
Other languages Required | No - backends can be written in Kotlin. Compatibility with alternative frontend languages is easy to support with kotlin plugins. The examples here create infrastructure, deploy code and execute client test code : all 100% kotlin. | Yes - terraform only represents infrastructure :-(. |