I have spent a day without success trying to mock a data resource like this:
data "terraform_remote_state" "global" {
backend = "s3"
config = {
bucket = var.tfstate_bucket
key = var.global_tfstate_key
region = "ap-southeast-2"
}
}
data "aws_cloudformation_stack" "stackset_provider_base" {
name = data.terraform_remote_state.global.outputs.provider_stack_name
}
data "aws_security_group" "provider_sg_01" {
id = data.aws_cloudformation_stack.stackset_provider_base.outputs["ProviderSG01Id"]
}
data "aws_security_group" "provider_sg_02" {
id = data.aws_cloudformation_stack.stackset_provider_base.outputs["ProviderSG02Id"]
}
One approach I tried is this:
mock_provider "aws" {
override_data {
target = data.terraform_remote_state.global
values = {
outputs = {
provider_stack_name = "mock-provider-stack"
}
}
}
override_data {
target = data.aws_cloudformation_stack.stackset_provider_base
values = {
outputs = {
ProviderSG01Id = "sg-0123456789abcdef0"
ProviderSG02Id = "sg-abcdef01234567890"
}
}
}
Using this approach and terraform test still reaches out to the remote state suggesting that remote state was not mocked.
I also tried variations on this:
mock_provider "aws" {
mock_data "aws_cloudformation_stack" {
defaults = {
outputs = {
ProviderSG01Id = "sg-0123456789abcdef0"
ProviderSG02Id = "sg-abcdef01234567890"
}
}
}
}
mock_provider "terraform" {
mock_data "terraform_remote_state" {
defaults = {
outputs = {
provider_stack_name = "fake-stack-name"
}
}
}
}
Nothing I’ve tried seems to work however. Is it possible to create a mock here?
Hi @alexharv074! Do you have the full test cases you are trying to test available to share? Your second approach works for me:
# main.tf
variable "tfstate_bucket" {
type = string
default = "something"
}
variable "global_tfstate_key" {
type = string
default = "something else"
}
data "terraform_remote_state" "global" {
backend = "s3"
config = {
bucket = var.tfstate_bucket
key = var.global_tfstate_key
region = "ap-southeast-2"
}
}
data "aws_cloudformation_stack" "stackset_provider_base" {
name = data.terraform_remote_state.global.outputs.provider_stack_name
}
data "aws_security_group" "provider_sg_01" {
id = data.aws_cloudformation_stack.stackset_provider_base.outputs["ProviderSG01Id"]
}
data "aws_security_group" "provider_sg_02" {
id = data.aws_cloudformation_stack.stackset_provider_base.outputs["ProviderSG02Id"]
}
# main.tftest.hcl
mock_provider "aws" {
mock_data "aws_cloudformation_stack" {
defaults = {
outputs = {
ProviderSG01Id = "sg-0123456789abcdef0"
ProviderSG02Id = "sg-abcdef01234567890"
}
}
}
}
mock_provider "terraform" {
mock_data "terraform_remote_state" {
defaults = {
outputs = {
provider_stack_name = "fake-stack-name"
}
}
}
}
run "test" {}
Those two files, when executed with terraform test -verbose
, give me the following:
~/terraform/72491 > terraform test -verbose
main.tftest.hcl... in progress
run "test"... pass
# data.aws_cloudformation_stack.stackset_provider_base:
data "aws_cloudformation_stack" "stackset_provider_base" {
capabilities = []
description = "naelyz6m"
disable_rollback = false
iam_role_arn = "a0trgmrd"
id = "tw8772ar"
name = "fake-stack-name"
notification_arns = []
outputs = {
"ProviderSG01Id" = "sg-0123456789abcdef0"
"ProviderSG02Id" = "sg-abcdef01234567890"
}
parameters = {}
tags = {}
template_body = "6dsy2cae"
timeout_in_minutes = 0
}
# data.aws_security_group.provider_sg_01:
data "aws_security_group" "provider_sg_01" {
arn = "rypz91ss"
description = "fx4dmjl9"
id = "sg-0123456789abcdef0"
name = "ojux9bmn"
tags = {}
vpc_id = "41kmvcgx"
}
# data.aws_security_group.provider_sg_02:
data "aws_security_group" "provider_sg_02" {
arn = "igvm5nu4"
description = "716cu08v"
id = "sg-abcdef01234567890"
name = "2anm7m18"
tags = {}
vpc_id = "rw4dl7f8"
}
# data.terraform_remote_state.global:
data "terraform_remote_state" "global" {
backend = "s3"
config = {
bucket = "something"
key = "something else"
region = "ap-southeast-2"
}
outputs = {
provider_stack_name = "fake-stack-name"
}
}
main.tftest.hcl... tearing down
main.tftest.hcl... pass
Success! 1 passed, 0 failed.
~/terraform/72491 >
You can see in the verbose output that the mock providers have filled in the relevant data from the provided mocks, while filled in everything else with correctly typed attributes.
Perhaps running with the -verbose
flag will show you more about what is happening? Or if you shared an example test case I could also take a look at that. Thanks!
Just as an aside, the first approach you shared wouldn’t work for the terraform_remote_state. By embedding the mock_data block in the mock_provider you are telling the testing framework to only apply the mock behaviour to resources managed by the specified behaviour.
You can also override behaviour of data sources and resources outside of the provider using the override_data
and override_resource
block without affecting the behaviour of all the other resources within a given provider.