Пример #1
0
    private static async Task <string> GetStorageAccountKey(string resourceGroupName, string accountName, int keyIndex)
    {
        var accountKeys = await ListStorageAccountKeys.InvokeAsync(new ListStorageAccountKeysArgs
        {
            ResourceGroupName = resourceGroupName,
            AccountName       = accountName
        });

        return(accountKeys.Keys[keyIndex].Value);
    }
        static async Task <string> GetStorageAccountPrimaryKey(string resourceGroupName, string accountName)
        {
            var accountKeys = await ListStorageAccountKeys.InvokeAsync(new ListStorageAccountKeysArgs
            {
                ResourceGroupName = resourceGroupName,
                AccountName       = accountName
            });

            return(accountKeys.Keys[0].Value);
        }
Пример #3
0
    private static Output <string> GetConnectionString(Input <string> resourceGroupName, Input <string> accountName)
    {
        // Retrieve the primary storage account key.
        var storageAccountKeys = ListStorageAccountKeys.Invoke(new ListStorageAccountKeysInvokeArgs
        {
            ResourceGroupName = resourceGroupName,
            AccountName       = accountName
        });

        return(storageAccountKeys.Apply(keys =>
        {
            var primaryStorageKey = keys.Keys[0].Value;

            // Build the connection string to the storage account.
            return Output.Format($"DefaultEndpointsProtocol=https;AccountName={accountName};AccountKey={primaryStorageKey}");
        }));
    }
Пример #4
0
    private static Output <string> GetConnectionString(Input <string> resourceGroupName, Input <string> accountName)
    {
        var storageAccountKeys = Output.All(resourceGroupName, accountName).Apply(t => ListStorageAccountKeys.InvokeAsync(new ListStorageAccountKeysArgs {
            ResourceGroupName = t[0], AccountName = t[1]
        }));

        return(storageAccountKeys.Apply(keys => Output.Format($"DefaultEndpointsProtocol=https;AccountName={accountName};AccountKey={keys.Keys[0].Value};EndpointSuffix=core.windows.net")));
    }
