/// <summary>
        /// Writes the module blocks for any modules this module refers to.
        /// </summary>
        /// <returns>Task to await.</returns>
        public async Task WriteModuleBlocksAsync()
        {
            var modulesFile = Path.Combine(this.ModuleDirectory, TerraformExporterConstants.ModulesFile);

            if (File.Exists(modulesFile))
            {
                // In case we removed all pre-existing submodule references
                File.Delete(modulesFile);
            }

            if (!this.NestedModules.Any())
            {
                return;
            }

            using (var fs = AsyncFileHelpers.OpenWriteAsync(modulesFile))
                using (var writer = new StreamWriter(fs, AsyncFileHelpers.DefaultEncoding))
                {
                    foreach (var module in this.NestedModules)
                    {
                        var sb = new StringBuilder().AppendLine($"module \"{module.Name}\" {{").AppendLine(
                            $"  source = \"./{module.Settings.ModuleDirectory.Replace('\\', '/')}\"");

                        if (module.IsImported)
                        {
                            // We can only emit module arguments once the module has been imported and
                            // corresponding "variable" declarations are visible to Terraform command.
                            foreach (var input in module.Inputs.Where(i => !(i.IsDataSource || i is PseudoParameterInput)))
                            {
                                sb.AppendLine($"  {input.GenerateVariableAssignment()}");
                            }
                        }

                        sb.AppendLine("}");

                        await writer.WriteLineAsync(sb.ToString());
                    }
                }
        }
示例#2
0
        /// <summary>
        /// Recursively process nested stacks.
        /// </summary>
        /// <param name="settings">The settings.</param>
        /// <param name="warnings">The warnings.</param>
        /// <returns>Module being processed.</returns>
        private static async Task <ModuleInfo> ProcessChildModule(
            ITerraformExportSettings settings,
            IList <string> warnings)
        {
            var childModules = new List <ModuleInfo>();

            foreach (var child in settings.Resources.Where(
                         r => r.ResourceType == TerraformExporterConstants.AwsCloudFormationStack))
            {
                var logicalId = child.LogicalResourceId;
                var stackName = GetStackName(child.StackResource.PhysicalResourceId);
                var stackData = await StackHelper.ReadStackAsync(
                    settings.CloudFormationClient,
                    stackName,
                    new Dictionary <string, object>());

                var childModuleSettings = settings.CopyWith(
                    stackData.Template,
                    stackData.Resources,
                    stackData.Outputs,
                    stackName,
                    Path.Combine("modules", stackName),
                    logicalId);

                childModules.Add(await ProcessChildModule(childModuleSettings, warnings));
            }

            var workingDirectory = Path.Combine(settings.WorkspaceDirectory, settings.ModuleDirectory);

            if (!Directory.Exists(workingDirectory))
            {
                Directory.CreateDirectory(workingDirectory);
            }

            settings.Logger.LogInformation($"Processing stack {settings.StackName}...");
            var scriptFile = Path.Combine(workingDirectory, TerraformExporterConstants.MainScriptFile);

            ModuleInfo module;

            using (var fs = settings.IsRootModule ? AsyncFileHelpers.OpenAppendAsync(scriptFile) : AsyncFileHelpers.OpenWriteAsync(scriptFile))
                using (var writer = new StreamWriter(fs, AsyncFileHelpers.DefaultEncoding))
                {
                    var thisModuleSettings = settings.CopyWith(
                        settings.Template,
                        settings.Resources.Where(r => r.ResourceType != TerraformExporterConstants.AwsCloudFormationStack),
                        null,
                        settings.StackName,
                        settings.IsRootModule ? "." : settings.ModuleDirectory,
                        settings.LogicalId);

                    module = new ModuleInfo(
                        thisModuleSettings,
                        childModules,
                        new InputVariableProcessor(thisModuleSettings, warnings).ProcessInputs(),
                        thisModuleSettings.CloudFormationOutputs);

                    await module.ProcessResources(writer, warnings);
                }

            await module.WriteModuleBlocksAsync();

            return(module);
        }