

# Install and configure the Terraform provisioning engine
<a name="install-config-engine"></a>

To successfully use Terraform products with AWS Service Catalog, you must install and configure a Terraform provisioning engine in the same account where you will be administering Terraform products. To get started, you can use the Terraform provisioning engine provided by AWS, which installs and configures the code and infrastructure required for the Terraform provisioning engine to work with AWS Service Catalog. This one-time setup takes approximately 30 minutes. AWS Service Catalog provides a GitHub repository with instructions on [ installing and configuring the Terraform provisioning engine](https://github.com/aws-samples/service-catalog-engine-for-terraform-os). 

## Queue determination
<a name="queue-determination"></a>

When you call a provisioning operation, AWS Service Catalog prepares a payload message to send to the relevant queue in the provisioning engine. In order to build the ARN for the queue, AWS Service Catalog makes a the following assumptions:
+ The provisioning engine is located in the account of the product owner
+ The provisioning engine is located in the same region in which the call to AWS Service Catalog was made
+ The provisioning engine queues follows the documented naming schema detailed below

For example, if ProvisionProduct is called in `us-east-1` from account 1111111111 using a product created by account 0000000000000, AWS Service Catalog assumes the correct SQS ARN is `arn:aws:sqs:us-east-1:0000000000000:ServiceCatalogTerraformOSProvisionOperationQueue`. 

The same logic applies for the Lambda function called by `DescribeProvisioningParameters`. 

# Adding Confused Deputy to your Terraform provisioning engine
<a name="confused-deputy-TRFM-engine"></a>

## Confused Deputy context keys on the endpoints to restrict access for `lambda:Invoke` operations
<a name="confused-deputy-TRFM-lambda"></a>

The parameter parser Lambda function created by AWS Service Catalog-provided engines has an access policy that grants cross-account `lambda:Invoke` permission only to the AWS Service Catalog service principal:

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "servicecatalog.amazonaws.com"
            },
            "Action": "lambda:InvokeFunction",
            "Resource": "arn:aws:lambda:us-east-1:111122223333:function:ServiceCatalogTerraformOSParameterParser"
        }
    ]
}
```

------

This should be the only permission necessary in order for the integration with AWS Service Catalog to function properly. However, you can constrain this further using the `aws:SourceAccount` [ Confused Deputy](https://docs.aws.amazon.com/IAM/latest/UserGuide/confused-deputy) context key. When AWS Service Catalog sends messages to these queues, AWS Service Catalog populates the key with the provisioning account's ID. This is helpful when you intend to distribute products via portfolio sharing and want to ensure that only specific accounts are using your engine.

For example, you can restrict your engine to only allow requests that originate from 000000000000 and 111111111111 using the condition shown below:

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "servicecatalog.amazonaws.com"
            },
            "Action": "lambda:InvokeFunction",
            "Resource": "arn:aws:lambda:us-east-1:111122223333:function:ServiceCatalogTerraformOSParameterParser",
            "Condition": {
                "StringLike": {
                    "aws:SourceAccount": [
                        "000000000000",
                        "111111111111"
                    ]
                }
            }
        }
    ]
}
```

------

## Confused Deputy context keys on the endpoints to restrict access for `sqs:SendMessage` operations
<a name="confused-deputy-TRFM-sqs"></a>

The provisioning operation intake Amazon SQS queues created by AWS Service Catalog-provided engines have an access policy that grants cross-account `sqs:SendMessage` (and associated KMS) permissions only to the AWS Service Catalog service principal:

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "Enable AWS Service Catalog to send messages to the queue",
            "Effect": "Allow",
            "Principal": {
                "Service": "servicecatalog.amazonaws.com"
            },
            "Action": "sqs:SendMessage",
            "Resource": [
                "arn:aws:sqs:us-east-1:111122223333:ServiceCatalogTerraformOSProvisionOperationQueue"
            ]
        },
        {
            "Sid": "Enable AWS Service Catalog encryption/decryption permissions when sending message to queue",
            "Effect": "Allow",
            "Principal": {
                "Service": "servicecatalog.amazonaws.com"
            },
            "Action": [
                "kms:DescribeKey",
                "kms:Decrypt",
                "kms:ReEncryptFrom",
                "kms:ReEncryptTo",
                "kms:GenerateDataKey"
            ],
            "Resource": "arn:aws:kms:us-east-1:111122223333:key/key_id"
        }
    ]
}
```

------

This should be the only permission necessary in order for the integration with AWS Service Catalog to function properly. However, you can constrain this further using the `aws:SourceAccount` [ Confused Deputy](https://docs.aws.amazon.com/IAM/latest/UserGuide/confused-deputy) context key. When AWS Service Catalog sends messages to these queues, AWS Service Catalog populates the keys with the provisioning account's ID. This is helpful when you intend to distribute products via portfolio sharing and want to ensure that only specific accounts are using your engine.

For example, you can restrict your engine to only allow requests that originate from 000000000000 and 111111111111 using the condition shown below:

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "Enable AWS Service Catalog to send messages to the queue",
            "Effect": "Allow",
            "Principal": {
                "Service": "servicecatalog.amazonaws.com"
            },
            "Action": "sqs:SendMessage",
            "Resource": [
                "arn:aws:sqs:us-east-1:111122223333:ServiceCatalogTerraformOSProvisionOperationQueue"
            ],
            "Condition": {
                "StringLike": {
                    "aws:SourceAccount": [
                        "000000000000",
                        "111111111111"
                    ]
                }
            }
        },
        {
            "Sid": "Enable AWS Service Catalog encryption/decryption permissions when sending message to queue",
            "Effect": "Allow",
            "Principal": {
                "Service": "servicecatalog.amazonaws.com"
            },
            "Action": [
                "kms:DescribeKey",
                "kms:Decrypt",
                "kms:ReEncryptFrom",
                "kms:ReEncryptTo",
                "kms:GenerateDataKey"
            ],
            "Resource": "arn:aws:kms:us-east-1:111122223333:key/key_id"
        }
    ]
}
```

------