Join EC2 Instance to AD domain via terraform - active-directory

I hope you can help me with my problem. I am trying to automatically let my ec2 instance joins an ad domain with my terraform script. Since Terraform does not support any "Domain join directory" option I wanted to try to create an SSM Document to let Systems Manager make that for me. Actually I got the following Code:
resource "aws_directory_service_directory" "ad" {
name = "active-directory-service.com"
password = "${var.ad-password}"
edition = "Standard"
size = "Small"
type = "MicrosoftAD"
vpc_settings {
vpc_id = "${aws_vpc.vpc.id}"
subnet_ids = ["${aws_subnet.ds-subnet.0.id}",
"${aws_subnet.ds-subnet.1.id}"
]
}
}
resource "aws_vpc_dhcp_options" "vpc-dhcp-options" {
domain_name = "${var.dir_domain_name}"
domain_name_servers = aws_directory_service_directory.ad.dns_ip_addresses
}
resource "aws_vpc_dhcp_options_association" "dns_resolver" {
vpc_id = aws_vpc.vpc.id
dhcp_options_id = aws_vpc_dhcp_options.vpc-dhcp-options.id
}
resource "aws_ssm_document" "ad-server-domain-join-document" {
name = "myapp_dir_default_doc"
document_type = "Command"
content = <<DOC
{
"schemaVersion": "1.0",
"description": "Join an instance to a domain",
"runtimeConfig": {
"aws:domainJoin": {
"properties": {
"directoryId": "${aws_directory_service_directory.ad.id}",
"directoryName": "${var.dir_domain_name}",
"directoryOU": "${var.dir_computer_ou}",
"dnsIpAddresses": [
"${aws_directory_service_directory.ad.dns_ip_addresses[0]}",
"${aws_directory_service_directory.ad.dns_ip_addresses[1]}"
}
}
}
}
DOC
}
resource "aws_ssm_association" "ad-server-association" {
name = "dir_default_doc"
instance_id = aws_instance.ec2-ad-instance.id
}
I get the following error message:
This value does not have any indices. Can someone please tell me how to fix this issue?

If the AMI you are using does not have SSM, this is how you do it:
user_data = <<EOF
<powershell>
Add-Computer -DomainName 'NAME_OF_THE_DOMAIN' -NewName 'NEW_NAME_OF_THE_MACHINE' -Credential (New-Object -TypeName PSCredential -ArgumentList "DOMAIN_USERNAME",(ConvertTo-SecureString -String 'DOMAIN_PASSWORD' -AsPlainText -Force)[0]) -Restart
</powershell>
EOF
Or, if you want to use SSM, using the new Terraform 12/13 syntax and the latest schema version, here is a ready to copy and paste snippet:
data "aws_directory_service_directory" "my_domain_controller" {
directory_id = "d-XXXXXXXXXXXXX"
}
resource "aws_ssm_document" "ad-join-domain" {
name = "ad-join-domain"
document_type = "Command"
content = jsonencode(
{
"schemaVersion" = "2.2"
"description" = "aws:domainJoin"
"mainSteps" = [
{
"action" = "aws:domainJoin",
"name" = "domainJoin",
"inputs" = {
"directoryId" : data.aws_directory_service_directory.my_domain_controller.id,
"directoryName" : data.aws_directory_service_directory.my_domain_controller.name
"dnsIpAddresses" : sort(data.aws_directory_service_directory.my_domain_controller.dns_ip_addresses)
}
}
]
}
)
}
resource "aws_ssm_association" "windows_server" {
name = aws_ssm_document.ad-join-domain.name
targets {
key = "InstanceIds"
values = ["i-XXXXXXXXXXXX"]
}
}
You will need to specify an instance profile when creating the ec2 instance which has the required permissions for this snippet to work.

As mentioned in the comment, reproducible examples will accelerate anyone's ability to help :)
I assumed terraform 0.12 is in use.
aws_directory_service_directory.ad.dns_ip_addresses is not a list, it is a set. Conceptually, this means it is unordered. As a result, access it like:
sort(aws_directory_service_directory.ad.dns_ip_addresses)[0]
The sort will order it and allow you to access it with an index. The following issue explains this, albeit in regards to attempting to verbosely use element to access https://github.com/hashicorp/terraform/issues/22392
The documentation for this resource calls it a list which is incorrect in practice it seems: https://www.terraform.io/docs/providers/aws/r/directory_service_directory.html

As per https://aws.amazon.com/blogs/security/how-to-configure-your-ec2-instances-to-automatically-join-a-microsoft-active-directory-domain/
dnsIpAddresses expects list in json format
"dnsIpAddresses": [
"198.51.100.1",
"198.51.100.2"
]
convert aws_directory_service_directory.ad.dns_ip_addresses to json format
"dnsIpAddresses": [ "${join("\", \"",aws_directory_service_directory.ad.dns_ip_addresses)}" ]

