Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for first-class expressions to Terraform lexer #1303

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 0 additions & 15 deletions lib/rouge/demos/terraform
Original file line number Diff line number Diff line change
@@ -1,10 +1,3 @@
# From: /~https://github.com/terraform-providers/terraform-provider-aws/blob/master/examples/count/main.tf

# Specify the provider and access details
provider "aws" {
region = "${var.aws_region}"
}

resource "aws_elb" "web" {
name = "terraform-example-elb"

Expand All @@ -21,11 +14,3 @@ resource "aws_elb" "web" {
# The instances are registered automatically
instances = ["${aws_instance.web.*.id}"]
}

resource "aws_instance" "web" {
instance_type = "m1.small"
ami = "${lookup(var.aws_amis, var.aws_region)}"

# This will create 4 instances
count = 4
}
8 changes: 8 additions & 0 deletions lib/rouge/lexers/terraform.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,14 @@ def self.builtins
@builtins ||= %w()
end

prepend :hash do
rule %r/[.,()*]/, Punctuation
end

prepend :array do
rule %r/[.,()*]/, Punctuation
end

state :strings do
rule %r/\\./, Str::Escape
rule %r/\$\{/ do
Expand Down
299 changes: 27 additions & 272 deletions spec/visual/samples/terraform
Original file line number Diff line number Diff line change
@@ -1,31 +1,36 @@
# From /~https://github.com/terraform-providers/terraform-provider-aws/blob/master/examples/ecs-alb/main.tf
# Comment

# Specify the provider and access details
# Object with no key/value pairs
data "aws_availability_zones" "available" {}

# Object with single key/value
provider "aws" {
region = "${var.aws_region}"
most_recent = false
}

## EC2

### Network

data "aws_availability_zones" "available" {}
# Object with various comma-separated values
provider "aws" {
most_recent = false, other_value = null
}

# Object with various newline-separated values
resource "aws_vpc" "main" {
most_recent = true
cidr_block = "10.10.0.0/16"
region = "${var.aws_region}"
count = 0
another_num = 3.14
}

# Object with interpolated values
resource "aws_subnet" "main" {
count = "${var.az_count}"
cidr_block = "${cidrsubnet(aws_vpc.main.cidr_block, 8, count.index)}"
availability_zone = "${data.aws_availability_zones.available.names[count.index]}"
vpc_id = "${aws_vpc.main.id}"
}

resource "aws_internet_gateway" "gw" {
vpc_id = "${aws_vpc.main.id}"
}

# Object with nested object
resource "aws_route_table" "r" {
vpc_id = "${aws_vpc.main.id}"

Expand All @@ -35,175 +40,17 @@ resource "aws_route_table" "r" {
}
}

resource "aws_route_table_association" "a" {
count = "${var.az_count}"
subnet_id = "${element(aws_subnet.main.*.id, count.index)}"
route_table_id = "${aws_route_table.r.id}"
}

### Compute

# Object with list value
resource "aws_autoscaling_group" "app" {
name = "tf-test-asg"
vpc_zone_identifier = ["${aws_subnet.main.*.id}"]
min_size = "${var.asg_min}"
max_size = "${var.asg_max}"
desired_capacity = "${var.asg_desired}"
launch_configuration = "${aws_launch_configuration.app.name}"
}

# Object with nested interpolation
data "template_file" "cloud_config" {
template = "${file("${path.module}/cloud-config.yml")}"

vars {
aws_region = "${var.aws_region}"
ecs_cluster_name = "${aws_ecs_cluster.main.name}"
ecs_log_level = "info"
ecs_agent_version = "latest"
ecs_log_group_name = "${aws_cloudwatch_log_group.ecs.name}"
}
}

data "aws_ami" "stable_coreos" {
most_recent = true

filter {
name = "description"
values = ["CoreOS Container Linux stable *"]
}

filter {
name = "architecture"
values = ["x86_64"]
}

filter {
name = "virtualization-type"
values = ["hvm"]
}

owners = ["595879546273"] # CoreOS
}

resource "aws_launch_configuration" "app" {
security_groups = [
"${aws_security_group.instance_sg.id}",
]

key_name = "${var.key_name}"
image_id = "${data.aws_ami.stable_coreos.id}"
instance_type = "${var.instance_type}"
iam_instance_profile = "${aws_iam_instance_profile.app.name}"
user_data = "${data.template_file.cloud_config.rendered}"
associate_public_ip_address = true

lifecycle {
create_before_destroy = true
}
}

### Security

resource "aws_security_group" "lb_sg" {
description = "controls access to the application ELB"

vpc_id = "${aws_vpc.main.id}"
name = "tf-ecs-lbsg"

ingress {
protocol = "tcp"
from_port = 80
to_port = 80
cidr_blocks = ["0.0.0.0/0"]
}

egress {
from_port = 0
to_port = 0
protocol = "-1"

cidr_blocks = [
"0.0.0.0/0",
]
}
}

resource "aws_security_group" "instance_sg" {
description = "controls direct access to application instances"
vpc_id = "${aws_vpc.main.id}"
name = "tf-ecs-instsg"

ingress {
protocol = "tcp"
from_port = 22
to_port = 22

cidr_blocks = [
"${var.admin_cidr_ingress}",
]
}

ingress {
protocol = "tcp"
from_port = 8080
to_port = 8080

security_groups = [
"${aws_security_group.lb_sg.id}",
]
}

egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}

## ECS

resource "aws_ecs_cluster" "main" {
name = "terraform_example_ecs_cluster"
}

data "template_file" "task_definition" {
template = "${file("${path.module}/task-definition.json")}"

vars {
image_url = "ghost:latest"
container_name = "ghost"
log_group_region = "${var.aws_region}"
log_group_name = "${aws_cloudwatch_log_group.app.name}"
}
}

resource "aws_ecs_task_definition" "ghost" {
family = "tf_example_ghost_td"
container_definitions = "${data.template_file.task_definition.rendered}"
}

resource "aws_ecs_service" "test" {
name = "tf-example-ecs-ghost"
cluster = "${aws_ecs_cluster.main.id}"
task_definition = "${aws_ecs_task_definition.ghost.arn}"
desired_count = 1
iam_role = "${aws_iam_role.ecs_service.name}"

load_balancer {
target_group_arn = "${aws_alb_target_group.test.id}"
container_name = "ghost"
container_port = "2368"
}

depends_on = [
"aws_iam_role_policy.ecs_service",
"aws_alb_listener.front_end",
]
}

## IAM

# Object with HEREDOC string
resource "aws_iam_role" "ecs_service" {
name = "tf_example_ecs_role"

Expand All @@ -224,103 +71,11 @@ resource "aws_iam_role" "ecs_service" {
EOF
}

resource "aws_iam_role_policy" "ecs_service" {
name = "tf_example_ecs_policy"
role = "${aws_iam_role.ecs_service.name}"

policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:Describe*",
"elasticloadbalancing:DeregisterInstancesFromLoadBalancer",
"elasticloadbalancing:DeregisterTargets",
"elasticloadbalancing:Describe*",
"elasticloadbalancing:RegisterInstancesWithLoadBalancer",
"elasticloadbalancing:RegisterTargets"
],
"Resource": "*"
}
]
}
EOF
}

