コード例 #1
0
    private Pulumi.AzureNative.KeyVault.Vault CreateVault(string resourceGroupName, Config config,
                                                          Pulumi.AzureNative.ManagedIdentity.UserAssignedIdentity reader)
    {
        var kpiDevelopmentVault = new Pulumi.AzureNative.KeyVault.Vault("kpivault",
                                                                        new Pulumi.AzureNative.KeyVault.VaultArgs
        {
            Properties = new VaultPropertiesArgs
            {
                AccessPolicies =
                {
                    CreateAccessPolicy(reader.PrincipalId, config)
                },
                Sku = new Pulumi.AzureNative.KeyVault.Inputs.SkuArgs
                {
                    Family = "A",
                    Name   = Pulumi.AzureNative.KeyVault.SkuName.Standard
                },
                SoftDeleteRetentionInDays = 90,
                TenantId = config.Require("azureTenantId")
            },
            ResourceGroupName = resourceGroupName,
            Tags =
            {
                { "environment", "dev"        },
                { "product",     "kpi-system" }
            }
        });

        return(kpiDevelopmentVault);
    }
コード例 #2
0
    public KpiAzureFunctionStack()
    {
        var config = new Config();

        var resourceGroupName = config.Require("resourceGroupName");
        var appServicePlan    = new Pulumi.AzureNative.Web.AppServicePlan("kpi-linux-asp",
                                                                          new Pulumi.AzureNative.Web.AppServicePlanArgs
        {
            Kind = "functionapp",
            ResourceGroupName = resourceGroupName,
            Sku = new SkuDescriptionArgs
            {
                Name = "Y1",
                Tier = "Dynamic"
            },
            Tags =
            {
                { "environment", "dev"        },
                { "product",     "kpi-system" }
            }
        });

        // var storageAccount = new Pulumi.AzureNative.Storage.StorageAccount("kpistrg", new Pulumi.AzureNative.Storage.StorageAccountArgs
        // {
        //     Kind = Pulumi.AzureNative.Storage.Kind.StorageV2,
        //     ResourceGroupName = resourceGroupName,
        //     Sku = new Pulumi.AzureNative.Storage.Inputs.SkuArgs
        //     {
        //         Name = "Standard_LRS",
        //     },
        //     Tags =
        //     {
        //         { "environment", "dev" },
        //         { "product", "kpi-system" },
        //     },
        // });

        var storageAccount = new Pulumi.Azure.Storage.Account("kpistrg", new Pulumi.Azure.Storage.AccountArgs
        {
            ResourceGroupName      = resourceGroupName,
            AccountReplicationType = "LRS",
            AccountTier            = "Standard",
            AccountKind            = "StorageV2"
        });

        var container = new BlobContainer("zips-container", new BlobContainerArgs
        {
            AccountName       = storageAccount.Name,
            PublicAccess      = PublicAccess.None,
            ResourceGroupName = resourceGroupName
        });

        var blob = new Blob("myfunctions", new BlobArgs
        {
            AccountName       = storageAccount.Name,
            ContainerName     = container.Name,
            ResourceGroupName = resourceGroupName,
            Source            = new FileArchive(FunctionAppPublishFolder),
            Type = BlobType.Block
        });

        var codeBlobUrl = SignedBlobReadUrl(blob, container, storageAccount.Name, resourceGroupName);

        // Application insights
        var appInsights = new Component("appInsights", new ComponentArgs
        {
            ApplicationType   = ApplicationType.Web,
            Kind              = "web",
            ResourceGroupName = resourceGroupName
        });

        var userAssignedIdentity = new Pulumi.AzureNative.ManagedIdentity.UserAssignedIdentity("kpi-identity",
                                                                                               new Pulumi.AzureNative.ManagedIdentity.UserAssignedIdentityArgs
        {
            ResourceGroupName = resourceGroupName
        });

        var vault = CreateVault(resourceGroupName, config, userAssignedIdentity);

        /*
         * Create relevant Vault Secrets.
         *
         * N.B.: we use these to make the secrets unreadable for users who have read-access
         * to the Azure Function itself, but not the vault.
         */
        var influxDbTokenSecret = CreateSecret("InfluxDbToken", config.RequireSecret("InfluxDb.Token"), vault,
                                               resourceGroupName);
        var mailChimpTokenSecret = CreateSecret("MailchimpApiKey", config.RequireSecret("Mailchimp.ApiKey"), vault,
                                                resourceGroupName);
        var googleAnalyticsKeySecret = CreateSecret("GoogleAnalyticsKey", config.RequireSecret("GoogleAnalytics.Key"),
                                                    vault, resourceGroupName);

        var kpiCollector = new Pulumi.AzureNative.Web.WebApp("kpi-collector", new Pulumi.AzureNative.Web.WebAppArgs
        {
            Kind = "functionapp,linux",
            ResourceGroupName = resourceGroupName,
            ServerFarmId      = appServicePlan.Id,
            SiteConfig        = new SiteConfigArgs
            {
                AppSettings =
                    GenerateGoogleAnalyticsArgs(config, "GoogleAnalytics.Sites")
                    .Concat(
                        new[]
                {
                    new NameValuePairArgs
                    {
                        Name  = "AzureWebJobsStorage",
                        Value = storageAccount.PrimaryBlobConnectionString
                    },
                    new NameValuePairArgs
                    {
                        Name  = "FUNCTIONS_WORKER_RUNTIME",
                        Value = "dotnet"
                    },
                    new NameValuePairArgs
                    {
                        Name  = "WEBSITE_RUN_FROM_PACKAGE",
                        Value = codeBlobUrl
                    },
                    new NameValuePairArgs()
                    {
                        Name  = "FUNCTIONS_EXTENSION_VERSION",
                        Value = "~3"             // use Azure functions v3
                    },

                    /* App Insights - for some reason Azure Functions
                     * built via Portal use both configuration values
                     * */

                    new NameValuePairArgs
                    {
                        Name  = "APPLICATIONINSIGHTS_CONNECTION_STRING",
                        Value = Output.Format($"InstrumentationKey={appInsights.InstrumentationKey}")
                    },
                    new NameValuePairArgs
                    {
                        Name  = "APPINSIGHTS_INSTRUMENTATIONKEY",
                        Value = appInsights.InstrumentationKey
                    },

                    /* Add InfluxDb parameters
                     *
                     * All of these configuration parameters are consumed via
                     * Microsoft.Extensions.Configuration environment variables
                     * consumption - hence why we use the double underscore - to separate
                     * configuration areas.
                     */
                    new NameValuePairArgs()
                    {
                        Name  = "InfluxDb__ConnectionString",
                        Value = config.Require("InfluxDb.ConnectionString")
                    },
                    new NameValuePairArgs()
                    {
                        Name  = "InfluxDb__Org",
                        Value = config.Require("InfluxDb.Org")
                    },
                    new NameValuePairArgs()
                    {
                        Name  = "InfluxDb__Bucket",
                        Value = config.Require("InfluxDb.Bucket")
                    },
                    new NameValuePairArgs()
                    {
                        Name  = "InfluxDb__Token",
                        Value = Output.Format(
                            $"@Microsoft.KeyVault(VaultName={vault.Name};SecretName={influxDbTokenSecret.Name})")
                    },


                    /* Email marketing configuration values */
                    new NameValuePairArgs()
                    {
                        Name  = "Mailchimp__ApiKey",
                        Value = Output.Format(
                            $"@Microsoft.KeyVault(VaultName={vault.Name};SecretName={mailChimpTokenSecret.Name})")
                    },

                    /* Web analytics configuration values */
                    new NameValuePairArgs()
                    {
                        Name  = "GoogleAnalytics__ServiceAccount",
                        Value = config.Require("GoogleAnalytics.ServiceAccount")
                    },

                    new NameValuePairArgs()
                    {
                        Name  = "GoogleAnalytics__Key",
                        Value = Output.Format(
                            $"@Microsoft.KeyVault(VaultName={vault.Name};SecretName={googleAnalyticsKeySecret.Name})")
                    }
                }).ToArray()
            },
            Identity = new ManagedServiceIdentityArgs()
            {
                Type = Pulumi.AzureNative.Web.ManagedServiceIdentityType.SystemAssigned
            },
            Tags =
            {
                { "environment", "dev"        },
                { "product",     "kpi-system" }
            }
        });

        // need to create access policies using the azure function system identity
        var appId = kpiCollector.Identity.Apply(s => s.PrincipalId);


        var accessPolicy = new AccessPolicy("kpi-keyvault-access",
                                            new AccessPolicyArgs()
        {
            ObjectId          = appId,
            SecretPermissions = "get",
            KeyVaultId        = vault.Id,
            TenantId          = config.Require("azureTenantId")
        });
    }