you can make the target on your SSM association to be a tag instead of using a specific instance, so any instance you are deploying and has the tag per se adjoin will join the domain
resource "aws_ssm_association" "windows_server" {
name = aws_ssm_document.ad-join-domain.name
targets {
key = "tag:adjoin"
values = ["true"]
}
}

I've tried following solution below, which was mentioned here - but unfortunately, the EC2s do not join the Active Directory in an automated way. I've to manually enter the domain and the dns.
Any idea what's wrong with that approach?
Thank you a lot in advance!
resource "aws_instance" "some-application" {
ami = "ami-05a60358d5cda31c5"
instance_type = "t2.micro"
security_groups = [aws_security_group.sg-license-server.id]
subnet_id = module.vpc.public_subnets[0]
key_name = aws_key_pair.pubkey.key_name
tags = {
"Name" = "Some-Application"
}
user_data = <<EOF
<powershell>
msiexec.exe /i https://awscli.amazonaws.com/AWSCLIV2.msi
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope LocalMachine
Add-Computer -DomainName '${aws_directory_service_directory.my_directory_service.name}' -NewName 'Some-Application' -Credential (New-Object -TypeName PSCredential -ArgumentList 'Administrator',(ConvertTo-SecureString -String '${aws_directory_service_directory.my_directory_service.password}' -AsPlainText -Force)[0]) -Restart
</powershell>
EOF
}
resource "aws_instance" "license-server" {
ami = "ami-05a60358d5cda31c5"
instance_type = "t2.micro"
security_groups = [aws_security_group.sg-license-server.id]
subnet_id = module.vpc.public_subnets[0]
key_name = aws_key_pair.pubkey.key_name
tags = {
"Name" = "License-Server"
}
user_data = <<EOF
<powershell>
msiexec.exe /i https://awscli.amazonaws.com/AWSCLIV2.msi
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope LocalMachine
Add-Computer -DomainName '${aws_directory_service_directory.my_directory_service.name}' -NewName 'License-Server' -Credential (New-Object -TypeName PSCredential -ArgumentList 'Administrator',(ConvertTo-SecureString -String '${aws_directory_service_directory.my_directory_service.password}' -AsPlainText -Force)[0]) -Restart
</powershell>
EOF
}
resource "aws_security_group" "sg-fsx" {
name = "SG-FSX"
vpc_id = module.vpc.vpc_id
ingress {
from_port = 53
to_port = 636
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 3268
to_port = 3269
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 9389
to_port = 9389
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 5985
to_port = 5985
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 88
to_port = 464
protocol = "udp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 5985
to_port = 5985
protocol = "udp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 49152
to_port = 65535
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "sg-fsx"
}
}
resource "aws_security_group" "sg-license-server" {
name = "SG-License-Server"
vpc_id = module.vpc.vpc_id
ingress {
from_port = 0
to_port = 6556
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 27000
to_port = 27000
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 49152
to_port = 65535
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "sg-license-server"
}
}
resource "aws_key_pair" "pubkey" {
key_name = "aws-cloud"
public_key = file("key/aws_instance.pub")
}
resource "aws_vpc_dhcp_options" "vpc-dhcp-options" {
domain_name = aws_directory_service_directory.my_directory_service.name
domain_name_servers = aws_directory_service_directory.my_directory_service.dns_ip_addresses
}
resource "aws_vpc_dhcp_options_association" "dns_resolver" {
vpc_id = module.vpc.vpc_id
dhcp_options_id = aws_vpc_dhcp_options.vpc-dhcp-options.id
}
resource "aws_fsx_windows_file_system" "example" {
active_directory_id = aws_directory_service_directory.my_directory_service.id
storage_capacity = 300
subnet_ids = [module.vpc.private_subnets[0]]
throughput_capacity = 1024
security_group_ids = [aws_security_group.sg-fsx.id]
}