Пример #5
0
    public AppStack()
    {
        var config = new Config();

        var resourceGroup = new ResourceGroup("rotatesecretoneset-rg");

        var sqlAdminLogin    = config.Get("sqlAdminLogin") ?? "sqlAdmin";
        var sqlAdminPassword = new RandomUuid("sqlPassword").Result;
        var sqlServer        = new Server("sqlServer", new ServerArgs
        {
            AdministratorLogin         = sqlAdminLogin,
            AdministratorLoginPassword = sqlAdminPassword,
            ResourceGroupName          = resourceGroup.Name,
            Version = "12.0",
        });

        new FirewallRule("AllowAllWindowsAzureIps",
                         new FirewallRuleArgs
        {
            ServerName        = sqlServer.Name,
            ResourceGroupName = resourceGroup.Name,
            StartIpAddress    = "0.0.0.0",
            EndIpAddress      = "0.0.0.0",
        });

        var clientConfig = Output.Create(GetClientConfig.InvokeAsync());
        var tenantId     = clientConfig.Apply(c => c.TenantId);

        var storageAccount = new StorageAccount("storageaccount", new StorageAccountArgs
        {
            Kind = "Storage",
            ResourceGroupName = resourceGroup.Name,
            Sku = new Storage.Inputs.SkuArgs
            {
                Name = "Standard_LRS"
            },
        });

        var appInsights = new Component("appInsights", new ComponentArgs
        {
            RequestSource     = "IbizaWebAppExtensionCreate",
            ResourceGroupName = resourceGroup.Name,
            ApplicationType   = "web",
            Kind = "web",
            Tags =
            {
                //{ "[concat('hidden-link:', resourceId('Microsoft.Web/sites', parameters('functionAppName')))]", "Resource" },
            },
        });

        var secretName = config.Get("secretName") ?? "sqlPassword";
        var appService = new AppServicePlan("functionApp-appService", new AppServicePlanArgs
        {
            ResourceGroupName = resourceGroup.Name,
            Sku = new SkuDescriptionArgs
            {
                Name = "Y1",
                Tier = "Dynamic",
            },
        });

        var storageKey = Output.Tuple(resourceGroup.Name, storageAccount.Name).Apply(v =>
        {
            var task = ListStorageAccountKeys.InvokeAsync(new ListStorageAccountKeysArgs {
                AccountName = v.Item2, ResourceGroupName = v.Item1
            });
            return(Output.Create(task).Apply(t => t.Keys[0].Value));
        });

        var functionApp = new WebApp("functionApp", new WebAppArgs
        {
            Kind = "functionapp",
            ResourceGroupName = resourceGroup.Name,
            ServerFarmId      = appService.Id,
            Identity          = new ManagedServiceIdentityArgs {
                Type = ManagedServiceIdentityType.SystemAssigned
            },
            SiteConfig = new SiteConfigArgs
            {
                AppSettings =
                {
                    new NameValuePairArgs
                    {
                        Name  = "AzureWebJobsStorage",
                        Value = Output.Format($"DefaultEndpointsProtocol=https;AccountName={storageAccount.Name};AccountKey={storageKey}"),
                    },
                    new NameValuePairArgs
                    {
                        Name  = "FUNCTIONS_EXTENSION_VERSION",
                        Value = "~3",
                    },
                    new NameValuePairArgs
                    {
                        Name  = "FUNCTIONS_WORKER_RUNTIME",
                        Value = "dotnet",
                    },
                    new NameValuePairArgs
                    {
                        Name  = "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING",
                        Value = Output.Format($"DefaultEndpointsProtocol=https;AccountName={storageAccount.Name};EndpointSuffix=core.windows.net;AccountKey={storageKey}"),
                    },
                    new NameValuePairArgs
                    {
                        Name  = "WEBSITE_NODE_DEFAULT_VERSION",
                        Value = "~10",
                    },
                    new NameValuePairArgs
                    {
                        Name  = "APPINSIGHTS_INSTRUMENTATIONKEY",
                        Value = appInsights.InstrumentationKey,
                    },
                },
            },
        });

        var functionAppSourceControl = new WebAppSourceControl("functionApp-sourceControl",
                                                               new WebAppSourceControlArgs
        {
            Name = functionApp.Name,
            IsManualIntegration = true,
            Branch            = "main",
            RepoUrl           = config.Get("functionAppRepoURL") ?? "https://github.com/Azure-Samples/KeyVault-Rotation-SQLPassword-Csharp.git",
            ResourceGroupName = resourceGroup.Name,
        });

        var webAppAppService = new AppServicePlan("webApp-appService", new AppServicePlanArgs
        {
            ResourceGroupName = resourceGroup.Name,
            Sku = new SkuDescriptionArgs
            {
                Name = "F1",
            },
        });

        var webApp = new WebApp("webApp", new WebAppArgs
        {
            Kind = "app",
            ResourceGroupName = resourceGroup.Name,
            ServerFarmId      = webAppAppService.Id,
            Identity          = new ManagedServiceIdentityArgs {
                Type = ManagedServiceIdentityType.SystemAssigned
            },
        });

        var keyVault = new Vault("keyVault", new VaultArgs
        {
            Properties = new VaultPropertiesArgs
            {
                AccessPolicies =
                {
                    new AccessPolicyEntryArgs
                    {
                        TenantId    = tenantId,
                        ObjectId    = functionApp.Identity.Apply(i => i !.PrincipalId),
                        Permissions = new PermissionsArgs
                        {
                            Secrets ={ "get",               "list", "set" },
                        },
                    },
    public FunctionApp(string name, FunctionAppArgs args, ComponentResourceOptions?options = null)
        : base("infra:functionapp", name, options)
    {
        var opts = new CustomResourceOptions {
            Parent = this
        };

        var appStorage = new StorageAccount(name.Replace("-", ""), new StorageAccountArgs
        {
            ResourceGroupName = args.ResourceGroupName,
            Sku = new SkuArgs
            {
                Name = SkuName.Standard_LRS,
            },
            Kind = Pulumi.AzureNative.Storage.Kind.StorageV2,
        });

        var appServicePlan = new AppServicePlan(name, new AppServicePlanArgs
        {
            ResourceGroupName = args.ResourceGroupName,
            Location          = args.Location,
            Kind = "FunctionApp",
            Sku  = new SkuDescriptionArgs
            {
                Tier = "Dynamic",
                Name = "Y1"
            }
        }, opts);

        var container = new BlobContainer("code-container", new BlobContainerArgs
        {
            AccountName       = appStorage.Name,
            PublicAccess      = PublicAccess.None,
            ResourceGroupName = args.ResourceGroupName,
        });

        var blob = new Blob($"zip-{DateTime.UtcNow:ddMMyyyyhhmmss}", new BlobArgs
        {
            AccountName       = appStorage.Name,
            ContainerName     = container.Name,
            ResourceGroupName = args.ResourceGroupName,
            Type   = BlobType.Block,
            Source = new FileArchive("../publish")
        });

        var appInsights = new Component("appInsights", new ComponentArgs
        {
            ApplicationType   = ApplicationType.Web,
            Kind              = "web",
            ResourceGroupName = args.ResourceGroupName,
        });

        var codeBlobUrl = SignedBlobReadUrl(blob, container, appStorage, args.ResourceGroupName);

        var accountKeys = Output.Tuple(args.ResourceGroupName, appStorage.Name)
                          .Apply(p => ListStorageAccountKeys.InvokeAsync(new ListStorageAccountKeysArgs
        {
            ResourceGroupName = p.Item1,
            AccountName       = p.Item2
        }));

        var storageConnectionString =
            Output.Format(
                $"DefaultEndpointsProtocol=https;AccountName={appStorage.Name};AccountKey={accountKeys.Apply(a => a.Keys[0].Value)}");

        var app = new WebApp(name, new WebAppArgs
        {
            Kind = "FunctionApp",
            ResourceGroupName = args.ResourceGroupName,
            ServerFarmId      = appServicePlan.Id,
            SiteConfig        = new SiteConfigArgs
            {
                AppSettings = new[]
                {
                    new NameValuePairArgs
                    {
                        Name  = "APPLICATIONINSIGHTS_CONNECTION_STRING",
                        Value = Output.Format($"InstrumentationKey={appInsights.InstrumentationKey}"),
                    },
                    new NameValuePairArgs
                    {
                        Name  = "FUNCTIONS_EXTENSION_VERSION",
                        Value = "~3"
                    },
                    new NameValuePairArgs
                    {
                        Name  = "FUNCTIONS_WORKER_RUNTIME",
                        Value = "dotnet-isolated"
                    },
                    new NameValuePairArgs {
                        Name  = "WEBSITE_RUN_FROM_PACKAGE",
                        Value = codeBlobUrl,
                    },
                    new NameValuePairArgs
                    {
                        Name  = "AzureWebJobsStorage",
                        Value = GetConnectionString(args.ResourceGroupName, appStorage.Name)
                    }
                }
            }
        });

        var slotConfigNames = new WebAppSlotConfigurationNames(name, new WebAppSlotConfigurationNamesArgs {
            Name = app.Name,
            ResourceGroupName = args.ResourceGroupName,
            AppSettingNames   = { "FUNCTIONS_WORKER_RUNTIME", "FUNCTIONS_EXTENSION_VERSION" }
        });

        var stagingSlot = new WebAppSlot($"{name}-slot", new WebAppSlotArgs()
        {
            Name = app.Name,
            Slot = "staging",
            ResourceGroupName = args.ResourceGroupName,
            SiteConfig        = new SiteConfigArgs
            {
                AppSettings = new[]
                {
                    new NameValuePairArgs
                    {
                        Name  = "WEBSITE_ADD_SITENAME_BINDINGS_IN_APPHOST_CONFIG",
                        Value = "1"
                    },
                    new NameValuePairArgs
                    {
                        Name  = "WEBSITE_SWAP_WARMUP_PING_PATH",
                        Value = "/helloworld"
                    }
                }
            },
        });

        this.AppName         = app.Name;
        this.AppId           = app.Id;
        this.DefaultHostname = app.DefaultHostName;
    }