hcl2cdktf
hcl2cdktf copied to clipboard
Tags are rendered invalid
The ./test.tf
example renders tags
like this:
const ubuntu2 = new Instance(this, 'ubuntu2', {
ami: "ami-0ff8a91507f77f867",
availabilityZone: "us-east-1a",
instanceType: "t3.nano",
tags: [
[{
name: "MyInstance2"
}]
]
});
It should be:
const ubuntu2 = new Instance(this, 'ubuntu2', {
ami: "ami-0ff8a91507f77f867",
availabilityZone: "us-east-1a",
instanceType: "t3.nano",
tags: {
name: "MyInstance2"
}
})
I think this is an issue when attempting to use the HCL1 parser due to this:
In Terraform v0.12 and later, the language makes a distinction between argument syntax and nested block syntax within blocks
... the JSON syntax cannot support the nested block processing mode for these arguments. This is, unfortunately, one necessary concession on the equivalence between native syntax and JSON syntax made pragmatically for compatibility with existing provider design patterns. Providers may phase out such patterns in future major releases.
I'm now having it use HCL2 by default, however I now have issues when a single block is present. Example:
resource "aws_instance" "ubuntu" {
ami = "ami-0ff8a91507f77f867"
instance_type = "t3.nano"
availability_zone = "us-east-1a"
network_interface {
network_interface_id = "something"
device_index = 0
}
network_interface {
network_interface_id = "something2"
device_index = 1
}
credit_specification {
cpu_credits = "unlimited"
}
security_groups = [
"sg-123",
"sg-456"
]
tags = {
Name = "MyInstance"
}
}
const ubuntu = new Instance(this, 'ubuntu', {
ami: "ami-0ff8a91507f77f867",
availabilityZone: "us-east-1a",
creditSpecification: {
cpuCredits: "unlimited"
},
instanceType: "t3.nano",
networkInterface: [
{
deviceIndex: 0,
networkInterfaceId: "something"
},
{
deviceIndex: 1,
networkInterfaceId: "something2"
}
],
securityGroups: [
"sg-123",
"sg-456"
],
tags: {
name: "MyInstance"
}
});
Note the cpuCredits
should be an array.
I took this example and converted it bare
:
Generated version
this.addOverride('locals', {
s3OriginId: "myS3Origin"
});
const s3_distribution = new CloudfrontDistribution(this, 's3_distribution', {
aliases: [
"mysite.example.com",
"yoursite.example.com"
],
comment: "Some comment",
defaultCacheBehavior: [{
allowedMethods: [
"DELETE",
"GET",
"HEAD",
"OPTIONS",
"PATCH",
"POST",
"PUT"
],
cachedMethods: [
"GET",
"HEAD"
],
defaultTtl: 3600,
forwardedValues: [{
cookies: [{
forward: "none"
}],
queryString: false
}],
maxTtl: 86400,
minTtl: 0,
targetOriginId: s3_origin_id!,
viewerProtocolPolicy: "allow-all"
}],
defaultRootObject: "index.html",
enabled: true,
isIpv6Enabled: true,
loggingConfig: [{
bucket: "mylogs.s3.amazonaws.com",
includeCookies: false,
prefix: "myprefix"
}],
orderedCacheBehavior: [
{
allowedMethods: [
"GET",
"HEAD",
"OPTIONS"
],
cachedMethods: [
"GET",
"HEAD",
"OPTIONS"
],
compress: true,
defaultTtl: 86400,
forwardedValues: [{
cookies: [{
forward: "none"
}],
headers: [
"Origin"
],
queryString: false
}],
maxTtl: 31536000,
minTtl: 0,
pathPattern: "/content/immutable/*",
targetOriginId: s3_origin_id!,
viewerProtocolPolicy: "redirect-to-https"
},
{
allowedMethods: [
"GET",
"HEAD",
"OPTIONS"
],
cachedMethods: [
"GET",
"HEAD"
],
compress: true,
defaultTtl: 3600,
forwardedValues: [{
cookies: [{
forward: "none"
}],
queryString: false
}],
maxTtl: 86400,
minTtl: 0,
pathPattern: "/content/*",
targetOriginId: s3_origin_id!,
viewerProtocolPolicy: "redirect-to-https"
}
],
origin: [{
domainName: b.bucket_regional_domain_name!,
originId: s3_origin_id!,
s3OriginConfig: [{
originAccessIdentity: "origin-access-identity/cloudfront/ABCDEFG1234567"
}]
}],
priceClass: "PriceClass_200",
restrictions: [{
geoRestriction: [{
locations: [
"US",
"CA",
"GB",
"DE"
],
restrictionType: "whitelist"
}]
}],
tags: {
Environment: "production"
},
viewerCertificate: [{
cloudfrontDefaultCertificate: true
}]
});
const b = new S3Bucket(this, 'b', {
acl: "private",
bucket: "mybucket",
tags: {
Name: "My bucket"
}
});
There were three things I had to fix manually:
- The local issue #1
- Attribute references should be camel cased:
domainName: b.bucketRegionalDomainName!,
rather thandomainName: b.bucket_regional_domain_name!,
- unreferenced variables could be omitted
s3_distribution
in this case. Not sure how complex. that would be. - bucket was declared after distribution, which made Typescript complain
Overall, just minor things and I think that this is really good already!
Here's the working version
this.addOverride('locals', {
s3OriginId: "myS3Origin"
});
const s3_origin_id = "${local.s3OriginId}"
const b = new S3Bucket(this, 'b', {
acl: "private",
bucket: "mybucket",
tags: {
Name: "My bucket"
}
});
new CloudfrontDistribution(this, 's3_distribution', {
aliases: [
"mysite.example.com",
"yoursite.example.com"
],
comment: "Some comment",
defaultCacheBehavior: [{
allowedMethods: [
"DELETE",
"GET",
"HEAD",
"OPTIONS",
"PATCH",
"POST",
"PUT"
],
cachedMethods: [
"GET",
"HEAD"
],
defaultTtl: 3600,
forwardedValues: [{
cookies: [{
forward: "none"
}],
queryString: false
}],
maxTtl: 86400,
minTtl: 0,
targetOriginId: s3_origin_id!,
viewerProtocolPolicy: "allow-all"
}],
defaultRootObject: "index.html",
enabled: true,
isIpv6Enabled: true,
loggingConfig: [{
bucket: "mylogs.s3.amazonaws.com",
includeCookies: false,
prefix: "myprefix"
}],
orderedCacheBehavior: [
{
allowedMethods: [
"GET",
"HEAD",
"OPTIONS"
],
cachedMethods: [
"GET",
"HEAD",
"OPTIONS"
],
compress: true,
defaultTtl: 86400,
forwardedValues: [{
cookies: [{
forward: "none"
}],
headers: [
"Origin"
],
queryString: false
}],
maxTtl: 31536000,
minTtl: 0,
pathPattern: "/content/immutable/*",
targetOriginId: s3_origin_id!,
viewerProtocolPolicy: "redirect-to-https"
},
{
allowedMethods: [
"GET",
"HEAD",
"OPTIONS"
],
cachedMethods: [
"GET",
"HEAD"
],
compress: true,
defaultTtl: 3600,
forwardedValues: [{
cookies: [{
forward: "none"
}],
queryString: false
}],
maxTtl: 86400,
minTtl: 0,
pathPattern: "/content/*",
targetOriginId: s3_origin_id!,
viewerProtocolPolicy: "redirect-to-https"
}
],
origin: [{
domainName: b.bucketRegionalDomainName!,
originId: s3_origin_id!,
s3OriginConfig: [{
originAccessIdentity: "origin-access-identity/cloudfront/ABCDEFG1234567"
}]
}],
priceClass: "PriceClass_200",
restrictions: [{
geoRestriction: [{
locations: [
"US",
"CA",
"GB",
"DE"
],
restrictionType: "whitelist"
}]
}],
tags: {
Environment: "production"
},
viewerCertificate: [{
cloudfrontDefaultCertificate: true
}]
});
however I now have issues when a single block is present
According to the documentation this sounds like an edge case. Perhaps it's ok to ignore for the time being? I'll try to get a feeling for the occurrences of this.
Also, I'll create issues for the things I fixed manually.
The schema for creditSpecification
looks like this:
// On AWS instance resource
"credit_specification": {
"type": ["list", ["object", {
"cpu_credits": "string"
}]],
"description_kind": "plain",
"computed": true
},
For the AWS Provider, there are ~ 100 occurrences of this: "type": ["list", ["object",
- So, we should try to find a solution for this.