Related

How to use terraform to enable Managed private endpoint on datafactory azure sql database linked service

I am trying to use terraform to create adf linked services however the terraform resource doesn't give the option to select an already existing managed private endpoint for the linked service to communicate over but when creating from the portal, this is possible. bellow is my code
resource "azurerm_data_factory" "process-adf" {
resource_group_name = module.resourcegroup.resource_group.name
location = module.resourcegroup.resource_group.location
name = "adf"
managed_virtual_network_enabled = true
public_network_enabled = false
tags = var.tags
identity {
type = "SystemAssigned"
}
}
resource "azurerm_data_factory_linked_service_azure_sql_database" "process-mssql-adf" {
name = "mssql-adf"
data_factory_id = azurerm_data_factory.process-adf.id
integration_runtime_name = azurerm_data_factory_integration_runtime_azure.adf.id
connection_string = "data source=servername;initial catalog=databasename;user id=admin;Password=password;integrated security=True;encrypt=True;connection timeout=30"
}
resource "azurerm_data_factory_managed_private_endpoint" "adf-msssql-pe" {
name = "adf"
data_factory_id = azurerm_data_factory.process-adf.id
target_resource_id = azurerm_mssql_server.process-control.id
subresource_name = "sqlServer"
}
resource "azurerm_data_factory_integration_runtime_azure" "adf" {
name = "adf"
data_factory_id = azurerm_data_factory.process-adf.id
location = module.resourcegroup.resource_group.location
virtual_network_enabled = true
}
how do i point the resource azurerm_data_factory_linked_service_azure_sql_database to the resource azurerm_data_factory_managed_private_endpoint ?

Basic SQL commands in Terraform

