16

I have my security groups in a securitygroup.tf file.

In the same dir there are plenty of other resource descriptions (rds, ec2 etc).

Is there a way to perform a terraform apply --auto-approve only for my securitygroups.tf?

18

Not really. The standard way to work around this though is to use eg:

terraform apply -target=aws_security_group.my_sg

but that's only going to apply one security group at a time, so will get tedious if you have a lot of them. You can, however, target multiple resources in one command:

terraform apply -target=aws_security_group.my_sg -target=aws_security_group.my_2nd_sg

However, there are potentially a couple of workarounds:

  • The -target parameter respects dependencies.

    This means if you were to eg. -target=aws_instance.my_server and that instance had, say, five security groups attached to it via interpolation, changes to those security groups should be included in the plan (I haven't thoroughly tested this, but I believe this is how it works).

    That is a bit messy though, as you probably don't want to touch an instance. A safer alternative might be using something like a null_resource to provide a target for the security groups, but again I haven't tried this (there might be another 'safe' resource you could rely on, though?).

  • Create a module.

    You can target a module just like you can target a plain resource:

    terraform apply -target=module.my_security_groups
    

    Inside this module, you could define all of your security groups - just like you would have outside of the module. As well as being able to target it directly, this also makes it easier for you to re-use the same set of security groups for other infrastructure, if you ever need to.

2

If you organize your code by modules, you could apply terraform only on a module, eg :

# securitygroup.tf
module "securitygroup" {
  source = "git@github.com:user/securitygroup-terraform-module.git?ref=master"
}

$ tf apply -target=module.securitygroup
1

Doesn't look like it's possible. Here is the code to load config files and it loads all *.tf files from current directory (or a specified one) and there is nothing there to limit the configuration to a single file.

0

Using terraform module is preferred, but if you really have to run terraform apply against a single file, I made this bash script to generate terraform apply command against all targets and modules in one file:

#!/usr/bin/env bash
if [[ -z "$@" ]]; then
  echo "Missing file input arguments"
  exit 1
fi

echo "terraform apply \\"
for FILE in "$@"
do
  RESOURCE=$(sed -n 's/resource "\([^"]*\)" "\([^"]*\)".*/-target=\1.\2 \\/gp' $FILE)
  MODULE=$(sed -n 's/module "\([^"]*\)".*/-target=module.\1 \\/gp' $FILE)
  if [[ -z "$RESOURCE" ]] && [[ -z "$MODULE" ]]; then
    echo "Cannot detect terraform resource and module in $FILE"
    exit 1
  fi

  if [[ ! -z "$RESOURCE" ]]; then
    echo -e $"$RESOURCE"
  fi
  if [[ ! -z "$MODULE" ]]; then
    echo -e $"$MODULE"
  fi
done
echo "-refresh=true"

I'm not really bash expert, but it was tested to work on Mac.

EDIT: The sed command assumes that the resources and modules are formatted nicely according to terraform fmt, like so:

resource "aws_eip" "my_public_ip" {
}

resource "aws_instance" "my_server" {
}

module "my_module" {
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.