Skip to content

Commit

Permalink
Merge pull request #6 from env0/feat-special-care-with-autoscaling_group
Browse files Browse the repository at this point in the history
Feature: Special care for aws_autoscaling_group
  • Loading branch information
roni-frantchi authored Jan 13, 2020
2 parents 5724e81 + 9649a3a commit 3605d9c
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 12 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ go build
## Usage
Terratag recives two commaind line arguments:
- `-dir` - optional, the directory to recursively search for any `.tf` file and try to terratag it.
- `-tags` - tags, in valid **HCL map syntax** (not JSON!)
- `-tags` - tags, as valid JSON (NOT HCL)

```bash
terraform init # needed to initialize provider schema and pull child terraform modules
terratag -dir=foo/bar -tags='{ hello = "world" }' # (or go main.go -dir=... -tags=...)
terratag -dir=foo/bar -tags=\"hello\": \"world\"} # (or go run . -dir=... -tags=...)
```

## Notes
Expand Down
60 changes: 50 additions & 10 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ func initArgs() (string, string, bool) {
dir = setFlag("dir", ".")

if tags == "" {
log.Println("Usage: terratag -tags='{ some_tag = \"value\" }' [-dir=\".\"]")
log.Println("Usage: terratag -tags='{ \"some_tag\": \"value\" }' [-dir=\".\"]")
isMissingArg = true
}

Expand Down Expand Up @@ -105,21 +105,28 @@ func tagFileResources(path string, dir string, tags string, tfVersion int) {

terratag := TerratagLocal{
Found: map[string]hclwrite.Tokens{},
Added: tags,
Added: jsonToHclMap(tags),
}

anyTagged := false
var swappedTagsStrings []string

for _, block := range file.Body().Blocks() {
if block.Type() == "resource" {
resourceType := block.Labels()[0]
log.Print("Processing resource ", block.Labels())
for _, resource := range file.Body().Blocks() {
if resource.Type() == "resource" {
resourceType := resource.Labels()[0]
log.Print("Processing resource ", resource.Labels())

isTaggable := isTaggable(dir, resourceType)
isTaggable, isTaggableViaSpecialTagBlock := isTaggable(dir, resourceType)

if isTaggable {
swappedTagsStrings = append(swappedTagsStrings, tagResource(filename, terratag, block, tfVersion))
if !isTaggableViaSpecialTagBlock {
// for now, we count on it that if there's a single "tag" in the schema (unlike "tags" block),
// then no "tags" interpolation is used, but rather multiple instances of a "tag" block
// https://www.terraform.io/docs/providers/aws/r/autoscaling_group.html
swappedTagsStrings = append(swappedTagsStrings, tagResource(filename, terratag, resource, tfVersion))
} else {
appendTagBlocks(resource, tags)
}
anyTagged = true
} else {
log.Print("Resource not taggable, skipping. ")
Expand All @@ -145,6 +152,32 @@ func tagFileResources(path string, dir string, tags string, tfVersion int) {
}
}

func appendTagBlocks(resource *hclwrite.Block, tags string) {
var tagsMap map[string]string
err := json.Unmarshal([]byte(tags), &tagsMap)
panicOnError(err, nil)

for key, value := range tagsMap {
resource.Body().AppendNewline()
tagBlock := resource.Body().AppendNewBlock("tag", nil)
tagBlock.Body().SetAttributeValue("key", cty.StringVal(key))
tagBlock.Body().SetAttributeValue("value", cty.StringVal(value))
tagBlock.Body().SetAttributeValue("propagate_at_launch", cty.BoolVal(true))
}
}

func jsonToHclMap(tags string) string {
var tagsMap map[string]string
err := json.Unmarshal([]byte(tags), &tagsMap)
panicOnError(err, nil)

var mapContent []string
for key, value := range tagsMap {
mapContent = append(mapContent, "\""+key+"\"="+"\""+value+"\"")
}
return "{" + strings.Join(mapContent, ",") + "}"
}

func panicOnError(err error, moreInfo *string) {
if err != nil {
if moreInfo != nil {
Expand Down Expand Up @@ -326,7 +359,7 @@ func getResourceExistingTagsKey(filename string, resource *hclwrite.Block) strin
return "terratag_found_" + filename + delimiter + strings.Join(resource.Labels(), delimiter)
}

func isTaggable(dir string, resourceType string) bool {
func isTaggable(dir string, resourceType string) (bool, bool) {
command := exec.Command("tfschema", "resource", "show", "-format=json", resourceType)
command.Dir = dir
output, err := command.Output()
Expand All @@ -339,6 +372,8 @@ func isTaggable(dir string, resourceType string) bool {
panicOnError(err, nil)

isTaggable := false
isTaggableViaSpecialTagBlock := false

attributes := schema["attributes"].([]interface{})
for _, attributeMap := range attributes {
var attribute TfSchemaAttribute
Expand All @@ -349,7 +384,12 @@ func isTaggable(dir string, resourceType string) bool {
isTaggable = true
}
}
return isTaggable

if resourceType == "aws_autoscaling_group" {
isTaggableViaSpecialTagBlock = true
}

return isTaggable, isTaggableViaSpecialTagBlock
}

type TfSchemaAttribute struct {
Expand Down

0 comments on commit 3605d9c

Please sign in to comment.