resource "aws_iam_instance_profile" "app" {
name = "tf-ecs-instprofile"
role = "${aws_iam_role.app_instance.name}"
}

resource "aws_iam_role" "app_instance" {
name = "tf-ecs-example-instance-role"

assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOF
}

data "template_file" "instance_profile" {
template = "${file("${path.module}/instance-profile-policy.json")}"

vars {
app_log_group_arn = "${aws_cloudwatch_log_group.app.arn}"
ecs_log_group_arn = "${aws_cloudwatch_log_group.ecs.arn}"
}
}

resource "aws_iam_role_policy" "instance" {
name = "TfEcsExampleInstanceRole"
role = "${aws_iam_role.app_instance.name}"
policy = "${data.template_file.instance_profile.rendered}"
}

## ALB

resource "aws_alb_target_group" "test" {
name = "tf-example-ecs-ghost"
port = 80
protocol = "HTTP"
vpc_id = "${aws_vpc.main.id}"
}

resource "aws_alb" "main" {
name = "tf-example-alb-ecs"
subnets = ["${aws_subnet.main.*.id}"]
security_groups = ["${aws_security_group.lb_sg.id}"]
}

resource "aws_alb_listener" "front_end" {
load_balancer_arn = "${aws_alb.main.id}"
port = "80"
protocol = "HTTP"

default_action {
target_group_arn = "${aws_alb_target_group.test.id}"
type = "forward"
}
}

## CloudWatch Logs

resource "aws_cloudwatch_log_group" "ecs" {
name = "tf-ecs-group/ecs-agent"
}

resource "aws_cloudwatch_log_group" "app" {
name = "tf-ecs-group/app-ghost"
## Object with first-class expressions
resource "aws_subnet" "main" {
count = var.az_count
cidr_block = cidrsubnet(aws_vpc.main.cidr_block, 8, count.index)
availability_zone = data.aws_availability_zones.available.names[count.index]
vpc_id = aws_vpc.main.id
fqns = aws_route53_record.cert_validation[*].fqdn
}