I am using Terraform to build an Azure DB and set the correct Azure AD Admin etc - all working well.
I now need to create
CREATE LOGIN [XXX-XXX] FROM EXTERNAL PROVIDER;
CREATE USER [XXX-XXX] FOR LOGIN [XXX-XXX];
ALTER ROLE db_datareader ADD MEMBER [XXX-XXX]
Any ideas if this is possible within Terraform - thinking its the easiest way as the user is already authorised to create the database.
Its not possible to directly run the commands that you have mentioned in the question but you can use Invoke-sqlcmd and authenticate with your AAD admin credentials and run the commands .
I tested the scenario with the below code :
provider "azurerm" {
features{}
}
data "azurerm_client_config" "current" {}
resource "azurerm_resource_group" "example" {
name = "example-resources"
location = "West Europe"
}
resource "azurerm_sql_server" "example" {
name = "ansumansqlserver"
resource_group_name = azurerm_resource_group.example.name
location = azurerm_resource_group.example.location
version = "12.0"
administrator_login = "admin"
administrator_login_password = "password"
tags = {
environment = "production"
}
}
resource "azurerm_storage_account" "example" {
name = "ansumansacc"
resource_group_name = azurerm_resource_group.example.name
location = azurerm_resource_group.example.location
account_tier = "Standard"
account_replication_type = "LRS"
}
resource "azurerm_sql_database" "example" {
name = "ansumansqldatabase"
resource_group_name = azurerm_resource_group.example.name
location = azurerm_resource_group.example.location
server_name = azurerm_sql_server.example.name
extended_auditing_policy {
storage_endpoint = azurerm_storage_account.example.primary_blob_endpoint
storage_account_access_key = azurerm_storage_account.example.primary_access_key
storage_account_access_key_is_secondary = true
retention_in_days = 6
}
tags = {
environment = "production"
}
}
resource "azurerm_sql_active_directory_administrator" "example" {
server_name = azurerm_sql_server.example.name
resource_group_name = azurerm_resource_group.example.name
login = "sqladmin"
tenant_id = data.azurerm_client_config.current.tenant_id
object_id = data.azurerm_client_config.current.object_id
}
## creating Login in master database first
resource "null_resource" "master"{
provisioner "local-exec"{
command = <<EOT
Set-AzContext -SubscriptionId "<SubscriptionID>"
$token = (Get-AzAccessToken -ResourceUrl https://database.windows.net).Token
Invoke-SqlCmd -ServerInstance ${azurerm_sql_server.example.fully_qualified_domain_name} -Database master -AccessToken $token -Query "CREATE LOGIN [user#tenantname.onmicrosoft.com] FROM EXTERNAL PROVIDER"
EOT
interpreter = ["PowerShell", "-Command"]
}
depends_on=[
azurerm_sql_active_directory_administrator.example,
azurerm_sql_database.example
]
}
## creating the user from the login created in master and assigning role
resource "null_resource" "database"{
provisioner "local-exec"{
command = <<EOT
Set-AzContext -SubscriptionId "<SubscriptionID>"
$token = (Get-AzAccessToken -ResourceUrl https://database.windows.net).Token
$query= #'
CREATE USER [AJAY] FOR LOGIN [user#tenantname.onmicrosoft.com];
GO
ALTER ROLE [db_datareader] ADD MEMBER [AJAY];
GO
'#
Invoke-SqlCmd -ServerInstance ${azurerm_sql_server.example.fully_qualified_domain_name} -Database ${azurerm_sql_database.example.name} -AccessToken $token -Query $query
EOT
interpreter = ["PowerShell", "-Command"]
}
depends_on = [
null_resource.master
]
}
Output:
Note: Please make sure to have Azure Powershell Module and SQLServer Powershell Module.

Dynamics 365 Business Central terraform scopes

I am trying to create a terraform script that will register an application in Azure AD.
I have been successful when generating a script that only reads from Microsoft Graph scopes. But I am having trouble figuring out what the equivalent of those scopes are in Business Central (Cloud version).
For Microsoft Graph I have these permissions:
email
offline_access
openid
profile
Financials.ReadWrite.All
User.Read
And I read them like this in terraform:
provider "azuread" {
# Whilst version is optional, we /strongly recommend/ using it to pin the version of the Provider being used
version = "~> 0.10"
subscription_id = var.subscription_id
}
data "azuread_service_principal" "graph-api" {
display_name = "Microsoft Graph"
}
locals {
MAIL_PERMISSION = "${matchkeys(data.azuread_service_principal.graph-api.oauth2_permissions.*.id, data.azuread_service_principal.graph-api.oauth2_permissions.*.value, list("email"))[0]}"
USER_READ_PERMISSION = "${matchkeys(data.azuread_service_principal.graph-api.oauth2_permissions.*.id, data.azuread_service_principal.graph-api.oauth2_permissions.*.value, list("User.Read"))[0]}"
FINANCIALS_READ_WRITE_PERMISSION = "${matchkeys(data.azuread_service_principal.graph-api.oauth2_permissions.*.id, data.azuread_service_principal.graph-api.oauth2_permissions.*.value, list("Financials.ReadWrite.All"))[0]}"
OFFLINE_PERMISSION = "${matchkeys(data.azuread_service_principal.graph-api.oauth2_permissions.*.id, data.azuread_service_principal.graph-api.oauth2_permissions.*.value, list("offline_access"))[0]}"
OPENID_PERMISSION = "${matchkeys(data.azuread_service_principal.graph-api.oauth2_permissions.*.id, data.azuread_service_principal.graph-api.oauth2_permissions.*.value, list("openid"))[0]}"
PROFILE_PERMISSION = "${matchkeys(data.azuread_service_principal.graph-api.oauth2_permissions.*.id, data.azuread_service_principal.graph-api.oauth2_permissions.*.value, list("profile"))[0]}"
}
Which seems to be working fine. I am just struggling to find the similar way of doing this for the Dynamics 365 Business Central
I am interested in these:
app_access
Financials.ReadWrite.All
user_impersonation
Does anybody know what that endpoint might look like? The documentation is very limited.
EDIT:
This is the final script for anybody interested in setting up an Business Central application registration
variable "subscription_id" {
type = string
}
variable "app_name" {
type = string
}
variable "app_homepage" {
type = string
}
variable "app_reply_urls" {
type = list(string)
}
provider "azuread" {
# Whilst version is optional, we /strongly recommend/ using it to pin the version of the Provider being used
version = "~> 0.10"
subscription_id = var.subscription_id
}
data "azuread_service_principal" "graph-api" {
display_name = "Microsoft Graph"
}
data "azuread_service_principal" "d365bc" {
display_name = "Dynamics 365 Business Central"
}
locals {
APP_ACCESS_PERMISSION = "${matchkeys(data.azuread_service_principal.d365bc.app_roles.*.id, data.azuread_service_principal.d365bc.app_roles.*.value, list("app_access"))[0]}"
USER_IMPERSONATION_PERMISSION = "${matchkeys(data.azuread_service_principal.d365bc.oauth2_permissions.*.id, data.azuread_service_principal.d365bc.oauth2_permissions.*.value, list("user_impersonation"))[0]}"
BC_FINANCIALS_READ_WRITE_PERMISSION = "${matchkeys(data.azuread_service_principal.d365bc.oauth2_permissions.*.id, data.azuread_service_principal.d365bc.oauth2_permissions.*.value, list("Financials.ReadWrite.All"))[0]}"
GRAPH_FINANCIAL_READ_WRITE_PERMISSION = "${matchkeys(data.azuread_service_principal.graph-api.oauth2_permissions.*.id, data.azuread_service_principal.graph-api.oauth2_permissions.*.value, list("Financials.ReadWrite.All"))[0]}"
MAIL_READ_PERMISSION = "${matchkeys(data.azuread_service_principal.graph-api.oauth2_permissions.*.id, data.azuread_service_principal.graph-api.oauth2_permissions.*.value, list("User.Read"))[0]}"
MAIL_PERMISSION = "${matchkeys(data.azuread_service_principal.graph-api.oauth2_permissions.*.id, data.azuread_service_principal.graph-api.oauth2_permissions.*.value, list("email"))[0]}"
OFFLINE_PERMISSION = "${matchkeys(data.azuread_service_principal.graph-api.oauth2_permissions.*.id, data.azuread_service_principal.graph-api.oauth2_permissions.*.value, list("offline_access"))[0]}"
OPENID_PERMISSION = "${matchkeys(data.azuread_service_principal.graph-api.oauth2_permissions.*.id, data.azuread_service_principal.graph-api.oauth2_permissions.*.value, list("openid"))[0]}"
PROFILE_PERMISSION = "${matchkeys(data.azuread_service_principal.graph-api.oauth2_permissions.*.id, data.azuread_service_principal.graph-api.oauth2_permissions.*.value, list("profile"))[0]}"
}
resource "azuread_application" "businessCentral" {
name = var.app_name
homepage = var.app_homepage
identifier_uris = []
reply_urls = var.app_reply_urls
available_to_other_tenants = true
type = "webapp/api"
required_resource_access {
resource_app_id = data.azuread_service_principal.graph-api.application_id
resource_access {
id = local.GRAPH_FINANCIAL_READ_WRITE_PERMISSION
type = "Scope"
}
resource_access {
id = local.MAIL_PERMISSION
type = "Scope"
}
resource_access {
id = local.MAIL_READ_PERMISSION
type = "Scope"
}
resource_access {
id = local.OFFLINE_PERMISSION
type = "Scope"
}
resource_access {
id = local.OPENID_PERMISSION
type = "Scope"
}
resource_access {
id = local.PROFILE_PERMISSION
type = "Scope"
}
}
required_resource_access {
resource_app_id = data.azuread_service_principal.d365bc.application_id
resource_access {
id = local.APP_ACCESS_PERMISSION
type = "Role"
}
resource_access {
id = local.USER_IMPERSONATION_PERMISSION
type = "Scope"
}
resource_access {
id = local.BC_FINANCIALS_READ_WRITE_PERMISSION
type = "Scope"
}
}
app_role {
allowed_member_types = [
"Application"
]
description = "Admins can manage roles and perform all task actions"
display_name = "Admin"
is_enabled = true
value = "Admin"
}
}
One thing to note is that the app_access is Role and the rest of the API permissions are Scope.
You can call the above terraform with:
terraform plan -var="subscription_id={your_scription_id}" -var='app_reply_urls={your_urls_array}' -var="app_name={your_app_name}" -var="app_homepage={your_app_homepage}"
Try this:
provider "azuread" {
# Whilst version is optional, we /strongly recommend/ using it to pin the version of the Provider being used
version = "=0.10.0"
}
data "azuread_service_principal" "d365bc" {
application_id = "996def3d-b36c-4153-8607-a6fd3c01b89f"
}
locals {
APP_ACCESS_PERMISSION = "${matchkeys(data.azuread_service_principal.d365bc.app_roles.*.id, data.azuread_service_principal.d365bc.app_roles.*.value, list("app_access"))[0]}"
USER_IMPERSONATION_PERMISSION = "${matchkeys(data.azuread_service_principal.d365bc.oauth2_permissions.*.id, data.azuread_service_principal.d365bc.oauth2_permissions.*.value, list("user_impersonation"))[0]}"
FINANCIALS_READ_WRITE_PERMISSION = "${matchkeys(data.azuread_service_principal.d365bc.oauth2_permissions.*.id, data.azuread_service_principal.d365bc.oauth2_permissions.*.value, list("Financials.ReadWrite.All"))[0]}"
}
996def3d-b36c-4153-8607-a6fd3c01b89f is the client id of Microsoft Dynamics 365 BC service principal.
app_access is app permission so we need to use "app_roles" rather than "oauth2_permissions" here.

Create database schema with terraform

I created RDS instance using aws_db_instance (main.tf):
resource "aws_db_instance" "default" {
identifier = "${module.config.database["db_inst_name"]}"
allocated_storage = 20
storage_type = "gp2"
engine = "mysql"
engine_version = "5.7"
instance_class = "db.t3.micro"
name = "${module.config.database["db_name_prefix"]}${terraform.workspace}"
username = "${module.config.database["db_username"]}"
password = "${module.config.database["db_password"]}"
parameter_group_name = "default.mysql5.7"
skip_final_snapshot = true
}
Can I also create database schemas from file schema.sql with terraform apply?
$ tree -L 1
.
├── main.tf
└── schema.sql
You can use a provisioner (https://www.terraform.io/docs/provisioners/index.html) for that:
resource "aws_db_instance" "default" {
identifier = module.config.database["db_inst_name"]
allocated_storage = 20
storage_type = "gp2"
engine = "mysql"
engine_version = "5.7"
instance_class = "db.t3.micro"
name = "${module.config.database["db_name_prefix"]}${terraform.workspace}"
username = module.config.database["db_username"]
password = module.config.database["db_password"]
parameter_group_name = "default.mysql5.7"
skip_final_snapshot = true
provisioner "local-exec" {
command = "mysql --host=${self.address} --port=${self.port} --user=${self.username} --password=${self.password} < ./schema.sql"
}
}
#Apply scheme by using bastion host
resource "aws_db_instance" "default_bastion" {
identifier = module.config.database["db_inst_name"]
allocated_storage = 20
storage_type = "gp2"
engine = "mysql"
engine_version = "5.7"
instance_class = "db.t3.micro"
name = "${module.config.database["db_name_prefix"]}${terraform.workspace}"
username = module.config.database["db_username"]
password = module.config.database["db_password"]
parameter_group_name = "default.mysql5.7"
skip_final_snapshot = true
provisioner "file" {
connection {
user = "ec2-user"
host = "bastion.example.com"
private_key = file("~/.ssh/ec2_cert.pem")
}
source = "./schema.sql"
destination = "~"
}
provisioner "remote-exec" {
connection {
user = "ec2-user"
host = "bastion.example.com"
private_key = file("~/.ssh/ec2_cert.pem")
}
command = "mysql --host=${self.address} --port=${self.port} --user=${self.username} --password=${self.password} < ~/schema.sql"
}
}
mysql client needs to be installed on your device.
If you don't have direct access to your DB, there is also a remote-exec provisioner, where you can use a bastion host (transfer file to remote place with file provisioner first).
If your schema is not to complex, you could also use the MySQL provider of terraform:
https://www.terraform.io/docs/providers/mysql/index.html

How can i establish rpc properties with the datasource type DB in Corda community edition?

To establish an RPC connection in the community edition we need to specify the rpc username, password and permissions but when we are integrating external database like MySQL and change the datasource type from INMEMORY to "DB" it does not allows to give user properties.
these are the settings I am using in my node.conf
security = {
authService = {
dataSource = {
type = "DB"
passwordEncryption = "SHIRO_1_CRYPT"
connection = {
jdbcUrl = "jdbc:mysql://localhost:3306"
username = "root"
password = "password"
driverClassName = "com.mysql.jdbc.Driver"
}
}
options = {
cache = {
expireAfterSecs = 120
maxEntries = 10000
}
}
}
Maybe I didn't understand your question, but database setup in node.conf is separate from RPC user setup in node.conf:
Database (PostGres in my case)
extraConfig = [
'dataSourceProperties.dataSourceClassName' : 'org.postgresql.ds.PGSimpleDataSource',
'dataSourceProperties.dataSource.url' : 'jdbc:postgresql://localhost:5432/postgres',
'dataSourceProperties.dataSource.user' : 'db_user',
'dataSourceProperties.dataSource.password' : 'db_user_password',
'database.transactionIsolationLevel' : 'READ_COMMITTED',
'database.initialiseSchema' : 'true'
]
RPC User
rpcUsers = [[ user: "rpc_user", "password": "rpc_user_password", "permissions": ["ALL"]]]
Ok, I'm adding my node's node.config (it's part of Corda TestNet, and it's deployed on Google Cloud):
baseDirectory = "."
compatibilityZoneURL = "https://netmap.testnet.r3.com"
emailAddress = "xxx"
jarDirs = [ "plugins", "cordapps" ]
sshd { port = 2222 }
myLegalName = "OU=xxx, O=TESTNET_xxx, L=London, C=GB"
keyStorePassword = "xxx"
trustStorePassword = "xxx"
crlCheckSoftFail = true
database = {
transactionIsolationLevel = "READ_COMMITTED"
initialiseSchema = "true"
}
dataSourceProperties {
dataSourceClassName = "org.postgresql.ds.PGSimpleDataSource"
dataSource.url = "jdbc:postgresql://xxx:xxx/postgres"
dataSource.user = xxx
dataSource.password = xxx
}
p2pAddress = "xxx:xxx"
rpcSettings {
useSsl = false
standAloneBroker = false
address = "0.0.0.0:xxx"
adminAddress = "0.0.0.0:xxx"
}
rpcUsers = [
{ username=cordazoneservice, password=xxx, permissions=[ ALL ] }
]
devMode = false
cordappSignerKeyFingerprintBlacklist = []
useTestClock = false

Resources